LCOV - code coverage report
Current view: top level - src - file_parser.cxx (source / functions) Hit Total Coverage
Test: code_coverage_filter.info Lines: 250 375 66.7 %
Date: 2024-03-28 16:04:17 Functions: 19 22 86.4 %
Branches: 582 1262 46.1 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * @author: Shuran Wang
       3                 :            :  * @date: December 26, 2021
       4                 :            :  *
       5                 :            :  * \file file_parser.cxx \brief External file format wrapper implementation
       6                 :            :  *
       7                 :            :  * This file implements wrappers to external file format (XML) parsers
       8                 :            :  */
       9                 :            : 
      10                 :            : #include <iostream>
      11                 :            : #include <fstream>
      12                 :            : #include "file_parser.h"
      13                 :            : #include <algorithm>
      14                 :            : 
      15                 :            : //! Default Constructor 
      16                 :          0 : Parser::Parser() {
      17                 :          0 :     _injection_points.region_id = -1; // not defined
      18                 :          0 :     _sources.max_sources = -1; // not defined
      19                 :          0 : }
      20                 :            : 
      21                 :            : /**
      22                 :            :  * Regular Constructor, reads data from data file
      23                 :            :  * @param filename [in]: Path to the data file
      24                 :            :  */
      25                 :         72 : Parser::Parser(string filename) {
      26 [ +  - ][ +  - ]:         36 :     if (read_from_xml(filename)) {
                 [ +  - ]
      27         [ +  - ]:         36 :         fprintf(stderr, "\n\033[1;%dmSuccessfully read XML file.\033[0m\n", 35);
      28                 :            :     }
      29                 :            : 
      30                 :            :     // TODO: add checks
      31                 :         36 : }
      32                 :            : 
      33                 :            : /*
      34                 :            :  * Regular Destructor, deletes sources
      35                 :            :  */
      36                 :         62 : Parser::~Parser() {
      37         [ +  + ]:        311 :     for (unsigned i = 0; i < _sources.sources_init.size(); i++) {
      38 [ +  - ][ +  - ]:        280 :         if (_sources.sources_init[i]) delete _sources.sources_init[i];
      39                 :            :     }
      40                 :         31 : }
      41                 :            : 
      42                 :        293 : void Parser::read_line_source(const boost::property_tree::ptree& token) {
      43                 :            :     using boost::property_tree::ptree;
      44                 :        586 :     string location; // location for endpoint0
      45         [ +  - ]:        586 :     vector<SP_Point> endpoints;
      46                 :        293 :     double length = _INFINITY_;
      47 [ +  - ][ +  - ]:       2637 :     BOOST_FOREACH(ptree::value_type const& e, token) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
      48 [ +  - ][ +  + ]:       1172 :         if (e.first == "endpoint") {
      49                 :            :             // create endpoint
      50         [ +  - ]:       1172 :             SP_Point endpoint;
      51 [ +  - ][ +  - ]:        586 :             endpoint.set_xcoord (e.second.get<float>("x"));
                 [ +  - ]
      52 [ +  - ][ +  - ]:        586 :             endpoint.set_ycoord (e.second.get<float>("y"));
                 [ +  - ]
      53 [ +  - ][ +  - ]:        586 :             endpoint.set_zcoord (e.second.get<float>("z"));
                 [ +  - ]
      54                 :            : 
      55         [ +  + ]:        586 :             if (endpoints.size() == 0) { // first endpoint
      56 [ +  - ][ +  - ]:        293 :                 location = e.second.get<string>("<xmlattr>.location", "proximal");
                 [ +  - ]
      57         [ +  - ]:        293 :                 endpoints.push_back(endpoint);
      58                 :            : 
      59                 :            :                 // cout << "Pushing proximal endpoint " << endpoint << endl;
      60                 :            :             } else {
      61 [ +  - ][ +  - ]:        293 :                 if (location == "proximal") {
      62         [ +  - ]:        293 :                     endpoints.push_back(endpoint);
      63                 :            :                     // cout << "Pushing distal endpoint " << endpoint << endl;
      64 [ #  # ][ #  # ]:          0 :                 } else if (location == "distal") {
      65         [ #  # ]:          0 :                     endpoints.emplace(endpoints.begin(), endpoint);
      66                 :            :                     // cout << "Pushing proximal endpoint " << endpoint << endl;
      67                 :            :                 } else {
      68         [ #  # ]:          0 :                     fprintf(stderr, "\033[1;%dmInvalid attribute for endpoint, should be proximal or distal. \033[0m\n", 33);
      69                 :            :                 }
      70                 :            :             }
      71 [ +  - ][ +  + ]:        586 :         } else if (e.first == "length") {
      72                 :            :             // set length
      73         [ +  - ]:        293 :             length = boost::lexical_cast<double>(e.second.data());
      74 [ +  - ][ +  - ]:        293 :         } else if (e.first != "<xmlcomment>" && e.first != "<xmlattr>") {
         [ +  - ][ -  + ]
                 [ -  + ]
      75         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmInvalid tag in source, should be endpoint. Exiting... \033[0m\n", 31);
      76                 :          0 :             exit(-1);
      77                 :            :         }
      78                 :            :     }
      79                 :            : 
      80                 :            :     // if endpoints are not entered, use entered length to generate initial solution
      81         [ -  + ]:        293 :     if (endpoints.size() == 0) {
      82         [ #  # ]:          0 :         if (_sources.sources_init.size() != 0) {
      83         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmAt least 1 line source not entered, ignoring entered sources and will generate initial solution. Exiting... \033[0m\n", 31);
      84                 :          0 :             _sources.sources_init.clear();
      85                 :            :         }
      86         [ #  # ]:          0 :         _sources.lengths.push_back(length);
      87                 :          0 :         return;
      88                 :            :     }
      89                 :            : 
      90         [ -  + ]:        293 :     if (endpoints.size() != 2) {
      91         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmLine sources should have 2 endpoints, entered %lu. Exiting... \033[0m\n", 31, endpoints.size());
      92                 :          0 :         exit(-1);
      93                 :            :     }
      94                 :            : 
      95                 :            :     // cout << "endpoints[0] " << endpoints[0] << " endpoints[1] " << endpoints[1] << endl;
      96 [ -  + ][ #  # ]:        293 :     if (length == _INFINITY_) length = endpoints[0].get_distance_from(endpoints[1]);
      97         [ +  - ]:        293 :     _sources.lengths.push_back(length);
      98                 :            : 
      99 [ +  - ][ +  - ]:        293 :     Src_Line* s = new Src_Line(endpoints[0], endpoints[1]);
     100                 :            :     // cout << "Reading source " << s << endl;
     101 [ +  - ][ +  - ]:        293 :     _sources.sources_init.push_back(s);
     102                 :            : }
     103                 :            : 
     104                 :         18 : void Parser::read_point_source(const boost::property_tree::ptree& token) {
     105                 :            :     using boost::property_tree::ptree;
     106                 :         36 :     vector<SP_Point> endpoints;
     107 [ +  - ][ +  - ]:         90 :     BOOST_FOREACH(ptree::value_type const& e, token) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     108 [ +  - ][ +  + ]:         36 :         if (e.first == "endpoint") {
     109                 :            :             // create endpoint
     110         [ +  - ]:         36 :             SP_Point endpoint;
     111 [ +  - ][ +  - ]:         18 :             endpoint.set_xcoord (e.second.get<float>("x"));
                 [ +  - ]
     112 [ +  - ][ +  - ]:         18 :             endpoint.set_ycoord (e.second.get<float>("y"));
                 [ +  - ]
     113 [ +  - ][ +  - ]:         18 :             endpoint.set_zcoord (e.second.get<float>("z"));
                 [ +  - ]
     114                 :            : 
     115         [ +  - ]:         18 :             if (endpoints.size() == 0) { // first endpoint
     116         [ +  - ]:         18 :                 endpoints.push_back(endpoint);
     117                 :            :             } else {
     118         [ #  # ]:          0 :                 fprintf(stderr, "\033[1;%dmPoint source should only have 1 endpoint. Exiting... \033[0m\n", 31);
     119                 :          0 :                 exit(-1);
     120                 :            :             }
     121 [ +  - ][ +  - ]:         18 :         } else if (e.first != "<xmlcomment>" && e.first != "<xmlattr>") {
         [ +  - ][ -  + ]
                 [ -  + ]
     122         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmInvalid tag in source. Exiting... \033[0m\n", 31);
     123                 :          0 :             exit(-1);
     124                 :            :         }
     125                 :            :     }
     126                 :            : 
     127                 :            :     // check for incomplete point source
     128         [ -  + ]:         18 :     if (endpoints.size() == 0) {
     129         [ #  # ]:          0 :         if (_sources.sources_init.size() != 0) {
     130         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmAt least 1 point source not complete, ignoring entered sources and will generate initial solution. Exiting... \033[0m\n", 31);
     131                 :          0 :             _sources.sources_init.clear();
     132                 :            :         }
     133         [ #  # ]:          0 :         _sources.lengths.push_back(0);
     134                 :          0 :         return;
     135                 :            :     }
     136                 :            : 
     137         [ +  - ]:         18 :     _sources.lengths.push_back(0);
     138                 :            : 
     139 [ +  - ][ +  - ]:         18 :     Src_Point* s = new Src_Point(endpoints[0].get_xcoord(), endpoints[0].get_ycoord(), endpoints[0].get_zcoord());
         [ +  - ][ +  - ]
                 [ +  - ]
     140 [ +  - ][ +  - ]:         18 :     _sources.sources_init.push_back(s);
     141                 :            : }
     142                 :            : 
     143                 :            : //!
     144                 :            : //! This method reads the fullmonte parameters specified in xml file
     145                 :            : //! @param token [in]: string value of the <source> tag
     146                 :            : //! 
     147                 :          0 : void Parser::read_cutend_source(const boost::property_tree::ptree& token) {
     148                 :          0 :     vector<SP_Point> endpoints;
     149                 :          0 :     float r = 0, na= 0;
     150         [ #  # ]:          0 :     SP_Point dir;
     151                 :          0 :     bool set_r = false;
     152                 :          0 :     bool set_na = false;
     153                 :          0 :     bool set_dir = false;
     154                 :          0 :     bool set_endpoint = false;
     155                 :            :     using boost::property_tree::ptree;
     156 [ #  # ][ #  # ]:          0 :     BOOST_FOREACH(ptree::value_type const& e, token) {
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     157 [ #  # ][ #  # ]:          0 :         if (e.first == "endpoint") {
     158                 :            :             // create endpoint
     159         [ #  # ]:          0 :             SP_Point endpoint;
     160 [ #  # ][ #  # ]:          0 :             endpoint.set_xcoord (e.second.get<float>("x"));
                 [ #  # ]
     161 [ #  # ][ #  # ]:          0 :             endpoint.set_ycoord (e.second.get<float>("y"));
                 [ #  # ]
     162 [ #  # ][ #  # ]:          0 :             endpoint.set_zcoord (e.second.get<float>("z"));
                 [ #  # ]
     163                 :            : 
     164         [ #  # ]:          0 :             if (endpoints.size() == 0) { // first endpoint
     165         [ #  # ]:          0 :                 endpoints.push_back(endpoint);
     166                 :            :             } else {
     167         [ #  # ]:          0 :                 fprintf(stderr, "\033[1;%dmCut-end source should only have 1 endpoint. Exiting... \033[0m\n", 31);
     168                 :          0 :                 exit(-1);
     169                 :            :             }
     170                 :          0 :             set_endpoint = true;
     171 [ #  # ][ #  # ]:          0 :         } else if (e.first == "radius") {
     172         [ #  # ]:          0 :             r = boost::lexical_cast<float>(e.second.data());
     173                 :          0 :             set_r = true;
     174 [ #  # ][ #  # ]:          0 :         } else if (e.first == "na") {
     175         [ #  # ]:          0 :             na = boost::lexical_cast<float>(e.second.data());
     176                 :          0 :             set_na = true;
     177 [ #  # ][ #  # ]:          0 :         } else if (e.first == "direction") {
     178                 :            :             // create endpoint
     179 [ #  # ][ #  # ]:          0 :             dir.set_xcoord (e.second.get<float>("x"));
                 [ #  # ]
     180 [ #  # ][ #  # ]:          0 :             dir.set_ycoord (e.second.get<float>("y"));
                 [ #  # ]
     181 [ #  # ][ #  # ]:          0 :             dir.set_zcoord (e.second.get<float>("z"));
                 [ #  # ]
     182                 :          0 :             set_dir = true;
     183 [ #  # ][ #  # ]:          0 :         } else if (e.first != "<xmlcomment>" && e.first != "<xmlattr>") {
         [ #  # ][ #  # ]
                 [ #  # ]
     184         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmInvalid tag in source. Exiting... \033[0m\n", 31);
     185                 :          0 :             exit(-1);
     186                 :            :         }
     187                 :            :     }
     188                 :            : 
     189 [ #  # ][ #  # ]:          0 :     if (!(set_dir && set_endpoint && set_na && set_r)) {
         [ #  # ][ #  # ]
     190         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmCutEnd source not entered properly. Exiting... \033[0m\n", 31);
     191                 :          0 :         exit(-1);
     192                 :            :     }
     193         [ #  # ]:          0 :     _sources.lengths.push_back(0);
     194                 :            : 
     195         [ #  # ]:          0 :     Src_CutEnd* s = new Src_CutEnd(r, na, endpoints[0], dir);
     196         [ #  # ]:          0 :     _sources.sources_init.push_back(s);
     197                 :          0 : }
     198                 :            : 
     199                 :            : //!
     200                 :            : //! This method sets the XML file and builds data structures
     201                 :            : //! @param filename [in]: Path to the data file
     202                 :            : //! 
     203                 :         36 : bool Parser::read_from_xml(string filename) {
     204                 :            :     // use boost ptree to store xml information
     205                 :            :     using boost::property_tree::ptree;
     206         [ +  - ]:         72 :     ptree pt;
     207                 :            :     
     208         [ +  - ]:         36 :     fprintf(stderr, "\033[1;%dmReading XML file\033[0m\n", 33);
     209                 :            : 
     210                 :            :     // create istream to read from file
     211         [ +  - ]:         72 :     ifstream f;
     212         [ +  - ]:         36 :     f.open(filename);
     213 [ +  - ][ -  + ]:         36 :     if (!f) {
     214         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmCannot open XML File to read. \033[0m\n", 31);
     215                 :          0 :         return false;
     216                 :            :     }
     217                 :            : 
     218                 :            :     // read from xml file into ptree
     219         [ +  - ]:         36 :     read_xml(f, pt);
     220         [ +  - ]:         36 :     f.close();
     221                 :            : 
     222                 :            :     // traverse ptree
     223                 :            :     // fm_params
     224         [ +  - ]:         36 :     fprintf(stderr, "\033[1;%dmReading fm_params\033[0m\n", 36);
     225                 :         36 :     _fm_params_map.clear();
     226                 :         36 :     _params_map.clear();
     227 [ +  - ][ +  - ]:       1116 :     BOOST_FOREACH(ptree::value_type const& v, pt.get_child("fm_params")) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     228                 :            :         // check if tag is valid
     229 [ +  - ][ +  - ]:       1980 :         if (v.first == "use_cuda" || v.first == "pnf" || v.first == "num_packets" || v.first == "rand_seed" ||
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
                 [ +  + ]
     230 [ +  - ][ +  - ]:       1044 :                 v.first == "wavelength" ||  v.first == "mesh_file" || v.first == "max_hits" ||
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
     231 [ +  + ][ +  - ]:       1332 :                 v.first == "roulette_pr_win" || v.first == "roulette_w_min" || v.first == "max_steps") {
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
     232         [ +  - ]:        360 :             fprintf(stderr, "\033[1;%dmReading %s\033[0m\n", 36, v.first.c_str());
     233 [ +  - ][ +  - ]:        360 :             _fm_params_map[v.first] = v.second.data();
     234 [ +  - ][ +  - ]:        360 :             _params_map[v.first] = v.second.data(); // some params will be used by pdt_plan
     235 [ +  - ][ -  + ]:        180 :         } else if (v.first != "<xmlcomment>" && v.first != "<xmlattr>") {
         [ #  # ][ #  # ]
                 [ -  + ]
     236         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmInvalid tag in fm_params. \033[0m\n", 33);
     237                 :            :         }
     238                 :            :     }
     239                 :            : 
     240                 :            :     // program_params
     241         [ +  - ]:         36 :     fprintf(stderr, "\033[1;%dmReading program_params\033[0m\n", 36);
     242 [ +  - ][ +  - ]:        622 :     BOOST_FOREACH(ptree::value_type const& v, pt.get_child("program_params")) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     243                 :            :         // check if tag is valid
     244 [ +  - ][ +  - ]:       1023 :         if (v.first == "read_vtk" || v.first == "tumor_weight" || v.first == "run_tests" || v.first == "fm_output_file" ||
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
                 [ +  - ]
     245 [ +  - ][ +  - ]:        396 :                 v.first == "override_file_path" || v.first == "vary_tumor_weight" || v.first == "target_tumor_cov" ||
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
     246 [ +  - ][ +  - ]:        180 :                 v.first == "final_dist_file" || v.first == "run_rt_feedback" || v.first == "rt_feedback_seed" ||
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
     247 [ +  - ][ +  - ]:        108 :                 v.first == "rt_feedback_det_rad" || v.first == "rt_feedback_det_na" || v.first == "rt_feedback_lut_file" ||
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     248 [ +  + ][ +  - ]:        586 :                 v.first == "rt_feedback_lut_size" || v.first == "placement_type") {
         [ +  - ][ +  - ]
     249         [ +  - ]:        293 :             fprintf(stderr, "\033[1;%dmReading %s\033[0m\n", 36, v.first.c_str());
     250 [ +  - ][ +  - ]:        293 :             _params_map[v.first] = v.second.data();
     251 [ #  # ][ #  # ]:          0 :         } else if (v.first != "<xmlcomment>" && v.first != "<xmlattr>") {
         [ #  # ][ #  # ]
                 [ #  # ]
     252         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmInvalid tag in program_params. \033[0m\n", 33);
     253                 :            :         }
     254                 :            :     }
     255                 :            :     
     256 [ +  - ][ +  - ]:         36 :     if (_params_map["placement_type"] == "sa") {
         [ +  - ][ +  + ]
     257 [ +  - ][ +  - ]:          8 :         _params_map["placement_type"] = "fixed";
                 [ +  - ]
     258                 :          8 :                 _run_sa = true;
     259                 :            :         }
     260                 :            :         else {
     261                 :         28 :                 _run_sa = false;
     262                 :            :         }
     263                 :            : 
     264                 :            :     // sources
     265                 :         36 :     _sources.sources_init.clear();
     266         [ +  - ]:         36 :     fprintf(stderr, "\033[1;%dmReading sources\033[0m\n", 36);
     267 [ +  - ][ +  - ]:        252 :     BOOST_FOREACH(ptree::value_type const& v, pt.get_child("sources")) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     268 [ +  - ][ +  + ]:        108 :         if (v.first == "max_sources") {
     269         [ +  - ]:         36 :             fprintf(stderr, "\033[1;%dmReading max_sources\033[0m\n", 36);
     270         [ +  - ]:         36 :             _sources.max_sources = boost::lexical_cast<int>(v.second.data());
     271 [ +  - ][ +  + ]:         72 :         } else if (v.first == "line_tailored") {
     272         [ +  - ]:         36 :             fprintf(stderr, "\033[1;%dmReading line_tailored\033[0m\n", 36);
     273         [ +  - ]:         36 :             _sources.tailored = (v.second.data() == "true") ? true : false;
     274 [ +  - ][ +  - ]:         36 :         } else if (v.first == "sources_init") {
     275         [ +  - ]:         36 :             fprintf(stderr, "\033[1;%dmReading sources_init\033[0m\n", 36);
     276 [ +  - ][ +  - ]:        658 :             BOOST_FOREACH(ptree::value_type const& w, v.second) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     277 [ +  - ][ +  - ]:        311 :                 if (w.first == "source") {
     278 [ +  - ][ +  - ]:        622 :                     string type = w.second.get<string>("<xmlattr>.type", "");
                 [ +  - ]
     279                 :            : 
     280 [ +  - ][ +  + ]:        311 :                     if (type == "line") {
     281 [ +  + ][ +  + ]:        293 :                         if (_sources.sources_init.size() == 0 || _sources.source_type == Src_Abstract::Point) 
                 [ +  + ]
     282                 :         35 :                             _sources.source_type = Src_Abstract::Line;
     283         [ +  - ]:        258 :                         else if (_sources.unified_type) {
     284         [ -  + ]:        258 :                             if (_sources.source_type != Src_Abstract::Line)
     285                 :          0 :                                 _sources.unified_type = false;
     286                 :            :                         }
     287         [ +  - ]:        293 :                         read_line_source(w.second);
     288 [ +  - ][ +  - ]:         18 :                     } else if (type == "point") {
     289         [ +  + ]:         18 :                         if (_sources.sources_init.size() == 0) {
     290                 :          3 :                             _sources.source_type = Src_Abstract::Point;
     291 [ +  - ][ +  + ]:         15 :                         } else if (_sources.unified_type && _sources.source_type != Src_Abstract::Line) {
     292         [ -  + ]:          9 :                             if (_sources.source_type != Src_Abstract::Point)
     293                 :          0 :                                 _sources.unified_type = false;
     294                 :            :                         }
     295         [ +  - ]:         18 :                         read_point_source(w.second);
     296 [ #  # ][ #  # ]:          0 :                     } else if (type == "cut-end") {
     297         [ #  # ]:          0 :                         if (_sources.sources_init.size() == 0) 
     298                 :          0 :                             _sources.source_type = Src_Abstract::CutEnd;
     299         [ #  # ]:          0 :                         else if (_sources.unified_type) {
     300         [ #  # ]:          0 :                             if (_sources.source_type != Src_Abstract::CutEnd)
     301                 :          0 :                                 _sources.unified_type = false;
     302                 :            :                         }
     303         [ #  # ]:          0 :                         read_cutend_source(w.second);
     304                 :            :                     } else {
     305         [ #  # ]:          0 :                         fprintf(stderr, "\033[1;%dmNot supported source type. Exiting... \033[0m\n", 31);
     306                 :          0 :                         exit(-1);
     307                 :            :                     }
     308 [ #  # ][ #  # ]:          0 :                 } else if (w.first != "<xmlcomment>" && w.first != "<xmlattr>") {
         [ #  # ][ #  # ]
                 [ #  # ]
     309         [ #  # ]:          0 :                     fprintf(stderr, "\033[1;%dmInvalid tag in sources_init, should be source. \033[0m\n", 33);
     310                 :            :                 }
     311                 :            :             }
     312 [ #  # ][ #  # ]:          0 :         } else if (v.first != "<xmlcomment>" && v.first != "<xmlattr>") {
         [ #  # ][ #  # ]
                 [ #  # ]
     313         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmInvalid tag in sources. \033[0m\n", 33);
     314                 :            :         }
     315                 :            :     }
     316                 :            : 
     317         [ -  + ]:         36 :     if (_sources.max_sources == -1) {
     318         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmRequired field max_sources missing in sources. \033[0m\n", 31);
     319                 :          0 :         return false;
     320                 :            :     }
     321                 :            : 
     322         [ -  + ]:         36 :     if (_sources.sources_init.size() == 0) {
     323         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmInitial solution not provided. \033[0m\n", 31);
     324         [ #  # ]:          0 :         if (!_run_sa) {
     325         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmNot running SA, exiting... \033[0m\n", 31);
     326                 :          0 :             return false;
     327                 :            :         }
     328                 :            : 
     329         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmPDT-SPACE will generate an initial solution.\033[0m\n", 31);
     330                 :          0 :         _sources.source_type = Src_Abstract::Line;
     331         [ #  # ]:          0 :         while (_sources.lengths.size() < (unsigned)_sources.max_sources) {
     332         [ #  # ]:          0 :             _sources.lengths.push_back(_INFINITY_);
     333                 :            :         }
     334                 :            :     }
     335         [ +  - ]:         36 :     fprintf(stderr, "\033[1;%dmDone reading sources\033[0m\n", 36);
     336                 :            : 
     337                 :            :     // sa_options. Only read if running SA
     338                 :         36 :     _constrain_injection_point = false;
     339         [ +  + ]:         36 :     if (_run_sa) {
     340                 :            :         // injection_points
     341                 :          8 :         _injection_points.injection_points.clear();
     342                 :          8 :         _sa_params_map.clear();
     343                 :            :         // _placement_mode = PM_NONE;
     344         [ +  - ]:          8 :         fprintf(stderr, "\033[1;%dmReading sa_options\033[0m\n", 36);
     345 [ +  - ][ +  - ]:         88 :         BOOST_FOREACH(ptree::value_type const& u, pt.get_child("sa_options")) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     346                 :            :             // if (u.first == "placement_constraint") {
     347                 :            :             //     if (u.second.data() == "none") _placement_mode = PM_NONE;
     348                 :            :             //     else if (u.second.data() == "parallel") _placement_mode = PM_PARALLEL;
     349                 :            :             //     else if (u.second.data() == "point") _placement_mode = PM_POINT;
     350                 :            :             //     else {
     351                 :            :             //         _placement_mode = PM_NONE;
     352                 :            :             //         fprintf(stderr, "\033[1;%dmInvalid placement mode, defaulting to none. \033[0m\n", 33);
     353                 :            :             //     }
     354 [ +  - ][ +  - ]:        160 :             if (u.first == "beta" || u.first == "lambda" || u.first == "mpt" || u.first == "sa_placement_file" || u.first == "sa_num_packets" ||
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
                 [ +  + ]
     355 [ +  - ][ +  - ]:        136 :                     u.first == "max_src_distance" || u.first == "min_src_distance" || u.first == "distance_to_boundary" || 
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
                 [ -  + ]
     356         [ +  - ]:         16 :                     u.first == "output_top_placements") {
     357         [ +  - ]:         24 :                 fprintf(stderr, "\033[1;%dmReading %s\033[0m\n", 36, u.first.c_str());
     358 [ +  - ][ +  - ]:         24 :                 _sa_params_map[u.first] = u.second.data();
     359 [ +  - ][ +  + ]:         16 :             } else if (u.first == "injection_points") {
     360 [ +  - ][ +  - ]:          8 :                 _constrain_injection_point = u.second.get<bool>("<xmlattr>.constraint", true);
     361 [ +  - ][ +  - ]:         56 :                 BOOST_FOREACH(ptree::value_type const& v, u.second) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     362 [ +  - ][ +  + ]:         24 :                     if (v.first == "region_id") {
     363         [ +  - ]:          8 :                         _injection_points.region_id = boost::lexical_cast<int>(v.second.data());
     364 [ +  - ][ +  + ]:         16 :                     } else if (v.first == "point") {
     365         [ +  - ]:         16 :                         Parser_injection_point ip;
     366                 :          8 :                         ip.id = -1;
     367                 :          8 :                         ip.diameter = -1;
     368 [ +  - ][ +  - ]:         72 :                         BOOST_FOREACH(ptree::value_type const& w, v.second) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     369 [ +  - ][ +  + ]:         32 :                             if (w.first == "id") {
     370         [ +  - ]:          8 :                                 ip.id = boost::lexical_cast<int>(w.second.data());
     371 [ +  - ][ +  + ]:         24 :                             } else if (w.first == "diameter") {
     372         [ +  - ]:          8 :                                 ip.diameter = boost::lexical_cast<float>(w.second.data());
     373 [ +  - ][ +  + ]:         16 :                             } else if (w.first == "normal") {
     374 [ +  - ][ +  - ]:          8 :                                 float x = w.second.get<float>("x");
     375 [ +  - ][ +  - ]:          8 :                                 float y = w.second.get<float>("y");
     376 [ +  - ][ +  - ]:          8 :                                 float z = w.second.get<float>("z");
     377         [ +  - ]:          8 :                                 ip.normal = SP_Point(x, y, z);
     378 [ +  - ][ +  - ]:          8 :                             } else if (w.first == "center") {
     379 [ +  - ][ +  - ]:          8 :                                 float x = w.second.get<float>("x");
     380 [ +  - ][ +  - ]:          8 :                                 float y = w.second.get<float>("y");
     381 [ +  - ][ +  - ]:          8 :                                 float z = w.second.get<float>("z");
     382         [ +  - ]:          8 :                                 ip.center = SP_Point(x, y, z);
     383 [ #  # ][ #  # ]:          0 :                             } else if (w.first != "<xmlcomment>") {
     384         [ #  # ]:          0 :                                 fprintf(stderr, "\033[1;%dmInvalid tag in point. \033[0m\n", 33);
     385                 :            :                             }
     386                 :            :                         }
     387 [ +  - ][ -  + ]:          8 :                         if (ip.id < 0 || ip.diameter < 0) {
     388         [ #  # ]:          0 :                             fprintf(stderr, "\033[1;%dmInvalid injection point. \033[0m\n", 31);
     389                 :          0 :                             return false;
     390                 :            :                         }
     391 [ +  - ][ +  - ]:          8 :                         _injection_points.injection_points.push_back(ip);
     392 [ +  - ][ +  - ]:          8 :                     } else if (v.first != "<xmlcomment>" && v.first != "<xmlattr>") {
         [ +  - ][ -  + ]
                 [ -  + ]
     393         [ #  # ]:          0 :                         fprintf(stderr, "\033[1;%dmInvalid tag in injection_points. \033[0m\n", 33);
     394                 :            :                     }
     395                 :            :                 }
     396                 :            : 
     397         [ -  + ]:          8 :                 if (_injection_points.region_id < 0) {
     398         [ #  # ]:          0 :                     fprintf(stderr, "\033[1;%dmMissing injection point region id. \033[0m\n", 31);
     399                 :          8 :                     return false;
     400                 :            :                 }
     401 [ +  - ][ +  - ]:          8 :             } else if (u.first == "critical_tissues") {
     402         [ +  - ]:         16 :                 stringstream s (u.second.data());
     403                 :          8 :                 _critical_regions.clear();
     404                 :            :                 unsigned region;
     405 [ +  - ][ +  - ]:         32 :                 while (s >> region) {
                 [ +  + ]
     406         [ +  - ]:         24 :                     _critical_regions.insert(region);
     407                 :            :                 }
     408                 :            : 
     409         [ +  - ]:          8 :                 cout << "Read SA critical regions: ";
     410         [ +  + ]:         32 :                 for (auto const &elem: _critical_regions)
     411 [ +  - ][ +  - ]:         24 :                     cout << elem << " ";
     412         [ +  - ]:          8 :                 cout << endl;
     413 [ #  # ][ #  # ]:          0 :             } else if (u.first != "<xmlcomment>") {
     414         [ #  # ]:          0 :                 fprintf(stderr, "\033[1;%dmInvalid tag in sa_options. \033[0m\n", 33);
     415                 :            :             }
     416                 :            :         }
     417         [ +  - ]:          8 :         fprintf(stderr, "\033[1;%dmDone reading sa_options\033[0m\n", 36);
     418                 :            :     }
     419                 :            : 
     420                 :            :     // materials
     421         [ +  - ]:         36 :     fprintf(stderr, "\033[1;%dmReading materials\033[0m\n", 36);
     422                 :         36 :     _materials.clear();
     423 [ +  - ][ +  - ]:        540 :     BOOST_FOREACH(ptree::value_type const& u, pt.get_child("materials")) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     424 [ +  - ][ +  + ]:        252 :         if (u.first == "material") {
     425                 :            :             // do material read
     426                 :        432 :             struct Parser_material m;
     427 [ +  - ][ +  - ]:        216 :             m.name = u.second.get<string>("<xmlattr>.name", "Unnamed");
                 [ +  - ]
     428 [ +  - ][ +  - ]:        216 :             m.id = u.second.get<int>("id");
     429         [ +  - ]:        216 :             fprintf(stderr, "\033[1;%dmReading material %d\033[0m\n", 36, m.id);
     430 [ +  - ][ +  - ]:        216 :             m.n = u.second.get<double>("n", 1);
     431 [ +  - ][ +  - ]:        216 :             m.g = u.second.get<double>("g", 0);
     432 [ +  - ][ +  - ]:        216 :             m.mu_a = u.second.get<double>("mu_a", 0);
     433 [ +  - ][ +  - ]:        216 :             m.mu_s = u.second.get<double>("mu_s", 0);
     434 [ +  - ][ +  - ]:        216 :             m.is_tumor = u.second.get<bool>("is_tumor", false);
     435         [ +  + ]:        216 :             if (m.id != 0) {
     436                 :            :                 // only set if not exterior
     437 [ +  - ][ +  - ]:        180 :                 m.d_min = u.second.get<double>("d_min");
     438 [ +  - ][ +  - ]:        180 :                 m.d_max = u.second.get<double>("d_max");
     439 [ +  + ][ +  - ]:        180 :                 if (m.is_tumor && m.d_max < 1e-8) m.d_max = _INFINITY_;
     440 [ +  - ][ +  - ]:        180 :                 m.guardband = u.second.get<double>("safety_multiplier", 1);
     441                 :            :             }
     442                 :            : 
     443         [ +  - ]:        216 :             _materials.push_back(m);
     444 [ +  - ][ +  - ]:         36 :         } else if (u.first == "matched_boundary") {
     445         [ +  - ]:         36 :             _matched_boundary = (u.second.data() == "true") ? true : false;
     446 [ #  # ][ #  # ]:          0 :         } else if (u.first != "<xmlcomment>") {
     447         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmInvalid tag in materials. \033[0m\n", 33);
     448                 :            :         }
     449                 :            :     }
     450                 :            : 
     451                 :            :     // error checks for materials
     452         [ -  + ]:         36 :     if (_materials.size() == 0) {
     453         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmMaterials not read.\033[0m\n", 31);
     454                 :          0 :         return false;
     455                 :            :     }
     456                 :            : 
     457                 :            :     // sort materials by id
     458                 :         36 :     sort(_materials.begin(), _materials.end(), [](const Parser_material & p1, 
     459         [ +  - ]:        756 :                                         const Parser_material & p2) { return p1.id < p2.id; });
     460                 :            :     
     461                 :            :     // extensive error checks to avoid seg faults
     462                 :         36 :     int last_id = _materials[0].id;
     463                 :            :     // check for exterior, id should start from 0
     464         [ -  + ]:         36 :     if (_materials[0].id != 0) {
     465         [ #  # ]:          0 :         fprintf(stderr, "\033[1;%dmExterior (ID 0) not specified. Smallest ID is %u. Exiting... \033[0m\n", 31, _materials[0].id);
     466                 :          0 :         exit(-1);
     467                 :            :     }
     468         [ +  + ]:        216 :     for (unsigned i = 1; i < _materials.size(); i++) {
     469                 :            :         // check for overlapping ids
     470         [ -  + ]:        180 :         if (_materials[i].id == last_id) {
     471         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmMaterial ID should be unique. Exiting... \033[0m\n", 31);
     472                 :          0 :             exit(-1);
     473                 :            :         }
     474                 :            : 
     475                 :            :         // check for discontinuity in indices. TODO: may want to support discontinued material id?
     476         [ -  + ]:        180 :         if (_materials[i].id != last_id + 1) {
     477         [ #  # ]:          0 :             fprintf(stderr, "\033[1;%dmMaterial ID should be continuous. Missing ID %d. Exiting... \033[0m\n", 31, last_id + 1);
     478                 :          0 :             exit(-1);
     479                 :            :         }
     480                 :            : 
     481                 :        180 :         last_id = _materials[i].id;
     482                 :            :     }
     483         [ +  - ]:         36 :     fprintf(stderr, "\033[1;%dmDone reading materials\033[0m\n", 36);
     484                 :            : 
     485                 :         36 :     return true;
     486                 :            : }
     487                 :            : 
     488                 :            : //! Getter functions for injection points
     489                 :          4 : Parser_injection_points Parser::get_injection_points() {
     490                 :          4 :     return _injection_points;
     491                 :            : }
     492                 :            : 
     493                 :          4 : void Parser::get_injection_point_options(bool &constrain/*, PlacementMode &mode*/, unsigned &max_num) {
     494                 :          4 :     constrain = _constrain_injection_point;
     495                 :            :     // mode = _placement_mode;
     496                 :          4 :     max_num = (unsigned) (_sources.max_sources);
     497                 :          4 : }
     498                 :            : 
     499                 :         36 : void Parser::get_injection_point_options(bool &constrain/*, PlacementMode &mode*/) {
     500                 :         36 :     constrain = _constrain_injection_point;
     501                 :            :     // mode = _placement_mode;
     502                 :         36 : }
     503                 :            : 
     504                 :            : //! Getter function for sources called by sa_engine
     505                 :          4 : void Parser::get_sources(vector<SP_Line> &sources, vector<double> &lengths) {
     506 [ -  + ][ #  # ]:          4 :     if (!((_sources.source_type == Src_Abstract::Line || _sources.source_type == Src_Abstract::Point) && _sources.unified_type)) {
                 [ -  + ]
     507                 :          0 :                 fprintf(stderr, "\033[1;%dmCurrently only line and point sources supported in SA.\nExiting...\033[0m\n", 31);
     508                 :          0 :                 std::exit(-1);
     509                 :            :     }
     510                 :          4 :     sources.clear();
     511                 :          4 :     sources.resize(_sources.sources_init.size());
     512         [ +  + ]:         16 :     for (unsigned i = 0; i < _sources.sources_init.size(); i++) {
     513         [ +  - ]:         12 :         if (_sources.sources_init[i]->get_type() == Src_Abstract::Line) {
     514         [ +  - ]:         12 :             sources[i] = *((SP_Line*) (Src_Line*) (_sources.sources_init[i]));
     515                 :            :         } else {
     516         [ #  # ]:          0 :             sources[i] = SP_Line(*((SP_Point*) (Src_Point*) _sources.sources_init[i]), *((SP_Point*) _sources.sources_init[i]));
     517                 :            :         }
     518                 :         12 :         cout << "Reading source " << sources[i] << endl;
     519                 :            :     }
     520                 :          4 :     lengths = _sources.lengths;
     521                 :          4 : }
     522                 :            : 
     523                 :            : //! Getter function for sources called by pdt_plan
     524                 :          0 : void Parser::get_sources(vector<Src_Abstract*> &sources) {
     525                 :          0 :     sources = _sources.sources_init;
     526                 :          0 : }
     527                 :            : 
     528                 :            : //! Getter function for source types. If mixed type return mixed
     529                 :         36 : string Parser::get_source_type() {
     530         [ +  - ]:         36 :     if (_sources.unified_type) {
     531   [ +  +  -  - ]:         36 :         switch (_sources.source_type) {
     532                 :            :             case Src_Abstract::Line:
     533 [ +  + ][ +  - ]:         35 :                 if (_sources.tailored) return "tailored";
     534         [ +  - ]:         34 :                 return "line";
     535                 :            :             case Src_Abstract::Point:
     536         [ +  - ]:          1 :                 return "point";
     537                 :            :             case Src_Abstract::CutEnd:
     538         [ #  # ]:          0 :                 return "cut-end";
     539                 :            :             default:
     540         [ #  # ]:          0 :                 return "undefined";
     541                 :            :         }
     542         [ #  # ]:         36 :     } else return "mixed";
     543                 :            : }
     544                 :            : 
     545                 :            : //! Get the number of valid injection points
     546                 :         36 : unsigned Parser::get_num_injection_points() {
     547                 :         36 :     return (unsigned) (_injection_points.injection_points.size());
     548                 :            : }
     549                 :            : 
     550                 :            : //! Gets the PDT-SPACE tissue properties
     551                 :         36 : void Parser::get_tissue_properties (vector<double>& dmin, vector<double>& dmax, vector<double>& guard, 
     552                 :            :         unordered_map<unsigned, string>& names) {
     553                 :            :     
     554                 :         36 :     dmin.resize(_materials.size() - 1);
     555                 :         36 :     dmax.resize(_materials.size() - 1);
     556                 :         36 :     guard.resize(_materials.size() - 1);
     557                 :         36 :     names.clear();
     558                 :            : 
     559 [ +  - ][ +  - ]:         36 :     names[0] = _materials[0].name;
     560                 :            : 
     561         [ +  + ]:        216 :     for (unsigned i = 1; i < _materials.size(); i++) {
     562 [ +  - ][ +  - ]:        180 :         names[i] = _materials[i].name;
     563                 :        180 :         guard[i - 1] = _materials[i].guardband;
     564                 :            : 
     565         [ +  + ]:        180 :         if (_materials[i].is_tumor) {
     566         [ -  + ]:         36 :             if (_materials[i].d_min < 1e-8) {
     567         [ #  # ]:          0 :                 fprintf(stderr, "\033[1;%dmMinimum dose threshold on Tumor CANNOT be ZERO! Exiting...\033[0m\n", 31);
     568                 :          0 :                 exit(-1);
     569                 :            :             }
     570                 :         36 :             dmin[i - 1] = _materials[i].d_min;
     571                 :            : 
     572         [ -  + ]:         36 :             if (_materials[i].d_max < 1e-8) {
     573                 :          0 :                 dmax[i - 1] = _INFINITY_;
     574                 :            :             } else {
     575                 :         36 :                 dmax[i - 1] = _materials[i].d_max;
     576                 :            :             }
     577                 :            : 
     578         [ +  + ]:         36 :             if (guard[i - 1] < 1) {
     579         [ +  - ]:          1 :                 fprintf(stderr, "\033[1;%dmWarning: guardband on tumor < 1!\033[0m\n", 33);
     580                 :            :             }
     581                 :            :         } else {
     582                 :        144 :             dmin[i - 1] = _materials[i].d_min; // Previously hardcoded to 0, keep or not?
     583                 :        144 :             dmax[i - 1] = _materials[i].d_max;
     584                 :            : 
     585         [ -  + ]:        144 :             if (guard[i - 1] > 1) {
     586         [ #  # ]:          0 :                 fprintf(stderr, "\033[1;%dmWarning: guardband on OAR > 1!\033[0m\n", 33);
     587                 :            :             }
     588                 :            :         }
     589                 :            :     }
     590                 :         36 : }
     591                 :            : 
     592                 :            : //! Gets the tumor region ids in an unordered_set
     593                 :         58 : void Parser::get_tumor_regions (unordered_set<unsigned>& tumor_regions) {
     594                 :         58 :     tumor_regions.clear();
     595                 :            : 
     596         [ +  + ]:        348 :     for (unsigned i = 1; i < _materials.size(); i++) {
     597 [ +  + ][ +  - ]:        290 :         if (_materials[i].is_tumor) tumor_regions.insert(_materials[i].id);
     598                 :            :     }
     599                 :         58 : }
     600                 :            : 
     601                 :            : //! Gets the map for FullMonte parameters
     602                 :         36 : unordered_map <string, string>& Parser::get_fm_params() {
     603                 :         36 :     return _fm_params_map;
     604                 :            : }
     605                 :            : 
     606                 :            : //! Gets the map for PDT-SPACE parameters
     607                 :         36 : unordered_map <string, string>& Parser::get_params() {
     608                 :         36 :     return _params_map;
     609                 :            : }
     610                 :            : 
     611                 :            : //! Gets the map for SA engine parameters
     612                 :          4 : unordered_map <string, string>& Parser::get_sa_params() {
     613                 :          4 :     return _sa_params_map;
     614 [ +  - ][ +  - ]:          4 : }

Generated by: LCOV version 1.12