nfsim_species_unifier.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2020 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 "nfsim_species_unifier.h"
  12. #include <iostream>
  13. #include <fstream>
  14. using namespace std;
  15. extern int bngldebug;
  16. namespace MCell {
  17. bool NFSimSpeciesUnifier::read_input_file(const std::string& input_file, const bool is_dat) {
  18. //bngldebug = 1;
  19. ifstream ifs;
  20. ifs.open(input_file, ifstream::in);
  21. if (!ifs.is_open()) {
  22. cerr << "Could not open input file " << input_file << ".\n";
  23. return false;
  24. }
  25. string line;
  26. uint linenr = 0;
  27. while (getline(ifs, line)) {
  28. linenr++;
  29. if (line.empty()) {
  30. continue;
  31. }
  32. if (line[0] == '#') {
  33. // comment
  34. continue;
  35. }
  36. // expecting that each line will be in this form:
  37. // NFSim Species:
  38. // BNGL_COMPLEX count
  39. // .dat (MCell viz output)
  40. // BNGL_COMPLEX position normal
  41. size_t cplx_end = line.find(' ');
  42. if (cplx_end == string::npos) {
  43. cerr << "Did not find a separator ' ' on line " << linenr << ".\n";
  44. return false;
  45. }
  46. string cplx_string = line.substr(0, cplx_end);
  47. string count_string;
  48. if (!is_dat) {
  49. count_string = line.substr(cplx_end);
  50. }
  51. else {
  52. count_string = "1"; // each line in .dat files is one instance
  53. }
  54. // parse cplx string
  55. BNG::Cplx cplx_inst(&bng_engine.get_data());
  56. int num_errors = BNG::parse_single_cplx_string(
  57. cplx_string, bng_engine.get_data(),
  58. cplx_inst
  59. );
  60. if (num_errors != 0) {
  61. cerr << "Could not parse complex instance '" << cplx_string << "' on line " << linenr << ".\n";
  62. ifs.close();
  63. return false;
  64. }
  65. assert(!cplx_inst.elem_mols.empty());
  66. // see what species it is
  67. BNG::Species new_species = BNG::Species(cplx_inst, bng_engine.get_data(), bng_engine.get_config(), false);
  68. BNG::species_id_t id = bng_engine.get_all_species().find_or_add(new_species);
  69. // convert count
  70. double count;
  71. try {
  72. count = stod(count_string);
  73. }
  74. catch (const std::invalid_argument& ia) {
  75. cerr << "Could not convert count '" << count_string << "' on line " << linenr << ".\n";
  76. ifs.close();
  77. return false;
  78. }
  79. // remember this count
  80. auto it = counts_per_unique_species.find(id);
  81. if (it == counts_per_unique_species.end()) {
  82. counts_per_unique_species[id] = count;
  83. }
  84. else {
  85. counts_per_unique_species[id] += count;
  86. }
  87. }
  88. return true;
  89. }
  90. // out_file may be an empty string, in this case the output is printed to
  91. bool NFSimSpeciesUnifier::print_unified_species(const std::string& out_file) {
  92. ostream* out;
  93. ofstream ofile;
  94. if (out_file != "") {
  95. ofile.open(out_file, ofstream::out);
  96. if (!ofile.is_open()) {
  97. cerr << "Could not open output file " << out_file << ".\n";
  98. return false;
  99. }
  100. out = &ofile;
  101. }
  102. else {
  103. out = &cout;
  104. }
  105. for (auto it: counts_per_unique_species) {
  106. BNG::Species& s = bng_engine.get_all_species().get(it.first);
  107. *out << s.to_str() << " " << it.second << "\n";
  108. }
  109. if (out_file != "") {
  110. ofile.close();
  111. }
  112. return true;
  113. }
  114. } // namespace MCell