MathCancer / PhysiCell

PhysiCell: Scientist end users should use latest release! Developers please fork the development branch and submit PRs to the dev branch. Thanks!
http://PhysiCell.org
145 stars 100 forks source link

custom cell division; cell lineage #269

Open rheiland opened 4 months ago

rheiland commented 4 months ago

Rather than submit a PR for this, as it's probably premature, I wanted to share/discuss a branch (https://github.com/rheiland/PhysiCell/tree/custom-division) that implements:

To test, rather than add another directory in sample_projects (which requires editing all of those Makefiles), I opted to add a sample_division_lineage to user_projects. Yes, I know this sort of violates its original purpose, but thought we could discuss this practice (with the sample_ prefix).

So, to test:

The following image shows results of being able to do asymmetric division, using the new custom function (rf. custom.cpp). However, note that it requires providing the custom function in create_cell_types (in custom.cpp); rf. https://github.com/MathCancer/PhysiCell/issues/265 .

Screenshot 2024-07-14 at 6 18 13 PM

And these screenshots show the outcome of displaying the new cells' generation and parentID scalars.

Screenshot 2024-07-14 at 5 55 11 PM
drbergman commented 4 months ago

This looks amazing! Still plenty to be done to make standard asym div functions, etc, but this will hopefully get us over the barrier to start really working on this. One comment:

  1. I think we may want generation to increment for both daughter cells on division. This number, as I understand it, tracks how many cell divisions from the initial ancestor of this cell until this one. This will not always be recoverable from counting parentID's since some of those may be removed from the simulation before a save event.
rheiland commented 4 months ago

Thanks for the review and comments! I agree on generation being incremented for both; I was in a fog, in part, because I was using "Fixed" cell cycle rates. I've pushed changes and show some updated plots here.

Personally, for the foreseeable future, I think asym div functions should be handled by users in custom.cpp.

Screenshot 2024-07-15 at 9 22 51 AM Screenshot 2024-07-15 at 9 22 37 AM
drbergman commented 4 months ago

Oh really? I'd be curious to hear why you're hesitant. I think if we add a asymmetric division probability to [cell def] behavior (and possibly a symmetric division probability to [cell def] behavior), then we're basically there. Those would be added in identical fashion as the transformation rates, for example. We'd just write a standard_asymmetric_cell_division_function that is non-NULL if any of these probabilities are nonzero / rules affect the probabilities. Then more little details to attend to (e.g., don't want probabilities to sum to more than 1) and I think we're there.

rheiland commented 4 months ago

OK, I could be convinced. But I think we all agree that any changes involving the XML requires more work - involving the Studio and rules. Guess I'm just thinking that a path with limited functionality (in custom.cpp) could make it into a release sooner.

pdalcastel commented 4 months ago

I think a new division function is not necessary for the asymmetric division. I think the ideal solution is the following:

-> being able to access the cell id of parent and daughter cell at the time of division in the custom.cpp.

This way the user can change the type manually. I did not know how to do that, hence I changed the division function and implemented the asymmetric division by brute force.

Besides that, yes, the generation count should be incremented in both cells. However, to simulate something like the cancer stem cell hypothesis, the stem cells always have the same division capacity, which is passed onwards to daughter cells. Then non stem daughter cells lose 1 division capacity per symmetric division. They die when this number reaches zero. So in our simulation we start the generation count at zero whenever a new non stem cell is born from a stem cell. And then we used Physicell rules to kill it when generation count reached the division capacity.

drbergman commented 4 months ago

In regards to asymmetric division: I think that is a good (and likely the right) approach, and that is how I understand what @rheiland did here.

That does sound like a very reasonable way to model that hypothesis. I think for default settings, we would need to stick with incrementing generation at each division. Changing it in your custom_division_function for your own purposes could still be an option, it just may not work with any future pipelines that use the default generation for analyzing model output.