Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PhysiMeSS addon and sample project #167

Merged
merged 55 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
147a269
Added PhysiMeSS addon
vincent-noel Mar 30, 2023
de1e35a
Added PhysiMeSS sample project
vincent-noel Mar 30, 2023
f750df4
Added small test in github actions
vincent-noel Mar 30, 2023
ba90bfd
Fix path for windows test
vincent-noel Mar 31, 2023
3d9e85d
Added a version number to PhysiMeSS addon
vincent-noel Mar 31, 2023
0f21c71
Added readme in the PhysiMeSS addon folder
vincent-noel Mar 31, 2023
fb99bc8
Fibre initialisation default values
CicelyKrystyna Apr 17, 2023
ef9442e
fibre initialisation default values
CicelyKrystyna Apr 17, 2023
af10789
Delete config/Fibre_Initialisation directory
CicelyKrystyna Apr 17, 2023
3495028
Update README.md
CicelyKrystyna Apr 17, 2023
b510bbb
physimess changes: uodate to readme and new fibre initialisation file
CicelyKrystyna Apr 17, 2023
b716d60
physimess changes: fibre degradation files update and changes to ReadMe
CicelyKrystyna Apr 18, 2023
3e0f05d
physimess change: change to some print statements
CicelyKrystyna Apr 19, 2023
4059bfe
physimess changes: updates to ReadMe detailing examples
CicelyKrystyna Apr 19, 2023
5f29bda
physimess changes: updates to ReadMe
CicelyKrystyna Apr 20, 2023
0bb5ea3
physimess changes: print statements for listing agent voxels
CicelyKrystyna Apr 20, 2023
4f53cc2
physimess changes: config directory with voxel/neighbour checking exa…
CicelyKrystyna Apr 20, 2023
76662b2
physimess changes: updates to crosslink finding function and simple e…
CicelyKrystyna Apr 20, 2023
9d61815
Implementation of physimess_neighbors
vincent-noel Apr 21, 2023
fe69ead
Now using original add potentials, and only use physimess neighbors w…
vincent-noel Apr 21, 2023
1e122cb
Now storing the list of voxels for each agent
vincent-noel Apr 21, 2023
c88981d
Using the voxel size from the container in register_fibre_voxels
vincent-noel Apr 21, 2023
5953aa3
Added custom cellcount function to the PhysiMESS sample project
vincent-noel Apr 22, 2023
d700271
Added a mechanism to clean PhysiMESS data structure if a fibre is del…
vincent-noel Apr 22, 2023
e06af9c
Added a mechanism to initialize PhysiMESS datastructure for new cells…
vincent-noel Apr 22, 2023
9c845e0
Improved make reset for PhysiMESS
vincent-noel Apr 22, 2023
b065611
Added omp critical pragmas when modifying the agent grid
vincent-noel Apr 24, 2023
af42c77
phsyimess changes: update to make reset and correction in Fibre_Cross…
CicelyKrystyna Apr 24, 2023
bbf76ad
Added draft of paint by cell pressure, and increased degradation rate…
vincent-noel Apr 25, 2023
85c6ded
physimess changes: fibre degradation updates
CicelyKrystyna May 2, 2023
b35bad7
physimess changes: updates to initialisation .xmls including fibre ra…
CicelyKrystyna May 16, 2023
51a0543
physimess updates: some changes to names of parameters and additional…
CicelyKrystyna May 18, 2023
21bf68e
Fix makefile after 1.12.0
vincent-noel May 30, 2023
ef9d24e
New version using Cell derived classes
vincent-noel Apr 23, 2023
ba0e187
Fix add potentials
vincent-noel May 30, 2023
dcaa9e5
add_potentials_* are now class member functions
vincent-noel Jun 16, 2023
829f84e
Cleanup
vincent-noel Jun 16, 2023
6525920
Degrade fibre is now within a virtual function, called in the add_pot…
vincent-noel Jun 16, 2023
ca00884
Cleanup
vincent-noel Jun 16, 2023
4227475
Default degradation function doesn't use cell pressure
vincent-noel Jun 16, 2023
595a46b
Added example of custom fibre degradation implementation
vincent-noel Jun 16, 2023
20517fd
Cleanup
vincent-noel Jun 16, 2023
dd58b09
Added parameter to choose if cell degradation depends on pressure
vincent-noel Jun 16, 2023
659f29f
Added a parameter to control the minimal movement to declare a cell s…
vincent-noel Jun 16, 2023
52d065d
Renaming PhysiMESS -> PhysiMeSS
vincent-noel Jun 18, 2023
76dfb83
Commented all outputs
vincent-noel Jun 18, 2023
07a728b
Assigning fibre orientation for randomly assigned fibres
vincent-noel Jun 19, 2023
8b2395a
Calling check_out_of_bounds after assign_fibre_orientation
vincent-noel Jun 19, 2023
b2b1bb2
Simplifying create_cell_types call by introducing a function to get a…
vincent-noel Jun 19, 2023
490eab4
Fix building of Fibre cell definitions vector
vincent-noel Jun 19, 2023
5dede70
Disabling spring adhesion of Fibre degradation example
vincent-noel Jun 19, 2023
edda44f
Activating degradation by default in the fibre_degradation example
vincent-noel Jun 19, 2023
4ce40e5
rename fibre_degradation_depends_on_pressure with fibre_custom_degrad…
vincent-noel Jun 19, 2023
5b455ae
Moved a bit the attractant in fibre_degradation so it won't be pushed…
vincent-noel Jun 21, 2023
69614fb
Made add_potential functions virtual so they can be overloaded
vincent-noel Jul 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion .github/workflows/test-macosx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,27 @@ jobs:

