Skip to content

Combining intracellular models with a single model - #415

Open
vincent-noel wants to merge 8 commits into
MathCancer:developmentfrom
vincent-noel:feat/intracellulars
Open

Combining intracellular models with a single model#415
vincent-noel wants to merge 8 commits into
MathCancer:developmentfrom
vincent-noel:feat/intracellulars

Conversation

@vincent-noel

Copy link
Copy Markdown
Collaborator

Hi all !

This is a PR on something I've been thinking about for some time: the possibility of having multiple types of intracellular models, and to have them interact. To achieve this, we need to modify a bit the implementation of Intracellular, mainly to change the variable in Phenotype, from an Intracellular pointer to a vector of Intracellular pointers.

This leads to a few more changes, such as having the pre/post intracellular update function belonging to the Intracellular object, and to add the Intracellular to a few method parameters (to be sure to have the "good" one).

Here I'm providing a quick example I build in the last days, which has an SBML ODE model for the TNF receptor binding and endocytosis and a Boolean model for the cell fate. To build it, use make spheroid_tnf.

For the ODE model, I'm using what I think is the latest implementation of roadrunner, based on #362 and #406. I had to modify a few things, such as introducing the Intracellular* parameter in many places, and I also changed the way the species values are modified before the update. So before thinking about merging this, we should focus on #362 and #406, and I can make a separate PR to have my changes too.

I am also working on example using the latest version of dFBA which is being developed at BSC by @marcorusc and @migp11, but I'll wait for them to submit their PR.

Let me know what you think !

@vincent-noel
vincent-noel changed the base branch from master to development March 31, 2026 20:00
@vincent-noel
vincent-noel force-pushed the feat/intracellulars branch 2 times, most recently from 742e7ae to 90d4278 Compare April 1, 2026 01:19
@drbergman

Copy link
Copy Markdown
Collaborator

I think this is really cool! We should have a conversation around next updates to Intracellular together since, as you pointed out, this interacts in non-trivial ways with other open PRs. This feels like a use-case for a GitHub project...

@migp11

migp11 commented Apr 1, 2026

Copy link
Copy Markdown

This sounds great! Together with @marcorusc and @othmya, we are finishing the physicell-dfba paper, which includes several different use cases that can be
@vincent-noel have you reimplemented the TNF receptor model in SBML from this publication?

@vincent-noel

Copy link
Copy Markdown
Collaborator Author

@migp11 Indeed, this is your TNF receptor model. That was the simplest example I could think of, and it worked.

About the AGS model, that's a nice idea. I have some reading to do, and then let's talk about this.

@drbergman drbergman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks 90% ready! Last 10% for me is just clarifying a couple changes. See individual comments.

For some of these comments, I'm unclear on the distinctions between start, clone, and inherit. If someone who knows how those work approves, I will approve regarding those comments, too.

Comment thread core/PhysiCell_cell.cpp
child->phenotype.intracellular->inherit(this);
for (size_t i=0; i < child->phenotype.intracellulars.size(); i++)
{
child->phenotype.intracellulars[i]->start();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just noting here that if we need to decide how to proceed with #425. the call to start() here would not be necessary. and I think we could make the inherit call unnecessary.

Comment thread core/PhysiCell_cell.cpp
Comment on lines +1142 to +1143
for (auto* intracellular: pNew->phenotype.intracellulars)
intracellular->start();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're confident we don't need to inherit here? I honestly don't know.

Comment thread core/PhysiCell_cell.cpp
Comment on lines -3195 to +3203
if (pParent != NULL && pParent->phenotype.intracellular != NULL) {
pCD->phenotype.intracellular->initialize_intracellular_from_pugixml(node);
if (pParent != NULL && pParent->phenotype.intracellulars.size() > 0) {
pCD->phenotype.intracellulars[0]->initialize_intracellular_from_pugixml(node);

// Otherwise we need to create a new one
} else {
MaBoSSIntracellular* pIntra = new MaBoSSIntracellular(node);
pCD->phenotype.intracellular = pIntra->getIntracellularModel();
pCD->phenotype.intracellulars.push_back(pIntra->getIntracellularModel());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code diff is hard for me to understand.

If the parent has an intracellular model,
    initialize the first intracellular of this cell def from the node.
else
    push a new one onto the end

Assuming that pCD inherits its intracellulars from pParent, we can't guarantee they share the same intracellular type. Also, why are we only updating the first entry here? I'll look for where we update further entries below.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found where further entries are updated below. I'm wondering now if this here is dead code.

Comment thread core/PhysiCell_cell.cpp
Comment on lines +3269 to +3316
#ifdef ADDON_PHYSIBOSS
if (model_type == "maboss") {
// If it has already be copied
if (pParent != NULL && pParent->phenotype.intracellulars.size() >= intracellular_count) {
pCD->phenotype.intracellulars[intracellular_count]->initialize_intracellular_from_pugixml(intracellular);

// Otherwise we need to create a new one
} else {
MaBoSSIntracellular* pIntra = new MaBoSSIntracellular(intracellular);
pCD->phenotype.intracellulars.push_back(pIntra->getIntracellularModel());
}
}
#endif

#ifdef ADDON_ROADRUNNER
if (model_type == "roadrunner")
{
// If it has already be copied
if (pParent != NULL && pParent->phenotype.intracellulars.size() >= intracellular_count)
{
// std::cout << "------ " << __FUNCTION__ << ": copying another\n";
pCD->phenotype.intracellulars[intracellular_count]->initialize_intracellular_from_pugixml(node);
}
// Otherwise we need to create a new one
else
{
std::cout << "\n------ " << __FUNCTION__ << ": creating new RoadRunnerIntracellular\n";
RoadRunnerIntracellular* pIntra = new RoadRunnerIntracellular(intracellular);
pIntra->validate_PhysiCell_tokens(pCD->phenotype);
pIntra->validate_SBML_species();
pCD->phenotype.intracellulars.push_back(pIntra->getIntracellularModel());

}
}
#endif

#ifdef ADDON_PHYSIDFBA
if (model_type == "dfba") {
// If it has already be copied
if (pParent != NULL && pParent->phenotype.intracellulars.size() > intracellular_count) {
pCD->phenotype.intracellulars[intracellular_count]->initialize_intracellular_from_pugixml(intracellular);
// Otherwise we need to create a new one
} else {
PhysiCelldFBA::dFBAIntracellular* pIntra = new PhysiCelldFBA::dFBAIntracellular(intracellular);
pCD->phenotype.intracellulars.push_back(pIntra->getIntracellularModel());
}
}
#endif

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah! This is what I was looking for. so what's the part above meant for then?

Comment on lines +1247 to +1258
Intracellular::Intracellular(const Intracellular *intracellular)
{
this->pre_update_intracellular = intracellular->pre_update_intracellular;
this->post_update_intracellular = intracellular->post_update_intracellular;
}

Intracellular* Intracellular::operator=(const Intracellular *intracellular ) {

this->pre_update_intracellular = intracellular->pre_update_intracellular;
this->post_update_intracellular = intracellular->post_update_intracellular;
return this;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we not want these to do inherit or clone? I'm speaking from ignorance here, but that seems to be something that we expect to happen every time we copy around Intracellular objects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants