Skip to content

Commit d792bd8

Browse files
committed
improve intracellular parsing
- if the intracellular type is set but the macro is not passed, the parser will now throw an error - if the intracellular is passed at the command line and the given cell type is not set therein, consider that to mean this cell type is not using intracellular
1 parent fcbc8ff commit d792bd8

File tree

5 files changed

+119
-75
lines changed

5 files changed

+119
-75
lines changed

VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.14.2-drbergman-1.3.0
1+
1.14.2-drbergman-1.3.1

core/PhysiCell_cell.cpp

Lines changed: 88 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,7 +2318,6 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node
23182318
// otherwise, modify properties of that model
23192319

23202320
// set up the death models
2321-
// int death_model_index = 0;
23222321
node = cd_node.child( "phenotype" );
23232322
node = node.child( "death" );
23242323
if( node )
@@ -2412,17 +2411,13 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node
24122411
if( node_temp )
24132412
{ death_params.lysed_fluid_change_rate = xml_get_my_double_value( node_temp ); }
24142413

2415-
// death_params.time_units =
2416-
// get_string_attribute_value( node, "unlysed_fluid_change_rate", "units" );
2417-
24182414
node = node.parent();
24192415
}
24202416

24212417
// set the model
24222418
// if the model already exists, just overwrite the parameters
24232419
if (model == PhysiCell_constants::apoptosis_death_model)
24242420
{
2425-
// pCD->phenotype.death.add_death_model( rate , &apoptosis , apoptosis_parameters );
24262421
if( death_model_already_exists == false )
24272422
{
24282423
pCD->phenotype.death.add_death_model( rate , &apoptosis , death_params );
@@ -2437,7 +2432,6 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node
24372432
else if (model == PhysiCell_constants::necrosis_death_model)
24382433
{
24392434
// set necrosis parameters
2440-
// pCD->phenotype.death.add_death_model( rate , &necrosis , necrosis_parameters );
24412435
if( death_model_already_exists == false )
24422436
{
24432437
pCD->phenotype.death.add_death_model( rate , &necrosis , death_params );
@@ -2960,11 +2954,7 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node
29602954
// pCI->dead_phagocytosis_rate = xml_get_my_double_value(node_dpr);
29612955
dead_phagocytosis_rate = xml_get_my_double_value(node_dpr);
29622956
}
2963-
/*
2964-
pCI->apoptotic_phagocytosis_rate = pCI->dead_phagocytosis_rate;
2965-
pCI->necrotic_phagocytosis_rate = pCI->dead_phagocytosis_rate;
2966-
pCI->other_dead_phagocytosis_rate = pCI->dead_phagocytosis_rate;
2967-
*/
2957+
29682958
pCI->apoptotic_phagocytosis_rate = dead_phagocytosis_rate;
29692959
pCI->necrotic_phagocytosis_rate = dead_phagocytosis_rate;
29702960
pCI->other_dead_phagocytosis_rate = dead_phagocytosis_rate;
@@ -3141,64 +3131,14 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node
31413131

31423132
// intracellular
31433133
node = cd_node.child( "phenotype" );
3144-
node = node.child( "intracellular" );
3145-
if( node )
3134+
node = node.child("intracellular");
3135+
if (node)
3136+
{
3137+
parse_intracellular_model(node, pCD, pParent);
3138+
}
3139+
else
31463140
{
3147-
std::string model_type = node.attribute( "type" ).value();
3148-
3149-
#ifdef ADDON_PHYSIBOSS
3150-
if (model_type == "maboss") {
3151-
argument_parser.read_intracellular_files(node, pCD->name, model_type);
3152-
// If it has already be copied
3153-
if (pParent != NULL && pParent->phenotype.intracellular != NULL) {
3154-
pCD->phenotype.intracellular->initialize_intracellular_from_pugixml(node);
3155-
3156-
// Otherwise we need to create a new one
3157-
} else {
3158-
MaBoSSIntracellular* pIntra = new MaBoSSIntracellular(node);
3159-
pCD->phenotype.intracellular = pIntra->getIntracellularModel();
3160-
}
3161-
}
3162-
#endif
3163-
3164-
#ifdef ADDON_ROADRUNNER
3165-
if (model_type == "roadrunner")
3166-
{
3167-
argument_parser.read_intracellular_files(node, pCD->name, model_type);
3168-
// If it has already be copied
3169-
if (pParent != NULL && pParent->phenotype.intracellular != NULL)
3170-
{
3171-
pCD->phenotype.intracellular->initialize_intracellular_from_pugixml(node);
3172-
}
3173-
// Otherwise we need to create a new one
3174-
else
3175-
{
3176-
RoadRunnerIntracellular* pIntra = new RoadRunnerIntracellular(node);
3177-
pCD->phenotype.intracellular = pIntra->getIntracellularModel();
3178-
}
3179-
pCD->phenotype.intracellular->validate_PhysiCell_tokens(pCD->phenotype);
3180-
pCD->phenotype.intracellular->validate_SBML_species();
3181-
}
3182-
#endif
3183-
3184-
#ifdef ADDON_PHYSIDFBA
3185-
if (model_type == "dfba") {
3186-
argument_parser.read_intracellular_files(node, pCD->name, model_type);
3187-
// If it has already be copied
3188-
if (pParent != NULL && pParent->phenotype.intracellular != NULL) {
3189-
pCD->phenotype.intracellular->initialize_intracellular_from_pugixml(node);
3190-
// Otherwise we need to create a new one
3191-
} else {
3192-
dFBAIntracellular* pIntra = new dFBAIntracellular(node);
3193-
pCD->phenotype.intracellular = pIntra->getIntracellularModel();
3194-
}
3195-
}
3196-
#endif
3197-
3198-
} else{
3199-
32003141
pCD->phenotype.intracellular = NULL;
3201-
32023142
}
32033143

32043144
// set up custom data
@@ -3283,10 +3223,90 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node
32833223
exit(-1);
32843224
#endif
32853225
}
3286-
3226+
32873227
return pCD;
32883228
}
32893229

3230+
void parse_intracellular_model(pugi::xml_node node, Cell_Definition* pCD, Cell_Definition* pParent)
3231+
{
3232+
std::string model_type = node.attribute( "type" ).value();
3233+
bool uses_intracellular = argument_parser.read_intracellular_files(node, pCD->name, model_type);
3234+
if (!uses_intracellular) {
3235+
return;
3236+
}
3237+
3238+
if (model_type == "maboss")
3239+
{
3240+
#ifdef ADDON_PHYSIBOSS
3241+
// If it has already be copied
3242+
if (pParent != NULL && pParent->phenotype.intracellular != NULL)
3243+
{
3244+
pCD->phenotype.intracellular->initialize_intracellular_from_pugixml(node);
3245+
3246+
// Otherwise we need to create a new one
3247+
}
3248+
else
3249+
{
3250+
MaBoSSIntracellular *pIntra = new MaBoSSIntracellular(node);
3251+
pCD->phenotype.intracellular = pIntra->getIntracellularModel();
3252+
}
3253+
#else
3254+
std::cerr << "ERROR: MaBoSS intracellular model is not supported in this build." << std::endl
3255+
<< "\tMake sure to compile with the -D ADDON_PHYSIBOSS flag." << std::endl;
3256+
exit(-1);
3257+
#endif
3258+
}
3259+
3260+
else if (model_type == "roadrunner")
3261+
{
3262+
#ifdef ADDON_ROADRUNNER
3263+
// If it has already be copied
3264+
if (pParent != NULL && pParent->phenotype.intracellular != NULL)
3265+
{
3266+
pCD->phenotype.intracellular->initialize_intracellular_from_pugixml(node);
3267+
}
3268+
// Otherwise we need to create a new one
3269+
else
3270+
{
3271+
RoadRunnerIntracellular *pIntra = new RoadRunnerIntracellular(node);
3272+
pCD->phenotype.intracellular = pIntra->getIntracellularModel();
3273+
}
3274+
pCD->phenotype.intracellular->validate_PhysiCell_tokens(pCD->phenotype);
3275+
pCD->phenotype.intracellular->validate_SBML_species();
3276+
#else
3277+
std::cerr << "ERROR: RoadRunner intracellular model is not supported in this build." << std::endl
3278+
<< "\tMake sure to compile with the -D ADDON_ROADRUNNER flag." << std::endl;
3279+
exit(-1);
3280+
#endif
3281+
}
3282+
3283+
else if (model_type == "dfba")
3284+
{
3285+
#ifdef ADDON_PHYSIDFBA
3286+
// If it has already be copied
3287+
if (pParent != NULL && pParent->phenotype.intracellular != NULL)
3288+
{
3289+
pCD->phenotype.intracellular->initialize_intracellular_from_pugixml(node);
3290+
// Otherwise we need to create a new one
3291+
}
3292+
else
3293+
{
3294+
dFBAIntracellular *pIntra = new dFBAIntracellular(node);
3295+
pCD->phenotype.intracellular = pIntra->getIntracellularModel();
3296+
}
3297+
#else
3298+
std::cerr << "ERROR: dFBA intracellular model is not supported in this build." << std::endl
3299+
<< "\tMake sure to compile with the -D ADDON_PHYSIDFBA flag." << std::endl;
3300+
#endif
3301+
}
3302+
3303+
else
3304+
{
3305+
std::cerr << "ERROR: Intracellular model type " << model_type << " is not supported." << std::endl;
3306+
exit(-1);
3307+
}
3308+
}
3309+
32903310
void initialize_cell_definitions_from_pugixml( pugi::xml_node root )
32913311
{
32923312
pugi::xml_node node_options;

core/PhysiCell_cell.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ Cell_Definition* initialize_cell_definition_from_pugixml( pugi::xml_node cd_node
292292
void initialize_cell_definitions_from_pugixml( pugi::xml_node root );
293293
void initialize_cell_definitions_from_pugixml( void );
294294

295+
void parse_intracellular_model(pugi::xml_node node, Cell_Definition* pCD, Cell_Definition* pParent);
296+
295297
extern std::vector<double> (*cell_division_orientation)(void);
296298

297299
void attach_cells( Cell* pCell_1, Cell* pCell_2 );

modules/PhysiCell_settings.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,10 +1106,31 @@ void ArgumentParser::print_usage(std::ostream& os, const char* program_name)
11061106
<< " " << program_name << " path_to_config_file " << options_requiring_flag << std::endl;
11071107
}
11081108

1109-
void ArgumentParser::read_intracellular_files(pugi::xml_node& node_config_intracellular, const std::string &cell_definition, const std::string &intracellular_type)
1109+
1110+
/**
1111+
* @brief Reads intracellular files based on the provided configuration and cell definition.
1112+
*
1113+
* This function attempts to read intracellular mappings from an XML file specified by the
1114+
* `path_to_intracellular_mappings_file`. If the file is not provided, it will look in the
1115+
* configuration node as usual. It ensures that there is only one intracellular mapping per
1116+
* cell type and sets the intracellular files accordingly. If this file is found and a mapping
1117+
* is found for the given cell definition and intracellular type, the function will set the
1118+
* intracellular files, but not the parameters which are set in the config file.
1119+
*
1120+
* @param node_config_intracellular The XML node containing the intracellular configuration.
1121+
* @param cell_definition The name of the cell definition to look for in the mappings file.
1122+
* @param intracellular_type The type of intracellular model to look for.
1123+
* @return true if either no intracellular file was passed in at the command line or intracellular
1124+
* mappings are found and set, false otherwise.
1125+
*
1126+
* @throws std::runtime_error if there are errors in loading or parsing the XML file, or if
1127+
* multiple mappings are found where only one is expected.
1128+
*/
1129+
bool ArgumentParser::read_intracellular_files(pugi::xml_node& node_config_intracellular, const std::string &cell_definition, const std::string &intracellular_type)
11101130
{
1111-
if (path_to_intracellular_mappings_file=="")
1112-
{ return; }
1131+
bool uses_intracellular = path_to_intracellular_mappings_file==""; // if an intracellular file was not passed in at the command line, then go ahead and look in the config as normal
1132+
if (uses_intracellular)
1133+
{ return uses_intracellular; }
11131134

11141135
pugi::xml_document physicell_intracellular_mappings_doc;
11151136

@@ -1147,7 +1168,7 @@ void ArgumentParser::read_intracellular_files(pugi::xml_node& node_config_intrac
11471168
}
11481169

11491170
if (!found)
1150-
{ return; }
1171+
{ return false; } // no intracellular mappings for this cell type
11511172

11521173
pugi::xml_node node_intracellular_ids = node_this_cell_definition.child("intracellular_ids");
11531174
if (!node_intracellular_ids)
@@ -1171,7 +1192,7 @@ void ArgumentParser::read_intracellular_files(pugi::xml_node& node_config_intrac
11711192
}
11721193

11731194
if (!one_id_found)
1174-
{ return; }
1195+
{ return false; } // reaching here (currently) means that there are no intracellular mappings for this cell type. above, we handle the case of finding 2+
11751196

11761197
pugi::xml_node node_intracellulars = mappings_root.child("intracellulars");
11771198
if (!node_intracellulars)
@@ -1218,6 +1239,7 @@ void ArgumentParser::read_intracellular_files(pugi::xml_node& node_config_intrac
12181239

12191240
std::string base_path_to_filename = path_to_intracellular_mappings_file.substr(0, path_to_intracellular_mappings_file.find_last_of(".")) + "_" + cell_definition + "_ID" + intracellular_ids[0];
12201241
set_intracellular_files(node_config_intracellular, node_this_intracellular, base_path_to_filename, intracellular_type);
1242+
return true; // intracellular mappings found for this cell type, so we will use them
12211243
}
12221244

12231245
void set_intracellular_files(pugi::xml_node &node_config_intracellular, const pugi::xml_node &node_this_intracellular, const std::string &base_path_to_filename, const std::string &intracellular_type)

modules/PhysiCell_settings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ class ArgumentParser {
255255

256256
ArgumentParser() {};
257257

258-
void read_intracellular_files(pugi::xml_node& node_config_intracellular, const std::string &cell_definition, const std::string &intracellular_type);
258+
bool read_intracellular_files(pugi::xml_node& node_config_intracellular, const std::string &cell_definition, const std::string &intracellular_type);
259259

260260
void print_usage(std::ostream& os, const char* program_name);
261261
};

0 commit comments

Comments
 (0)