- name: Run PhysiBoSS cell lines project
run: |
./PhysiBoSS_Cell_Lines
./PhysiBoSS_Cell_Lines

build_physimess:

runs-on: macos-11

steps:
- uses: actions/checkout@v2

- name: Install dependencies
run : brew install gcc@11

- name: Build PhysiMeSS project
run: |
make physimess-sample
make clean
make PHYSICELL_CPP=g++-11

- name: Run PhysiMeSS project
run: |
./project config/mymodel.xml
./project config/Fibre_Initialisation/mymodel_initialisation.xml
./project config/Cell_Fibre_Mechanics/mymodel_rotating.xml

16 changes: 15 additions & 1 deletion .github/workflows/test-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,18 @@ jobs:

- name: Run PhysiBoSS cell lines project
run: |
./PhysiBoSS_Cell_Lines
./PhysiBoSS_Cell_Lines

- name: Build PhysiMeSS project
run: |
make reset
make physimess-sample
make clean
make

- name: Run PhysiMeSS project
run: |
./project config/mymodel.xml
./project config/Fibre_Initialisation/mymodel_initialisation.xml
./project config/Cell_Fibre_Mechanics/mymodel_rotating.xml

16 changes: 15 additions & 1 deletion .github/workflows/test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,18 @@ jobs:

- name: Run PhysiBoSS cell lines project
run: |
.\\PhysiBoSS_Cell_Lines.exe
.\\PhysiBoSS_Cell_Lines.exe

- name: Build PhysiMeSS project
run: |
make reset
make physimess-sample
make clean
make

- name: Run PhysiMeSS project
run: |
.\\project config\\mymodel.xml
.\\project config\\Fibre_Initialisation\\mymodel_initialisation.xml
.\\project config\\Cell_Fibre_Mechanics\\mymodel_rotating.xml

