simulation_stats.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2019-2021 by
  4. * The Salk Institute for Biological Studies
  5. *
  6. * Use of this source code is governed by an MIT-style
  7. * license that can be found in the LICENSE file or at
  8. * https://opensource.org/licenses/MIT.
  9. *
  10. ******************************************************************************/
  11. #include "simulation_stats.h"
  12. #include "bng/bng.h"
  13. using namespace std;
  14. namespace MCell {
  15. RxnCountStats& SimulationStats::get_rxn_stats(
  16. const BNG::RxnContainer& all_rxns, const BNG::RxnClass* rxn_class) {
  17. // we must use reactant name pairs to store the information
  18. // because their count does not grow and rxn classes
  19. // also assuming that the names of reactants in reactions are always sorted
  20. // (does not matter how), i.e. there is always A + B -> C and A + B -> D,
  21. // and not B + A -> E
  22. assert(rxn_class->get_num_reactions() >= 1);
  23. BNG::rxn_rule_id_t id = rxn_class->get_rxn_rule_id(0);
  24. const BNG::RxnRule* rxn = all_rxns.get(id);
  25. assert(rxn != nullptr);
  26. assert(rxn->is_bimol());
  27. const string& n1 = rxn->reactants[0].name;
  28. assert(n1 != "");
  29. const string& n2 = rxn->reactants[1].name;
  30. assert(n2 != "");
  31. // increment or add a new item if the pair we are searching for does not exist
  32. auto it1 = bimol_rxn_stats.find(n1);
  33. if (it1 == bimol_rxn_stats.end()) {
  34. it1 = bimol_rxn_stats.insert(make_pair(n1, NameStatsMap())).first;
  35. }
  36. auto it2 = it1->second.find(n2);
  37. if (it2 == it1->second.end()) {
  38. it2 = it1->second.insert(make_pair(n2, RxnCountStats())).first;
  39. }
  40. return it2->second;
  41. }
  42. void SimulationStats::inc_rxn_occurred(
  43. const BNG::RxnContainer& all_rxns, const BNG::RxnClass* rxn_class,
  44. const uint64_t occurred) {
  45. get_rxn_stats(all_rxns, rxn_class).occurred += occurred;
  46. }
  47. void SimulationStats::inc_rxn_skipped(
  48. const BNG::RxnContainer& all_rxns, const BNG::RxnClass* rxn_class,
  49. const double skipped) {
  50. get_rxn_stats(all_rxns, rxn_class).skipped += skipped;
  51. }
  52. void SimulationStats::print_missed_rxns_warnings(const std::string& warnings_report_file_name) {
  53. bool first_report = true;
  54. stringstream ss;
  55. for (auto n1_map_pair: bimol_rxn_stats) {
  56. for (auto n2_stats_pair: n1_map_pair.second) {
  57. const RxnCountStats& stats = n2_stats_pair.second;
  58. if (stats.skipped > 0) {
  59. if (first_report) {
  60. ss << "Warning: Some reactions were missed because total reaction probability exceeded 1.\n";
  61. first_report = false;
  62. }
  63. double perc =
  64. 0.001 * round(1000 * stats.skipped * 100 / (stats.skipped + stats.occurred));
  65. if (perc >= SQRT_EPS) { // ignore really small values
  66. ss <<
  67. " " << n1_map_pair.first << " + " << n2_stats_pair.first << " -- " <<
  68. perc << "% of reactions missed.\n";
  69. }
  70. }
  71. }
  72. }
  73. if (ss.str() != "") {
  74. cerr << ss.str();
  75. if (warnings_report_file_name != "") {
  76. BNG::append_to_report(warnings_report_file_name, ss.str());
  77. }
  78. }
  79. }
  80. void SimulationStats::print_report(const std::string& warnings_report_file_name) {
  81. cout << "Total number of ray-subvolume intersection tests (number of ray_trace calls): " << ray_voxel_tests << "\n";
  82. cout << "Total number of ray-polygon intersection tests: " << ray_polygon_tests << "\n";
  83. cout << "Total number of ray-polygon intersections: " << ray_polygon_colls << "\n";
  84. cout << "Total number of mol reflections from a wall: " << mol_wall_reflections << "\n";
  85. cout << "Total number of vol mol vol mol collisions: " << vol_mol_vol_mol_collisions << "\n";
  86. cout << "Total number of molecule moves between walls: " << mol_moves_between_walls << "\n";
  87. cout << "Total number of usages of waypoints for counted volumes: " << num_waypoints_used << "\n";
  88. cout << "Total number of counted volume recomputations: " << recomputations_of_counted_volume << "\n";
  89. cout << "Total number of diffuse 3d calls: " << diffuse_3d_calls << "\n";
  90. if (diffusion_number != 0) {
  91. cout << "Average diffusion jump was: " <<
  92. diffusion_cummtime / (double)diffusion_number << " timesteps " <<
  93. " (" << diffusion_cummtime << "/" << diffusion_number << ")\n";
  94. }
  95. if (warnings_report_file_name != "") {
  96. print_missed_rxns_warnings(warnings_report_file_name);
  97. }
  98. }
  99. } // namespace MCell