10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ name:
list-projects:
@echo "Sample projects: template biorobots-sample cancer-biorobots-sample cancer-immune-sample"
@echo " celltypes3-sample heterogeneity-sample pred-prey-farmer virus-macrophage-sample"
@echo " worm-sample interaction-sample mechano-sample rules-sample"
@echo " worm-sample interaction-sample mechano-sample rules-sample physimess-sample"
@echo ""
@echo "Sample intracellular projects: ode-energy-sample physiboss-cell-lines-sample cancer-metabolism-sample"
@echo ""
Expand Down Expand Up @@ -188,6 +188,14 @@ rules-sample:
cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml
cp ./sample_projects/rules_sample/config/* ./config/

physimess-sample:
cp ./sample_projects/physimess/custom_modules/* ./custom_modules/
touch main.cpp && cp main.cpp main-backup.cpp
cp ./sample_projects/physimess/main.cpp ./main.cpp
cp Makefile Makefile-backup
cp ./sample_projects/physimess/Makefile .
cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml
cp -r ./sample_projects/physimess/config/* ./config/

# ---- intracellular projects
ode-energy-sample:
Expand Down
254 changes: 254 additions & 0 deletions addons/PhysiMeSS/PhysiMeSS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
#include "PhysiMeSS.h"

#include <algorithm>
#include <iterator>


static double last_update_time = -mechanics_dt;

void remove_physimess_out_of_bounds_fibres()
{
for (auto* cell : *all_cells) {
if (isFibre(cell) && static_cast<PhysiMeSS_Fibre*>(cell)->fail_count >= 10)
{
// std::cout << "I failed to place " << cell->type_name << " "
// << cell->ID << " in the domain - I am deleting agent "
// << std::endl;
delete_cell(cell);
}
}
}

void physimess_update_cell_velocity( Cell* pCell, Phenotype& phenotype, double dt)
{

double movement_threshold = PhysiCell::parameters.doubles("fibre_stuck_threshold");
if (!isFibre(pCell) && phenotype.motility.is_motile) {

// Here I changed this, because here we don't have access to the old position, and I didn't want to track the old position
// So I'm using the previous velocity, which is not exactly the same (because of Adams-Bashforth), but is a good proxy
// if (dist(pCell->old_position, pCell->position) < movement_threshold) {
if (norm(pCell->get_previous_velocity())*mechanics_dt < movement_threshold) {
static_cast<PhysiMeSS_Cell*>(pCell)->stuck_counter++;
} else {
static_cast<PhysiMeSS_Cell*>(pCell)->stuck_counter = 0;
}
}

if( pCell->functions.add_cell_basement_membrane_interactions )
{
pCell->functions.add_cell_basement_membrane_interactions(pCell, phenotype,dt);
}

pCell->state.simple_pressure = 0.0;
pCell->state.neighbors.clear(); // new 1.8.0

if (!isFibre(pCell)) {
//First check the neighbors in my current voxel
for (auto* neighbor: pCell->get_container()->agent_grid[pCell->get_current_mechanics_voxel_index()])
{
if (!isFibre(neighbor)) {
pCell->add_potentials(neighbor);
}
}
for (auto neighbor_voxel_index: pCell->get_container()->underlying_mesh.moore_connected_voxel_indices[pCell->get_current_mechanics_voxel_index()])
{
if(!is_neighbor_voxel(pCell, pCell->get_container()->underlying_mesh.voxels[pCell->get_current_mechanics_voxel_index()].center, pCell->get_container()->underlying_mesh.voxels[neighbor_voxel_index].center, neighbor_voxel_index))
continue;

for (auto* neighbor: pCell->get_container()->agent_grid[neighbor_voxel_index])
{
if (!isFibre(neighbor)) {
pCell->add_potentials(neighbor);
}
}
}
} else {
// Count crosslinks
static_cast<PhysiMeSS_Fibre*>(pCell)->X_crosslink_count = 0;
if (static_cast<PhysiMeSS_Fibre*>(pCell)->fibres_crosslinkers.size() > 0){
static_cast<PhysiMeSS_Fibre*>(pCell)->X_crosslink_count = static_cast<PhysiMeSS_Fibre*>(pCell)->fibres_crosslinkers.size();
}

}

// std::cout << " AGENT " << pCell->type_name << " " << pCell->ID << " has " ;
//add potentials between pCell and its neighbors
for (auto* neighbor : static_cast<PhysiMeSS_Agent*>(pCell)->physimess_neighbors)
{
// std::cout << neighbor->type_name << " " << neighbor->ID << " " ;

// if( this->ID == other_agent->ID )
if( pCell != neighbor )
{
if (!isFibre(pCell) && !isFibre(neighbor)) {
//Already done above
continue;
} else
if (!isFibre(pCell) && isFibre(neighbor)) {
static_cast<PhysiMeSS_Cell*>(pCell)->add_potentials_from_fibre(static_cast<PhysiMeSS_Fibre*>(neighbor));
} else if (isFibre(pCell) && !isFibre(neighbor)) {
static_cast<PhysiMeSS_Fibre*>(pCell)->add_potentials_from_cell(static_cast<PhysiMeSS_Cell*>(neighbor));
} else if (isFibre(pCell) && isFibre(neighbor)) {
static_cast<PhysiMeSS_Fibre*>(pCell)->add_potentials_from_fibre(static_cast<PhysiMeSS_Fibre*>(neighbor));
} else {
// std::cout << " WARNING: interaction between errant cell-types has been called : " << pCell->type_name << ", " << neighbor->type_name << std::endl;
return;
}
}
}
// std::cout << std::endl;

if (!isFibre(pCell)) {

PhysiMeSS_Cell* ppCell = static_cast<PhysiMeSS_Cell*>(pCell);
int stuck_threshold = 10;
int unstuck_threshold = 1;

if (ppCell->stuck_counter == stuck_threshold){
// std::cout << "!HELP! cell " << pCell->ID << " gets stuck at time "
// << PhysiCell_globals.current_time << std::endl;
ppCell->stuck_counter = 0;
ppCell->unstuck_counter = 1;
}

if (1 <= ppCell->unstuck_counter && ppCell->unstuck_counter < unstuck_threshold+1) {
/*std::cout << " getting unstuck at time "
<< PhysiCell_globals.current_time << std::endl;*/
ppCell->unstuck_counter++;
ppCell->force_update_motility_vector(dt);
ppCell->velocity += phenotype.motility.motility_vector;
}
else {
pCell->update_motility_vector(dt);
pCell->velocity += phenotype.motility.motility_vector;
}

if(ppCell->unstuck_counter == unstuck_threshold+1){
ppCell->unstuck_counter = 0;
}
}
return;

}

void physimess_mechanics( double dt )
{
static double dt_tolerance = 0.001 * dt;
if(fabs(((PhysiCell_globals.current_time - last_update_time)) - dt) < dt_tolerance)
{
last_update_time = PhysiCell_globals.current_time;

#pragma omp parallel for
for( int i=0; i < (*all_cells).size(); i++ )
{
Cell* pC = (*all_cells)[i];

static_cast<PhysiMeSS_Agent*>(pC)->physimess_voxels.clear();
if( !pC->is_out_of_domain )
{
static_cast<PhysiMeSS_Agent*>(pC)->register_fibre_voxels();
}
}

#pragma omp parallel for
for( int i=0; i < (*all_cells).size(); i++ )
{
Cell* pC = (*all_cells)[i];
static_cast<PhysiMeSS_Agent*>(pC)->physimess_neighbors.clear();
if (isFibre(pC)) {
static_cast<PhysiMeSS_Fibre*>(pC)->fibres_crosslinkers.clear();
}
if( !pC->is_out_of_domain )
{
static_cast<PhysiMeSS_Agent*>(pC)->find_agent_neighbors();
}
}

#pragma omp parallel for
for( int i=0; i < (*all_cells).size(); i++ )
{
Cell* pC = (*all_cells)[i];
if( !pC->is_out_of_domain )
{
static_cast<PhysiMeSS_Agent*>(pC)->deregister_fibre_voxels();
}
}

// determine and add crosslinks
#pragma omp parallel for
for( int i=0; i < (*all_cells).size(); i++ )
{
Cell* pC = (*all_cells)[i];
if (isFibre(pC)) {
static_cast<PhysiMeSS_Fibre*>(pC)->add_crosslinks();
}
}
}
}


void fibre_agent_SVG(std::ofstream& os, PhysiCell::Cell* pC, double z_slice, std::vector<std::string> (*cell_coloring_function)(Cell*), double X_lower, double Y_lower) {

// place a rod if it's a fibre (note fibre already renamed here)
if (isFibre(pC) ){

PhysiMeSS_Fibre* pFibre = static_cast<PhysiMeSS_Fibre*>(pC);
int crosslinks = pFibre->X_crosslink_count;
if (crosslinks >= 3){
// if fibre has cross-links different colour than if not
Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
(pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
4.0, "darkblue");
}
else if (crosslinks == 2){
// if fibre has cross-links different colour than if not
Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
(pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
4.0, "blue");
}
else if (crosslinks == 1){
// if fibre has cross-links different colour than if not
Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
(pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
4.0, "steelblue");
}
else {
Write_SVG_line(os, (pC->position)[0] - (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] - (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
(pC->position)[0] + (pFibre->mLength) * (pC->state.orientation)[0] - X_lower,
(pC->position)[1] + (pFibre->mLength) * (pC->state.orientation)[1] - Y_lower,
4.0, "lightskyblue");
}

}
else{
standard_agent_SVG(os, pC, z_slice, cell_coloring_function, X_lower, Y_lower);
}
}

void fibre_agent_legend(std::ofstream& os, Cell_Definition* cell_definition, double& cursor_x, double& cursor_y, std::vector<std::string> (*cell_coloring_function)(Cell*), double temp_cell_radius) {

// switch to the cell type
Cell C;
C.convert_to_cell_definition( *cell_definition );

// get the colors using the current coloring function
std::vector<std::string> colors = cell_coloring_function(&C);

// place the label
// place a rod if it's a fibre (note fibre not yet renamed)
if (isFibre(&C)) {
//Write_SVG_fibre(os, cursor_x, cursor_y , 0.5*temp_cell_radius , 1.0 , colors[1] , colors[0] );
Write_SVG_line(os, cursor_x, cursor_y-20.0 , cursor_x , cursor_y+20.0 , 4.0 , "lightskyblue" );
}
else {
standard_agent_legend(os, cell_definition, cursor_x, cursor_y, cell_coloring_function, temp_cell_radius);
}
}
23 changes: 23 additions & 0 deletions addons/PhysiMeSS/PhysiMeSS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef __PHYSIMESS__
#define __PHYSIMESS__

#include "../../core/PhysiCell_cell.h"
#include "../../modules/PhysiCell_pathology.h"
#include "PhysiMeSS_cell.h"
#include "PhysiMeSS_fibre.h"

#include <list>

using namespace PhysiCell;

static std::string PhysiMeSS_Version = "1.0.0";

void remove_physimess_out_of_bounds_fibres();

void physimess_mechanics( double dt );
void physimess_update_cell_velocity( Cell* pCell, Phenotype& phenotype, double dt);

void fibre_agent_SVG(std::ofstream& os, PhysiCell::Cell* pCell, double z_slice, std::vector<std::string> (*cell_coloring_function)(Cell*), double X_lower, double Y_lower);
void fibre_agent_legend(std::ofstream& os, Cell_Definition* cell_definition, double& cursor_x, double& cursor_y, std::vector<std::string> (*cell_coloring_function)(Cell*), double temp_cell_radius);

#endif
Loading