diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 062d26c35..60c113345 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -19,8 +19,8 @@ jobs: - uses: msys2/setup-msys2@v2 with: update: true - install: base-devel flex bison gcc make diffutils mingw-w64-x86_64-toolchain - + install: base-devel flex bison gcc make diffutils mingw-w64-x86_64-toolchain mingw-w64-x86_64-ca-certificates + - name: Build Virus Macrophage project run: | make virus-macrophage-sample diff --git a/.gitignore b/.gitignore index edf896b99..3a96ffe47 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,14 @@ sample_projects/cancer_biorobots/.DS_Store sample_projects/cancer_immune/.DS_Store sample_projects/celltypes3/.DS_Store sample_projects/heterogeneity/.DS_Store -sample_projects/template/.DS_Store \ No newline at end of file +sample_projects/template/.DS_Store +pmb_debug.log +heterogeneity +**/.DS_Store +**/._.DS_Store +cancer_immune_3D +biorobots +project +initial.svg +initial.svg +interaction_demo diff --git a/BioFVM/BioFVM_MultiCellDS.cpp b/BioFVM/BioFVM_MultiCellDS.cpp index e9d9dfa75..9d77e78b4 100644 --- a/BioFVM/BioFVM_MultiCellDS.cpp +++ b/BioFVM/BioFVM_MultiCellDS.cpp @@ -1387,4 +1387,48 @@ void read_microenvironment_from_MultiCellDS_xml( Microenvironment& M_destination return; } +bool read_microenvironment_from_matlab( std::string mat_filename ) +{ + std::cout << std::endl << "Attempting to load the microenvironment from " << mat_filename << " ... " << std::endl; + + std::vector< std::vector > mat = read_matlab( mat_filename ); + + // row 0 : x + // row 1 : y + // row 2 : z + // row 3 : vol + // row 4-n : substrate + int num_rows = mat.size(); + int num_cols = mat[0].size(); + + int number_of_mat_voxels = num_cols; + int number_of_mat_substrates = num_rows - 3 -1; + + if( number_of_mat_substrates != microenvironment.number_of_densities() ) + { + std::cout << "Error reading microenvironment from " << mat_filename << "! "; + std::cout << "Expected " << microenvironment.number_of_densities() << " substrates but only detected " + << number_of_mat_substrates << std::endl; + return false; + } + + if( number_of_mat_voxels != microenvironment.number_of_voxels() ) + { + std::cout << "Error reading microenvironment from " << mat_filename << "! "; + std::cout << "Expected " << microenvironment.number_of_voxels() << " voxels but only detected " + << number_of_mat_voxels << std::endl; + return false; + } + + for( int n=0 ; n < number_of_mat_voxels ; n++ ) + { + // std::cout << microenvironment.mesh.voxels[n].center << " vs " << mat[0][n] << " " << mat[1][n] << " " << mat[2][n] << std::endl; + for( int k=4; k < num_rows ; k++ ) + { microenvironment(n)[k-4] = mat[k][n]; } + } + + std::cout << "done!" << std::endl << std::endl; + return true; +} + }; diff --git a/BioFVM/BioFVM_MultiCellDS.h b/BioFVM/BioFVM_MultiCellDS.h index ad283b514..ad61ea574 100644 --- a/BioFVM/BioFVM_MultiCellDS.h +++ b/BioFVM/BioFVM_MultiCellDS.h @@ -188,6 +188,10 @@ void add_BioFVM_to_open_xml_pugi( pugi::xml_document& xml_dom , std::string file void save_BioFVM_to_MultiCellDS_xml_pugi( std::string filename_base , Microenvironment& M , double current_simulation_time); +/* beta in PhysiCell 1.11.0 */ + +bool read_microenvironment_from_matlab( std::string mat_filename ); + /* future / not yet supported */ void read_BioFVM_from_open_xml_pugi( pugi::xml_document& xml_dom , std::string filename_base, double& current_simulation_time , Microenvironment& M ); diff --git a/CITATION.txt b/CITATION.txt index 66b1ea46d..e8de5a7c0 100644 --- a/CITATION.txt +++ b/CITATION.txt @@ -1,7 +1,7 @@ If you use PhysiCell in your project, please cite PhysiCell and the version number, such as below: -We implemented and solved the model using PhysiCell (Version 1.10.4) [1]. +We implemented and solved the model using PhysiCell (Version 1.11.0) [1]. [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- @@ -11,7 +11,7 @@ We implemented and solved the model using PhysiCell (Version 1.10.4) [1]. Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM as below: -We implemented and solved the model using PhysiCell (Version 1.10.4) [1], +We implemented and solved the model using PhysiCell (Version 1.11.0) [1], with BioFVM [2] to solve the transport equations. [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, diff --git a/Makefile b/Makefile index 595ea5cd2..0cee2c68a 100644 --- a/Makefile +++ b/Makefile @@ -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" + @echo " worm-sample interaction-sample mechano-sample" @echo "" @echo "Sample intracellular projects: ode-energy-sample physiboss-cell-lines-sample cancer-metabolism-sample" @echo "" @@ -93,7 +93,7 @@ template: biorobots-sample: cp ./sample_projects/biorobots/custom_modules/* ./custom_modules/ touch main.cpp && cp main.cpp main-backup.cpp - cp ./sample_projects/biorobots/main-biorobots.cpp ./main.cpp + cp ./sample_projects/biorobots/main.cpp ./main.cpp cp Makefile Makefile-backup cp ./sample_projects/biorobots/Makefile . cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml @@ -102,7 +102,7 @@ biorobots-sample: cancer-biorobots-sample: cp ./sample_projects/cancer_biorobots/custom_modules/* ./custom_modules/ touch main.cpp && cp main.cpp main-backup.cpp - cp ./sample_projects/cancer_biorobots/main-cancer_biorobots.cpp ./main.cpp + cp ./sample_projects/cancer_biorobots/main.cpp ./main.cpp cp Makefile Makefile-backup cp ./sample_projects/cancer_biorobots/Makefile . cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml @@ -129,7 +129,7 @@ celltypes3-sample: heterogeneity-sample: cp ./sample_projects/heterogeneity/custom_modules/* ./custom_modules/ touch main.cpp && cp main.cpp main-backup.cpp - cp ./sample_projects/heterogeneity/main-heterogeneity.cpp ./main.cpp + cp ./sample_projects/heterogeneity/main.cpp ./main.cpp cp Makefile Makefile-backup cp ./sample_projects/heterogeneity/Makefile . cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml @@ -208,6 +208,13 @@ cancer-metabolism-sample: cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml cp ./sample_projects_intracellular/fba/cancer_metabolism/config/* ./config/ +mechano-sample: + cp ./sample_projects/mechano/custom_modules/* ./custom_modules/ + touch main.cpp && cp main.cpp main-backup.cpp + cp ./sample_projects/mechano/main.cpp ./main.cpp + cp Makefile Makefile-backup + cp ./sample_projects/mechano/Makefile . + cp ./sample_projects/mechano/config/* ./config/ # early examples for convergence testing @@ -422,3 +429,25 @@ upgrade: $(SOURCE) mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/README.md b/README.md index 702d26d0e..05463e00c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems -**Version:** 1.10.4 +**Version:** 1.11.0 -**Release date:** 18 July 2022 +**Release date:** 20 March 2023 ## Overview: PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. @@ -16,7 +16,7 @@ Visit http://MathCancer.org/blog for the latest tutorials and help. ### Key makefile rules: -**`make`** : compiles the current project. If no +**`make`**: compiles the current project. If no project has been defined, it first populates the cancer heterogeneity 2D sample project and compiles it @@ -38,6 +38,7 @@ Visit http://MathCancer.org/blog for the latest tutorials and help. * physiboss-cell-lines-sample * cancer-metabolism-sample * interaction-sample + * mechano-sample **`make list-projects`** : list all available sample projects @@ -74,249 +75,185 @@ See changes.md for the full change log. * * * ## Release summary: -Version 1.10.4 primarily fixes bugs in file output and the ode-energy sample, and refines thread safety in cell phagocytosis. - -The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. - -A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. -A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. +Version 1.11.0 adds several notable features, fixes bugs, and further expands the "signals" and "behaviors" that can be read and written with a simple API to facilitate building models. In particular, we add a brand new CSV format for initial cell positions (with more robust naming of cells by their human-readable names, a "header" line, and ability to extensively add and specificy individual cell properties), a new ability to save and load user projects in the `user_projects` directory, automated dynamic formation and breakage of spring-based cell-cell adhesions (based upon the cell-cell adhesion affinities, attachment rates, and detachment rates), automated inclusion of spring-based adhesions (at the mechanics time step) without need for the user to explicitly supply a spring function, a new "mechano" sample project to illustrate the new automated spring functionality, and updates to PhysiBoSS to ensure compatibility with the rapidly improving PhysiCell Studio. In addition, there is new capability of adding a background coloring (e.g., an oxygen heatmap) to SVG ouptuts--see the `interaction-sample` for an illustration (use the alternate XML config file to enable). This release includes several bugfixes, the most critical of which is to update the parameters for necrotic cells (which had previously been misset in the XML files, thus disabling necrotic cell lysis and shrinking). **NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. **NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. -### Major new features and changes in the 1.10.z versions -#### 1.10.4 -+ None in this version. See 1.10.0 -#### 1.10.3 -+ None in this version. See 1.10.0 -#### 1.10.2 -+ None in this version. See 1.10.0 -#### 1.10.1 -+ None in this version. See 1.10.0 -#### 1.10.0 -+ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. - + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. - + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. - + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. - + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. - + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. - + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. - + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. - -+ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. - + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). - + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` - -+ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. - + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. - + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. - + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - -+ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: - + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). - + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - -+ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of signals include: - + extracellular and intracellular substrate concentrations - + substrate gradients - + contact with dead cells - + contact with cells (of type X) - + damage - + pressure - + Use `display_signal_dictionary()` to quickly display a list of available signals. - + Substantial functionality to query signals - + `int find_signal_index( std::string signal_name )` : get the index of the named signal - + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals - + `std::string signal_name( int i );` display the name of the signal with the given index - + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell - + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell - + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices - + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals - + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index - + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name - -+ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of behaviors include: - + secretion, secretion target, uptake, and export rates - + cycle progression - + death rates - + motility parameters - + chemotactic parameters - + cell-cell adhesion and repulsion parameters - + cell adhesion affinities - + cell-BM adhesion and repulsion parameters - + phagocytosis rates - + attack rates - + fusion rates - + transformation rates - + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. - + Substantial functionality to query and set behaviors - + `int find_behavior_index( std::string response_name )` : get the index of the named behavior - + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. - + `std::string behavior_name( int i );` get the name of the behavior with the given index - + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors - + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype - + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype - + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype - + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype - + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype - + Substantial functionality to query the cell's current behavior - + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors - + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) - + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) - + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) - + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) - + Substantial functionality to query the cell's referece behaviors (from its cell definition) - + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors - + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) - + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) - + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) - + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) - -+ Created a new `interaction-sample` project to illustrate the new interactions and transformations: - + Blood vessels release resource - + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) - + Stem cells divide and differentiate into differentiated cells - + Differentiated cells divide until experiencing elevated pressure (to detect confluence) - + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. - + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria - + Macrophages phagocytose dead cells - + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria - + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria - + Accumulated damage kills bacteria. - + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. +### Major new features and changes in the 1.11.z versions +#### 1.11.0 ++ New and improved (v2) cell CSV format for cell import. This allows more intuitive statement of initial cell positions. The first line of your CSV file must be: + + ```x,y,z,cell type``` + + Every subsequent line is a single cell, now referencing cell types by their human-readable names (as defined in your XML configuration file) rather than requiring the integer `ID`. So, a sample second line to place a CD8 T cell at (30,-10,12) would be: + + ```30,-10,12,CD8 T cell``` + + Moreover, the new format allows you to initialize a variety of individual cell properties, including (total) `volume` and any supported cell beheavior. For example, if your cell definitions have custom variables `GFP` ond `oncoprotein`, then you can extend the first header line to: + + ```x,y,z,cell type,custom:GFP,custom:oncoprotein``` + + And then subsequent cells look like this: + + ```30,-10,12,CD8 T cell,0.5,3.2``` + + You can tell our parser to skip specifying a specific variable with `s` or `S` or an empty entry. Here, the first cell would skip writing the initial value of the GFP, and teh second would skip initializing the oncoprotein: + + ```30,-10,12,CD8 T cell,,3.2``` + ```50,13,-4,M0 Macrophage,0.5,s``` + + We will continue to automatically support older CSV cell files; any cells CSV file missing the first line of headers will be processed in the old format. + ++ Ability to save and load user projects + + Use `make save PROJ=project_name` to save your project to a folder in `./user_projects` named `project_name`. For example: + + ```make save PROJ=new_tumor_sample``` + + saves your project as `new_tumor_sample`. In particular, it saves your `Makefile`, `main.cpp`, everything in `./config`, and everything in `./custom_modules`. + + + Use `make load PROJ=project_name` to load your project from a folder in `./user_projects` named `project_name`. For example: + + ```make load PROJ=new_tumor_sample``` + + loads your project from `new_tumor_sample`. In particular, it loads your `Makefile`, `main.cpp`, everything in `./config`, and everything in `./custom_modules`. + ++ Extended `cell_interactions` to include a vector `immunogenicities`: for a cell, `immunogenicity[j]` is how immunogenic this cell is to the jth cell type. By default, these will all be set to 1. (See next point.) + ++ Updated the built-in "attack" model: + $$\textrm{Probability cell } i \textrm{ attacks cell } j \textrm{ in } [t,t+\Delta t] = \textrm{attack}\_{ij} \cdot \textrm{immunogenicity}\_{ji} \Delta t $$ + By setting $\textrm{immunogenicity}\_{ji} = 1$ as teh default value, we maintain compatibiltiy with prior models. This is a way to further modulate immunogenic and cytotoxic interactions. + ++ Began migrating built-in sample projects to be compatible with the model builder GUI and the upcoming PhysiCell Studio, including: + + template + + biorobots (updates spring constant from 0.05 to 0.5) + + heterogeneity + + cancer biorobots (updates spring constant from 0.05 to 0.5) + ++ Added new signals: + + `apoptotic` returns 1 if a cell is apoptotic, and 0 otherwise + + `necrotic` returns 1 if a cell is necrotic, and 0 otherwise + + As always, access these via `double get_single_signal(Cell* pCell,std::string sig_name)`. + ++ Added new behaviors: + + `immunogenicity to [cell type]` is the cell's immunogenicity to a specific cell type. The probability that cell `i` attacks cell `j` in $[t,t+\Delta t]$ is $\textrm{attack}\_{ij} \cdot \textrm{immunogenicity}\_{ji} \Delta t.$ + + `cell attachment rate` is the rate at which the cell forms spring links with other cells. + + `cell detachment rate` is the rate at which spring links break. + + `maximum number of cell attachments` is the maximum number of spring links. + + `is_movable` can be set to 0 (false) to make an agent rigid: it will exert forces on other cells, but it itself cannot be moved. This behavior right now is somewhat fragile if used dynmaically, but can reliably be used during tissue setup. + + As always, access these via `double get_single_behavior(Cell* pCell,std::string beh_name)` and `void set_single_behavior(Cell* pCell,std::string beh_name,double new_value)`. + ++ Added new standard model `void dynamic_attachments(Cell*, Phenotype& ,double);` This function can automate dynamic attachments and detachments. When calling this function for cell $i$: + + For each current attachment, it detaches with probability $\textrm{detachment rate}\_i \Delta t$ + + For each cell $j$ in the neighbors list, it forms an attachment with probability + + $$\textrm{Prob attach } i \textrm{ to cell } j = \textrm{adhesion affinity}\_j \cdot \textrm{attachment rate}\_i \cdot \Delta t.$$ + + The attachment is only formed if both cell $i$ and $j$ have not exceeded their maximum number of + attachments. + ++ Added a new `spring_attachments` (of type `std::vector`) to cell `state` to track automated formation and removal of spring-link adhesions separately of the user-focused `attached` data struture. This will allow users to continue managing the `attachments` structure on their own for custom contact functions, without interference from automated springs (see more below). + ++ Added new standard model `void dynamic_spring_attachments(Cell*, Phenotype& ,double);` This functions exactly as the `dynamic_attachments` function, except it stores attached cells to `cell.state.spring_attachments` to avoid interfering with the user-managed `cell.state.attachments` data struture. + ++ **Automated spring attachments / detachments:** the new `dynamic_spring_attachments` function is automatically called at every mechancis time step, with cell-cell spring attachment and detachment based on the cells' current rates. Each cell evaluates spring-like elastic adhesion betwen itslef and cells in `cell.state.spring_attachments` to add to its own velocity. Some notes: + + Each cell automatically removes all its spring attachments during division + + Each cell automatically removes all its spring attachments at the *end* of death. If you want dead cells to have increased detachment, add a rule accordingly using the built-in behavior dictionary. + + If a cell is not movable (`is_movable = false`), then it is not moved by springs, but it can exert spring forces on other cells, allowing it to act as an "anchor". + + This automated spring functionality is completely independent of (and does not interfere with) the user-defined contact function and user-manageed `cell.state.attached` data structure. + + **WARNING:** If in a past life you set `phenotype.mechanics.attachment_rate` to a nonzero rate, you may find yourself surprised with unintended spring adhesions as this new automation kicks in. Please review and revise your configuration file as necessary. + + You can disable this behavior in the XML configuration file: + ``` + + + true + + ++ Added a new `mechano-sample` project that shows automated dynamic attachment and detachment of cells: + + Constant cancer cell birth and death + + Basic mechano feedback: high-pressure sets cancer cell birth to zero + + Cancer cell phenotype sets high detachment rate upon death. + + Automated connection of cancer, basement membrane (BM) agents with spring links using the built-ins noted above. No user intervention or code required beyond setting nonzero rates. + + Cancer cells manually set to apoptose at 10000 min. + ++ Updated PhysiBoSS to remove cell definition "inheritance," (with "flat", self-standing cell definitions), to make it compatible with PhysiCell Studio. Hereafter, all properties of each cell definition must be explicitely defined. ### Minor new features and changes: -#### 1.10.4 -+ None in this version. -#### 1.10.3 -+ Added `attachment_rate` and `detachment_rate` to `phenotype.mechanics` for use in a future standard attachment and detachment model. -+ Modernized output format: - + More complete cell data saved for each cell agent. - + Merged the previously separate cell matlab files for each time save - + Added more metadata to outputs -+ `Variables` and `Vector_Variables` in `Custom_Cell_Data` now have a new Boolean attribute `conserved_quantity` (defaulted to false). If this value is set to true, then the custom variable is divided evenly between daughter cells at division. -+ Custom cell data can now be designated as conserved by settings an attribute `conserved="true"` in the XMO configuration file. -+ Improved support for Apple M1 and M2 chips. -+ Refinements to PhysiBoSS. - -#### 1.10.2 -+ Added `operator<<` for vectors of ints and vectors of strings. So that `std::cout << v << std::endl;` will work if `v` is `std::vector` of `std::vector`. It was truly annoying that these were missing, so sorry! -+ Added `dead` to the signals dictionaries, which returns 0.0 or 1.0 based on `phenotype.death.dead`. -+ Added `time` to the signals dictionaries, which returns the current simulation time based on `PhysiCell_Globals.current_time`. -+ Added a brief protocol on how to add new signals and behaviors to the dictionaries in the `/protocols` directory. -+ Added new functions `double& apoptosis_rate()` and `double& necrosis_rate()` to easily read and write these rates. Access via `cell.phenotype.death.apoptosis_rate()` and `cell.phenotype.death.necrosis_rate()`. -+ Added new ease of access functions for secretion: - + `double& Secretion::secretion_rate( std::string name )` allows you to easily read/write the secretion rate of a substrate by name. For example: - ```pCell->phenotype.secretion.secretion_rate("oxygen") = 0.1``` - + `double& Secretion::uptake_rate( std::string name )` allows you to easily read/write the uptake rate of a substrate by name. For example: - ```pCell->phenotype.secretion.uptake_rate("oxygen") = 0.1``` - + `double& Secretion::saturation_density( std::string name )` allows you to easily read/write the secretion target of a substrate by name. For example: - ```pCell->phenotype.secretion.saturation_density("oxygen") = 38``` - + `double& Secretion::net_export_rate( std::string name )` allows you to easily read/write the net export rate of a substrate by name. For example: - ```pCell->phenotype.secretion.net_export_rate("oxygen") = -100``` - -+ Added new ease of access function for internalized substrates: - + `double& Molecular::internalized_total_substrate( std::string name )` allows you to easily read/write the total amount of internalized substrate by name. For example: - ```pCell->phenotype.molecular.internalized_total_substrate( "oxygen" ) = 0.01`` -#### 1.10.1 -+ None in this version. See 1.10.0. -#### 1.10.0 -+ All sample projects have a new rule "make name" to tell you the name of the executable. - -+ All sample projects output the executable name to screen for easier reference. - -+ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. - -+ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. +#### 1.11.0 ++ Updated the `paint_by_number_cell_coloring` coloring function to paint the entire cell white if apoptotic, and brown if necrotic. (Previously, we colored the nucleus based on live/dead status.) This improves compatibility with the model GUI. + ++ Changed the default value of `attachment_rate` from 10 to 0 (in the `Mechanics` class) to avoid unexpected triggering of automated spring adheions. + ++ Added a safety check to `operator[]` for Parameters, based on [PR145](https://github.com/MathCancer/PhysiCell/pull/145/). Thanks, Vincent Noel!! + ++ In PhysiBoSS, introduced a new state inheritance mechanism (global, and node-specific). + ++ PhisBoSS has a new optional start time, to initiate the intracellular model at t > 0. + ++ Updated PhysiBoSS Cell Lines sample project (flatten XML, initial positions as CSV). + ++ Started combining change log into a more compact format: Each release family (1.y.z, such as 1.10.z) receives an extended entry with new changes grouped by minor release. This allows major releases to be grouped with subsequent minor feature enhancements and bug fixes, for a much shorter change log that's easier to read. README will document all changes of the current release family. ### Beta features (not fully supported): -#### 1.10.4 -+ None in this version. -#### 1.10.3 -+ Each time outputs two cell interaction graphs (as text files): - + neighbor graph records which cells are within interaction distance for each cell agent, with format; - ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of interacting cells) - + attached cell graph records which cells are attached for each cell agent, with format; - ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of attached cells) - + We might split these into 3 files: - + an ID list that has the ID of each cell in order of appearence. - + neighbor list omits the preceding "ID:" since now each row corresponds to the index in the ID list - + attached cell list omits the preceding "ID:" since now each row corresponds to the index in the ID list - + Began experimenting with a planned `integrity` subclass to `phenotype` that will record multiple types of cell damage and associated damage and repair rates. It is not yet clear if we wil provide built-in support for damaged-driven apoptotic death and cycle arrest, as these are generally better left to modeler-driven hypotheses. - -None in this version. See 1.10.0. -#### 1.10.2 -+ None in this version. See 1.10.0. -#### 1.10.1 - + None in this version. See 1.10.0. - #### 1.10.0 -+ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. - -+ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) - -+ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) - -+ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) - -+ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) - +#### 1.11.0 ++ Added `bool read_microenvironment_from_matlab( std::string mat_filename )` to `BioFVM_MultiCellDS`. This will read and overwrite from a stored microenvironment (in `mat_filename`, saved as a level 4 Matlab file) if it has the following format: + + Number of columns = number of voxels (must match the size as configured in the `PhysiCell_settings.xml` file) + + Number of rows = 3 + 1 + number of diffusing substrates (must match the size and ordering as configured in the `PhysiCell_settings.xml` file) + + Row 0: x coordinate of each voxel + + Row 1: y coordinate of each voxel + + Row 2: z coordinate of each voxel + + Row 3: volume of each voxel + + Rows j to end: value of (j-4)th substrate in each voxel + + Column ordering: + * For each z from low to high: + * For each y from low to high: + * for each x from low to high: + store voxel X[i] , Y[j], Z[k]. + + **Note:** This matches how PhysiCell saves the microenvironment. This will read any PhysiCell-saved microenvironment, so long as its sizes matches your current settings. + + **Note:** This may be fragile. It has only minimal error-checking. + + + Set default cell attachment rate to 0 in the template project and most sample projects to avoid unexpectedly triggering the new autmoated spring adhesions; users must affirmatively set a nonzero attachment rate to trigger this new automation in an individual cell. + + + In repsonse to [PR 123](https://github.com/MathCancer/PhysiCell/pull/123), `parameters.TYPE.find_index(search_name)` now returns -1 if the searched term isn't found. Thanks, Daniel Bergman! + ### Bugfixes: -#### 1.10.4 -+ Fixed vectorized outputs in MultiCellDS that incorrectly assumed linear data ordering in std::vector. Thank you Randy Heiland! -+ Fixed errors in the ode-energy-sample project. Thank you Randy Heiland, Furkan Kurtoglu, and John Metzcar! -+ Improved thread safety in phagocytosis. Thank you Michael Getz! -#### 1.10.3 -+ Fixed bug in `get_single_behavior` and `get_single_base_behavior` where querying any cycle exit rate or cycle entry mistakenly returned -1. -+ Corrected declaration of `standard_add_basement_membrane_interactions` in `PhysiCell_standard_models.h` to properly use phenotype by reference. Thank you Inês Gonçalves! -+ Removed the OpenMP pragma in `void Microenvironment::apply_dirichlet_conditions( void )` (around line 272) that tends to perform more poorly than serial code. +#### 1.11.0 ++ Fixed bug in cancer biorobots project that mistakenly set max cancer cell proliferation rate to 0.000072 instead of 0.00072 -#### 1.10.2 -+ Fixed error in `double get_single_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. ++ Fixed multiple broken signals/behaviors. -+ Fixed error in `double get_single_base_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. ++ Fixed calcification bug reported in issue [133](https://github.com/MathCancer/PhysiCell/issues/133). Thank you, @JulianoGianlupi! -+ Fixed bug in `add_PhysiCell_cells_to_open_xml_pugi()` that mistakenly used the wrong size (number of cell species rather than number of substrate species) when writing the chemotactic sensitivities. ++ Fixed typo in cell signals that used `contact with dead dell` instead of `contact with dead cell` -+ The cell `neighbors` list did not add non-adhesive cells within interaction distance. This is now fixed. ++ Changed default full data output to 60 minutes (to match the SVG output interval) for better compatibility with the model builder GUI. -#### 1.10.1 -+ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. ++ Fixed incorrect parameters for necrotic cell volume changes that prevented necrotic cell lysis and shrinkage. -+ Missing PhysiBoSS makefiles have been replaced. ++ Merged Daniel Bergman's [PR 126](https://github.com/MathCancer/PhysiCell/pull/126), which fixes cell legend colors. Thank's Daniel! -+ Fixed broken makefile for worms sample project. ++ Improved safety checks in the cell orientation function, thanks to Randy Heiland's [PR 122](https://github.com/MathCancer/PhysiCell/pull/122). Thanks, Randy! -#### 1.10.0 -+ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. ++ Now forcing Mersenne Twister as random generator in PhysiBoSS (use or /dev/random by MaBoSS would max out system descriptor) -+ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. ++ MaBoSS BND/CFG parsing is now in an OpenMP critical block (flex/bison parser is not thread safe) -+ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. ++ Remove duplicate initialization of maximum attachment rate from the Phenotype.Mechanics constructor. -+ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! ++ Fixed bug in neighbor/attached graph output filenames (previously double-appended a suffix to the filenames). ### Notices for intended changes that may affect backwards compatibility: + We intend to deprecate the unused phenotype variables `relative_maximum_attachment_distance`, `relative_detachment_distance`, and `maximum_attachment_rate` from `phenotype.mechanics.` -+ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the future. + We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. -+ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. ++ Additional search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. diff --git a/VERSION.txt b/VERSION.txt index 5a68790ef..169f19b49 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.10.4 \ No newline at end of file +1.11.0 \ No newline at end of file diff --git a/addons/PhysiBoSS/src/maboss_intracellular.cpp b/addons/PhysiBoSS/src/maboss_intracellular.cpp index 9dd89a561..80d028fbc 100644 --- a/addons/PhysiBoSS/src/maboss_intracellular.cpp +++ b/addons/PhysiBoSS/src/maboss_intracellular.cpp @@ -6,11 +6,18 @@ MaBoSSIntracellular::MaBoSSIntracellular() : Intracellular() initial_values.clear(); mutations.clear(); parameters.clear(); + listOfInputs.clear(); + listOfOutputs.clear(); } MaBoSSIntracellular::MaBoSSIntracellular(pugi::xml_node& node) { intracellular_type = "maboss"; + initial_values.clear(); + mutations.clear(); + parameters.clear(); + listOfInputs.clear(); + listOfOutputs.clear(); initialize_intracellular_from_pugixml(node); } @@ -24,6 +31,8 @@ MaBoSSIntracellular::MaBoSSIntracellular(MaBoSSIntracellular* copy) time_tick = copy->time_tick; scaling = copy->scaling; time_stochasticity = copy->time_stochasticity; + inherit_state = copy->inherit_state; + inherit_nodes = copy->inherit_nodes; initial_values = copy->initial_values; mutations = copy->mutations; parameters = copy->parameters; @@ -43,15 +52,13 @@ MaBoSSIntracellular::MaBoSSIntracellular(MaBoSSIntracellular* copy) maboss.set_time_stochasticity(copy->time_stochasticity); maboss.restart_node_values(); indicesOfInputs.clear(); - for (MaBoSSInput& input: listOfInputs) { - indicesOfInputs.push_back(PhysiCell::find_signal_index(input.physicell_name)); + for (const auto& input: listOfInputs) { + indicesOfInputs.push_back(PhysiCell::find_signal_index(input.second.physicell_name)); } indicesOfOutputs.clear(); - for (MaBoSSOutput& output: listOfOutputs) { - indicesOfOutputs.push_back(PhysiCell::find_behavior_index(output.physicell_name)); + for (const auto& output: listOfOutputs) { + indicesOfOutputs.push_back(PhysiCell::find_behavior_index(output.second.physicell_name)); } - //maboss.set_state(copy->maboss.get_maboss_state()); - //std::cout << get_state(); } } @@ -59,30 +66,33 @@ void MaBoSSIntracellular::update_inputs(PhysiCell::Cell* cell, PhysiCell::Phenot { std::vector signals = PhysiCell::get_selected_signals(cell, indicesOfInputs); - for (unsigned int i=0; i < listOfInputs.size(); i++) + int i=0; + for (auto& input: listOfInputs) { - MaBoSSInput& input = listOfInputs[i]; - if (input.isNode()) { + if (input.second.isNode()) { maboss.set_node_value( - input.intracellular_name, - input.updateNode(maboss.get_node_value(input.intracellular_name), signals[i]) + input.first, + input.second.updateNode(maboss.get_node_value(input.second.intracellular_name), signals[i]) ); - } else if (input.isParameter()) { + } else if (input.second.isParameter()) { maboss.set_parameter_value( - input.intracellular_parameter, - input.updateParameter(signals[i]) + input.first, + input.second.updateParameter(signals[i]) ); } + i++; } } void MaBoSSIntracellular::update_outputs(PhysiCell::Cell* cell, PhysiCell::Phenotype& phenotype, double dt) { std::vector signals = std::vector(listOfOutputs.size(), 0.0); - for (unsigned int i=0; i < listOfOutputs.size(); i++) + + int i=0; + for (auto& output: listOfOutputs) { - MaBoSSOutput& output = listOfOutputs[i]; - signals[i] = output.update(maboss.get_node_value(output.intracellular_name)); + signals[i] = output.second.update(maboss.get_node_value(output.second.intracellular_name)); + i++; } PhysiCell::set_selected_behaviors(cell, indicesOfOutputs, signals); } @@ -93,10 +103,31 @@ void MaBoSSIntracellular::initialize_intracellular_from_pugixml(pugi::xml_node& pugi::xml_node node_bnd = node.child( "bnd_filename" ); if ( node_bnd ) { bnd_filename = PhysiCell::xml_get_my_string_value (node_bnd); } + else + { std::cerr << "Error : No BND model file defined !" << std::endl; exit(-1); } pugi::xml_node node_cfg = node.child( "cfg_filename" ); if ( node_cfg ) { cfg_filename = PhysiCell::xml_get_my_string_value (node_cfg); } + else + { std::cerr << "Error : No CFG model file defined !" << std::endl; exit(-1); } + + // Setting all the rest to default values : Nothing should be kept from the existing intracellular object (NO INHERITANCE) + time_step = 12; + discrete_time = false; + time_tick = 0.5; + scaling = 1.0; + time_stochasticity = 0.0; + inherit_state = false; + start_time = 0.0; + initial_values.clear(); + mutations.clear(); + parameters.clear(); + inherit_nodes.clear(); + listOfInputs.clear(); + indicesOfInputs.clear(); + listOfOutputs.clear(); + indicesOfOutputs.clear(); pugi::xml_node node_init_values = node.child( "initial_values" ); if( node_init_values ) @@ -208,6 +239,29 @@ void MaBoSSIntracellular::initialize_intracellular_from_pugixml(pugi::xml_node& maboss.set_time_stochasticity(time_stochasticity); } + pugi::xml_node node_inheritance = node_settings.child( "inheritance" ); + if( node_inheritance ) + { + pugi::xml_attribute global_inheritance = node_inheritance.attribute( "global" ); + inherit_state = global_inheritance.as_bool(); + + pugi::xml_node node_inherit_node = node_inheritance.child( "inherit_node" ); + while( node_inherit_node ) + { + pugi::xml_attribute node_inherit_intracellular_name = node_inherit_node.attribute( "intracellular_name" ); + bool inherit_value = PhysiCell::xml_get_my_bool_value( node_inherit_node ); + inherit_nodes[node_inherit_intracellular_name.value()] = inherit_value; + + node_inherit_node = node_inheritance.next_sibling( "inherit_node" ); + } + + } + + pugi::xml_node node_start_time = node_settings.child( "start_time" ); + if( node_start_time ) + { + start_time = PhysiCell::xml_get_my_double_value( node_start_time ); + } } @@ -315,7 +369,11 @@ void MaBoSSIntracellular::initialize_intracellular_from_pugixml(pugi::xml_node& (settings && settings.child( "smoothing" ) ? PhysiCell::xml_get_my_int_value( settings.child( "smoothing" )) : 0) ); - listOfInputs.push_back(input); + // This construct is a trick to avoid making inputs and outputs constructible and assignable, or using c++17 insert_or_assign + // Using the same construct below + auto const res = listOfInputs.insert(std::pair(intracellular_name, input)); + if (!(res.second)) { res.first->second = input; } + } else { MaBoSSInput input = MaBoSSInput( @@ -327,8 +385,8 @@ void MaBoSSIntracellular::initialize_intracellular_from_pugixml(pugi::xml_node& (settings && settings.child( "smoothing" ) ? PhysiCell::xml_get_my_int_value( settings.child( "smoothing" )) : 0) ); - listOfInputs.push_back(input); - + auto const res = listOfInputs.insert(std::pair(intracellular_name, input)); + if (!(res.second)) { res.first->second = input; } } node_input = node_input.next_sibling( "input" ); @@ -338,16 +396,18 @@ void MaBoSSIntracellular::initialize_intracellular_from_pugixml(pugi::xml_node& while (node_output) { pugi::xml_node settings = node_output.child("settings"); - - listOfOutputs.push_back(MaBoSSOutput( - node_output.attribute( "physicell_name" ).value(), + std::string physicell_name = node_output.attribute( "physicell_name" ).value(); + MaBoSSOutput output = MaBoSSOutput( + physicell_name, node_output.attribute( "intracellular_name" ).value(), PhysiCell::xml_get_my_string_value(settings.child("action")), PhysiCell::xml_get_my_double_value(settings.child("value")), (settings && settings.child( "base_value" ) ? PhysiCell::xml_get_my_double_value( settings.child( "base_value" )) : PhysiCell::xml_get_my_double_value(settings.child("value"))), (settings && settings.child( "smoothing" ) ? PhysiCell::xml_get_my_int_value( settings.child( "smoothing" )) : 0) - )); + ); + auto const res = listOfOutputs.insert(std::pair(physicell_name, output)); + if (!(res.second)) { res.first->second = output; } node_output = node_output.next_sibling( "output" ); } } @@ -376,33 +436,39 @@ void MaBoSSIntracellular::display(std::ostream& os) os << "\t\t\t" << mutation.first << " = " << mutation.second << std::endl; os << "\t\t scaling = " << scaling << std::endl - << "\t\t time_stochasticity = " << time_stochasticity << std::endl; + << "\t\t time_stochasticity = " << time_stochasticity << std::endl + << "\t\t start_time = " << start_time << std::endl; os << "\t\t " << listOfInputs.size() << " input mapping defined" << std::endl; - for (auto& input : listOfInputs) - os << "\t\t\t" << input.physicell_name << " = " << input.intracellular_name - << "(" << input.threshold << ", " << input.inact_threshold << ", " << input.smoothing << ")" + for (const auto& input : listOfInputs) + os << "\t\t\t" << input.second.physicell_name << " = " << input.first + << "(" << input.second.threshold << ", " << input.second.inact_threshold << ", " << input.second.smoothing << ")" << std::endl; os << "\t\t " << listOfOutputs.size() << " output mapping defined" << std::endl; - for (auto& output : listOfOutputs) - os << "\t\t\t" << output.physicell_name << " = " << output.intracellular_name - << "(" << output.value << ", " << output.base_value << ", " << output.smoothing << ")" + for (const auto& output : listOfOutputs) + os << "\t\t\t" << output.first << " = " << output.second.intracellular_name + << "(" << output.second.value << ", " << output.second.base_value << ", " << output.second.smoothing << ")" << std::endl; - + + os << "\t\t global inheritance = " << inherit_state << std::endl; + os << "\t\t " << inherit_nodes.size() << " node-specific inheritance defined" << std::endl; + for (const auto& node_inheritance : inherit_nodes) + os << "\t\t\t" << node_inheritance.first << " = " << node_inheritance.second + << std::endl; + std::cout << std::endl; } void MaBoSSIntracellular::save(std::string filename, std::vector& cells) { - std::ofstream state_file( filename ); state_file << "ID,state" << std::endl; for( auto cell : cells ) - state_file << cell->ID << "," << static_cast(cell->phenotype.intracellular)->get_state() << std::endl; - + if (cell->phenotype.intracellular != NULL) + state_file << cell->ID << "," << static_cast(cell->phenotype.intracellular)->get_state() << std::endl; + state_file.close(); - } \ No newline at end of file diff --git a/addons/PhysiBoSS/src/maboss_intracellular.h b/addons/PhysiBoSS/src/maboss_intracellular.h index eab16b43a..2f7958f5b 100644 --- a/addons/PhysiBoSS/src/maboss_intracellular.h +++ b/addons/PhysiBoSS/src/maboss_intracellular.h @@ -10,7 +10,7 @@ #include "maboss_network.h" #include "utils.h" -static std::string PhysiBoSS_Version = "2.1.0"; +static std::string PhysiBoSS_Version = "2.2.0"; class MaBoSSIntracellular : public PhysiCell::Intracellular { private: @@ -26,18 +26,21 @@ class MaBoSSIntracellular : public PhysiCell::Intracellular { double time_tick = 0.5; double scaling = 1.0; double time_stochasticity = 0.0; + bool inherit_state = false; + std::map inherit_nodes; + double start_time = 0.0; std::map initial_values; std::map mutations; std::map parameters; - std::vector listOfInputs; + std::map listOfInputs; std::vector indicesOfInputs; - std::vector listOfOutputs; + std::map listOfOutputs; std::vector indicesOfOutputs; MaBoSSNetwork maboss; - double next_physiboss_run = 0; + double next_physiboss_run = 0.0; MaBoSSIntracellular(); @@ -56,6 +59,7 @@ class MaBoSSIntracellular : public PhysiCell::Intracellular { void start() { this->maboss.restart_node_values(); + this->next_physiboss_run = std::max(this->start_time, PhysiCell::PhysiCell_globals.current_time); } void update() { @@ -74,6 +78,12 @@ class MaBoSSIntracellular : public PhysiCell::Intracellular { return PhysiCell::PhysiCell_globals.current_time >= this->next_physiboss_run; } + void inherit(PhysiCell::Cell * cell) { + maboss.inherit_state( + static_cast(cell->phenotype.intracellular)->maboss.get_maboss_state(), + inherit_state, inherit_nodes + ); + } void update_inputs(PhysiCell::Cell* cell, PhysiCell::Phenotype& phenotype, double dt); void update_outputs(PhysiCell::Cell * cell, PhysiCell::Phenotype& phenotype, double dt); @@ -118,4 +128,4 @@ class MaBoSSIntracellular : public PhysiCell::Intracellular { }; -#endif \ No newline at end of file +#endif diff --git a/addons/PhysiBoSS/src/maboss_network.cpp b/addons/PhysiBoSS/src/maboss_network.cpp index 035944ddb..5e31f3a1f 100644 --- a/addons/PhysiBoSS/src/maboss_network.cpp +++ b/addons/PhysiBoSS/src/maboss_network.cpp @@ -16,13 +16,23 @@ void MaBoSSNetwork::init_maboss( std::string networkFile, std::string configFile } try{ - // Initialize MaBoSS Objects for a model - this->network = new Network(); - this->network->parse(networkFile.c_str()); - - this->config = new RunConfig(); - this->config->parse(this->network, configFile.c_str()); - + + #pragma omp critical + { + // Initialize MaBoSS Objects for a model + this->network = new Network(); + this->network->parse(networkFile.c_str()); + + this->config = new RunConfig(); + this->config->parse(this->network, configFile.c_str()); + } + + // Some models will have chosen to use the physical randon number generator + // This is a problem, as it will open /dev/urandom for each cell, and overload the number of file open + // So for now we just don't use this, and choose by default mersen twister + this->config->setParameter("use_physrandgen", false); + this->config->setParameter("use_mtrandgen", true); + IStateGroup::checkAndComplete(this->network); engine = new StochasticSimulationEngine(this->network, this->config, PhysiCell::UniformInt()); @@ -112,11 +122,18 @@ bool MaBoSSNetwork::has_node( std::string name ) { } void MaBoSSNetwork::set_node_value(std::string name, bool value) { - state.setNodeState(nodesByName[name], value); + if (has_node(name)) + state.setNodeState(nodesByName[name], value); + else + std::cout << "Can't find node " << name << "!!!!" << std::endl; } bool MaBoSSNetwork::get_node_value(std::string name) { - return state.getNodeState(nodesByName[name]); + if (has_node(name)) + return state.getNodeState(nodesByName[name]); + else + std::cout << "Can't find node " << name << "!!!!" << std::endl; + return true; } std::string MaBoSSNetwork::get_state() { diff --git a/addons/PhysiBoSS/src/maboss_network.h b/addons/PhysiBoSS/src/maboss_network.h index 580939e17..5aace16d3 100644 --- a/addons/PhysiBoSS/src/maboss_network.h +++ b/addons/PhysiBoSS/src/maboss_network.h @@ -143,6 +143,37 @@ class MaBoSSNetwork void set_state(NetworkState _state) { state = NetworkState(_state.getState()); } NetworkState get_maboss_state() { return state;} + void inherit_state(NetworkState mother, bool inherit_state, std::map& inherit_nodes) { + NetworkState new_state; + if (inherit_state){ + // If we inherit, we start from the state of the mother cell + new_state = mother; + } else { + // Else we start from the state of the daughter cell + new_state = state; + } + + // Then we look at individual inheritance + for (auto& inherit_node: inherit_nodes) { + + Node* node = network->getNode(inherit_node.first); + + // If we inherit from the model, we just do it + if (inherit_node.second) { + new_state.setNodeState(node,mother.getNodeState(node)); + + } else { + if (inherit_state){ + // Else if we don't inherit this node, but inherit_state is true, it means we exclude this node from the global inheritance + // So we take the value in state instead + new_state.setNodeState(node, state.getNodeState(node)); + } + } + } + + // Finally we set the state + set_state(new_state); + } }; #endif diff --git a/addons/dFBA/src/dfba_intracellular.h b/addons/dFBA/src/dfba_intracellular.h index f916a7f09..54800e1e4 100644 --- a/addons/dFBA/src/dfba_intracellular.h +++ b/addons/dFBA/src/dfba_intracellular.h @@ -76,7 +76,8 @@ class dFBAIntracellular : public PhysiCell::Intracellular void update(){ }; void update(PhysiCell::Cell* pCell, PhysiCell::Phenotype& phenotype, double dt); - + void inherit(PhysiCell::Cell * cell) {} + int update_phenotype_parameters(PhysiCell::Phenotype& phenotype); bool has_variable(std::string name) { return true; } diff --git a/addons/libRoadrunner/src/librr_intracellular.h b/addons/libRoadrunner/src/librr_intracellular.h index 257322221..4ca8b041a 100644 --- a/addons/libRoadrunner/src/librr_intracellular.h +++ b/addons/libRoadrunner/src/librr_intracellular.h @@ -93,6 +93,8 @@ class RoadRunnerIntracellular : public PhysiCell::Intracellular update_phenotype_parameters(phenotype); } + void inherit(PhysiCell::Cell * cell) {} + int update_phenotype_parameters(PhysiCell::Phenotype& phenotype); int validate_PhysiCell_tokens(PhysiCell::Phenotype& phenotype); int validate_SBML_species(); diff --git a/beta/setup_libmaboss.py b/beta/setup_libmaboss.py index faf08b68c..0a32db52f 100644 --- a/beta/setup_libmaboss.py +++ b/beta/setup_libmaboss.py @@ -21,20 +21,20 @@ # Assume Windows mb_file = "" url = "" - + maboss_version = "v2.5.2" if os_type.lower() == 'darwin': if "ARM64" in platform.uname().version: mb_file = "libMaBoSS-macos-arm64.tar.gz" url = "https://github.com/PhysiCell-Tools/intracellular_libs/raw/main/boolean/libMaBoSS-macos-arm64.tar.gz" else: mb_file = "libMaBoSS-osx64.tar.gz" - url = "https://github.com/sysbio-curie/MaBoSS-env-2.0/releases/download/v2.4.1/" + mb_file + url = "https://github.com/sysbio-curie/MaBoSS-env-2.0/releases/download/" + maboss_version + "/" + mb_file elif os_type.lower().startswith("win") or os_type.lower().startswith("msys_nt") or os_type.lower().startswith("mingw64_nt"): mb_file = "libMaBoSS-win64.tar.gz" - url = "https://github.com/sysbio-curie/MaBoSS-env-2.0/releases/download/v2.4.1/" + mb_file + url = "https://github.com/sysbio-curie/MaBoSS-env-2.0/releases/download/" + maboss_version + "/" + mb_file elif os_type.lower().startswith("linux"): mb_file = "libMaBoSS-linux64.tar.gz" - url = "https://github.com/sysbio-curie/MaBoSS-env-2.0/releases/download/v2.4.1/" + mb_file + url = "https://github.com/sysbio-curie/MaBoSS-env-2.0/releases/download/" + maboss_version + "/" + mb_file else: print("Your operating system seems to be unsupported. Please submit a ticket at https://sourceforge.net/p/physicell/tickets/ ") sys.exit(1) diff --git a/beta/test_build_all.sh b/beta/test_build_all.sh index 45e128e09..a79902e9e 100644 --- a/beta/test_build_all.sh +++ b/beta/test_build_all.sh @@ -39,6 +39,9 @@ make make reset make interaction-sample make +make reset +make mechano-sample +make # now the intracellular models, requiring additional libs make reset diff --git a/changes-old.md b/changes-old.md new file mode 100644 index 000000000..c598be44d --- /dev/null +++ b/changes-old.md @@ -0,0 +1,4487 @@ +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems + +**Version:** 1.11.0 + +**Release date:** 20 March 2023 + +## Overview: +PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. + +**Reference:** A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: [10.1371/journal.pcbi.1005991](https://dx.doi.org/10.1371/journal.pcbi.1005991) + +Visit http://MathCancer.org/blog for the latest tutorials and help. + +**Notable recognition:** ++ [2019 PLoS Computational Biology Research Prize for Public Impact](https://blogs.plos.org/biologue/2019/05/31/announcing-the-winners-of-the-2019-plos-computational-biology-research-prize/) + +### Key makefile rules: + +**`make`**: compiles the current project. If no + project has been defined, it first + populates the cancer heterogeneity 2D + sample project and compiles it + +**`make project-name`**: populates the indicated sample project. + Use "make" to compile it. + + * **`project-name`** choices: + * template + * biorobots-sample + * cancer-biorobots-sample + * cancer-immune-sample + * celltypes3-sample + * heterogeneity-sample + * pred-prey-farmer + * virus-macrophage-sample + * worm-sample + * ode-energy-sample + * physiboss-cell-lines-sample + * cancer-metabolism-sample + * interaction-sample + * mechano-sample + +**`make list-projects`** : list all available sample projects + +**`make clean`** : removes all .o files and the executable, so that the next "make" recompiles the entire project + +**`make data-cleanup`** : clears out all simulation data + +**`make reset`** : de-populates the sample project and returns to the original PhysiCell state. Use this when switching to a new PhysiCell sample project. + +**`make jpeg`** : uses ImageMagick to convert the SVG files in the output directory to JPG (with appropriate sizing to make movies). Supply `OUTPUT=foldername` to select a different folder. + +**`make movie`** : uses ffmpeg to convert the JPG files in the output directory an mp4 movie. Supply `OUTPUT=foldername` to select a different folder, or `FRAMERATE=framerate` to override the frame rate. + +**`make upgrade`** : fetch the latest release of PhysiCell and overwrite the core library and sample projects. + +### Key Links +**Homepage:** http://PhysiCell.MathCancer.org + +**Downloads:** http://PhysiCell.sf.net + +**Support:** https://sourceforge.net/p/physicell/tickets/ + +**Quick Start:** Look at QuickStart.md in the documentation folder. + +**User Guide:** Look at UserGuide.pdf in the documentation folder. + +**Setup and Training:** See last year's workshop and hackathon at https://github.com/PhysiCell-Training/ws2021 + +**Older Tutorials:** http://www.mathcancer.org/blog/physicell-tutorials/ + +**Latest info:** follow [@PhysiCell](https://twitter.com/PhysiCell) on Twitter (http://twitter.com/PhysiCell) + +See changes.md for the full change log. + +* * * +## Release summary: +Version 1.11.0 adds several notable features, fixes bugs, and further expands the "signals" and "behaviors" that can be read and written with a simple API to facilitate building models. In particular, we add a brand new CSV format for initial cell positions (with more robust naming of cells by their human-readable names, a "header" line, and ability to extensively add and specificy individual cell properties), a new ability to save and load user projects in the `user_projects` directory, automated dynamic formation and breakage of spring-based cell-cell adhesions (based upon the cell-cell adhesion affinities, attachment rates, and detachment rates), automated inclusion of spring-based adhesions (at the mechanics time step) without need for the user to explicitly supply a spring function, a new "mechano" sample project to illustrate the new automated spring functionality, and updates to PhysiBoSS to ensure compatibility with the rapidly improving PhysiCell Studio. In addition, there is new capability of adding a background coloring (e.g., an oxygen heatmap) to SVG ouptuts--see the `interaction-sample` for an illustration (use the alternate XML config file to enable). This release includes several bugfixes, the most critical of which is to update the parameters for necrotic cells (which had previously been misset in the XML files, thus disabling necrotic cell lysis and shrinking). + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes in the 1.11.z versions +#### 1.11.0 ++ New and improved (v2) cell CSV format for cell import. This allows more intuitive statement of initial cell positions. The first line of your CSV file must be: + + ```x,y,z,cell type``` + + Every subsequent line is a single cell, now referencing cell types by their human-readable names (as defined in your XML configuration file) rather than requiring the integer `ID`. So, a sample second line to place a CD8 T cell at (30,-10,12) would be: + + ```30,-10,12,CD8 T cell``` + + Moreover, the new format allows you to initialize a variety of individual cell properties, including (total) `volume` and any supported cell beheavior. For example, if your cell definitions have custom variables `GFP` ond `oncoprotein`, then you can extend the first header line to: + + ```x,y,z,cell type,custom:GFP,custom:oncoprotein``` + + And then subsequent cells look like this: + + ```30,-10,12,CD8 T cell,0.5,3.2``` + + You can tell our parser to skip specifying a specific variable with `s` or `S` or an empty entry. Here, the first cell would skip writing the initial value of the GFP, and teh second would skip initializing the oncoprotein: + + ```30,-10,12,CD8 T cell,,3.2``` + ```50,13,-4,M0 Macrophage,0.5,s``` + + We will continue to automatically support older CSV cell files; any cells CSV file missing the first line of headers will be processed in the old format. + ++ Ability to save and load user projects + + Use `make save PROJ=project_name` to save your project to a folder in `./user_projects` named `project_name`. For example: + + ```make save PROJ=new_tumor_sample``` + + saves your project as `new_tumor_sample`. In particular, it saves your `Makefile`, `main.cpp`, everything in `./config`, and everything in `./custom_modules`. + + + Use `make load PROJ=project_name` to load your project from a folder in `./user_projects` named `project_name`. For example: + + ```make load PROJ=new_tumor_sample``` + + loads your project from `new_tumor_sample`. In particular, it loads your `Makefile`, `main.cpp`, everything in `./config`, and everything in `./custom_modules`. + ++ Extended `cell_interactions` to include a vector `immunogenicities`: for a cell, `immunogenicity[j]` is how immunogenic this cell is to the jth cell type. By default, these will all be set to 1. (See next point.) + ++ Updated the built-in "attack" model: + $$\textrm{Probability cell } i \textrm{ attacks cell } j \textrm{ in } [t,t+\Delta t] = \textrm{attack}\_{ij} \cdot \textrm{immunogenicity}\_{ji} \Delta t $$ + By setting $\textrm{immunogenicity}\_{ji} = 1$ as teh default value, we maintain compatibiltiy with prior models. This is a way to further modulate immunogenic and cytotoxic interactions. + ++ Began migrating built-in sample projects to be compatible with the model builder GUI and the upcoming PhysiCell Studio, including: + + template + + biorobots (updates spring constant from 0.05 to 0.5) + + heterogeneity + + cancer biorobots (updates spring constant from 0.05 to 0.5) + ++ Added new signals: + + `apoptotic` returns 1 if a cell is apoptotic, and 0 otherwise + + `necrotic` returns 1 if a cell is necrotic, and 0 otherwise + + As always, access these via `double get_single_signal(Cell* pCell,std::string sig_name)`. + ++ Added new behaviors: + + `immunogenicity to [cell type]` is the cell's immunogenicity to a specific cell type. The probability that cell `i` attacks cell `j` in $[t,t+\Delta t]$ is $\textrm{attack}\_{ij} \cdot \textrm{immunogenicity}\_{ji} \Delta t.$ + + `cell attachment rate` is the rate at which the cell forms spring links with other cells. + + `cell detachment rate` is the rate at which spring links break. + + `maximum number of cell attachments` is the maximum number of spring links. + + `is_movable` can be set to 0 (false) to make an agent rigid: it will exert forces on other cells, but it itself cannot be moved. This behavior right now is somewhat fragile if used dynmaically, but can reliably be used during tissue setup. + + As always, access these via `double get_single_behavior(Cell* pCell,std::string beh_name)` and `void set_single_behavior(Cell* pCell,std::string beh_name,double new_value)`. + ++ Added new standard model `void dynamic_attachments(Cell*, Phenotype& ,double);` This function can automate dynamic attachments and detachments. When calling this function for cell $i$: + + For each current attachment, it detaches with probability $\textrm{detachment rate}\_i \Delta t$ + + For each cell $j$ in the neighbors list, it forms an attachment with probability + + $$\textrm{Prob attach } i \textrm{ to cell } j = \textrm{adhesion affinity}\_j \cdot \textrm{attachment rate}\_i \cdot \Delta t.$$ + + The attachment is only formed if both cell $i$ and $j$ have not exceeded their maximum number of + attachments. + ++ Added a new `spring_attachments` (of type `std::vector`) to cell `state` to track automated formation and removal of spring-link adhesions separately of the user-focused `attached` data struture. This will allow users to continue managing the `attachments` structure on their own for custom contact functions, without interference from automated springs (see more below). + ++ Added new standard model `void dynamic_spring_attachments(Cell*, Phenotype& ,double);` This functions exactly as the `dynamic_attachments` function, except it stores attached cells to `cell.state.spring_attachments` to avoid interfering with the user-managed `cell.state.attachments` data struture. + ++ **Automated spring attachments / detachments:** the new `dynamic_spring_attachments` function is automatically called at every mechancis time step, with cell-cell spring attachment and detachment based on the cells' current rates. Each cell evaluates spring-like elastic adhesion betwen itslef and cells in `cell.state.spring_attachments` to add to its own velocity. Some notes: + + Each cell automatically removes all its spring attachments during division + + Each cell automatically removes all its spring attachments at the *end* of death. If you want dead cells to have increased detachment, add a rule accordingly using the built-in behavior dictionary. + + If a cell is not movable (`is_movable = false`), then it is not moved by springs, but it can exert spring forces on other cells, allowing it to act as an "anchor". + + This automated spring functionality is completely independent of (and does not interfere with) the user-defined contact function and user-manageed `cell.state.attached` data structure. + + **WARNING:** If in a past life you set `phenotype.mechanics.attachment_rate` to a nonzero rate, you may find yourself surprised with unintended spring adhesions as this new automation kicks in. Please review and revise your configuration file as necessary. + + You can disable this behavior in the XML configuration file: + ``` + + + true + + ++ Added a new `mechano-sample` project that shows automated dynamic attachment and detachment of cells: + + Constant cancer cell birth and death + + Basic mechano feedback: high-pressure sets cancer cell birth to zero + + Cancer cell phenotype sets high detachment rate upon death. + + Automated connection of cancer, basement membrane (BM) agents with spring links using the built-ins noted above. No user intervention or code required beyond setting nonzero rates. + + Cancer cells manually set to apoptose at 10000 min. + ++ Updated PhysiBoSS to remove cell definition "inheritance," (with "flat", self-standing cell definitions), to make it compatible with PhysiCell Studio. Hereafter, all properties of each cell definition must be explicitely defined. + +### Minor new features and changes: +#### 1.11.0 ++ Updated the `paint_by_number_cell_coloring` coloring function to paint the entire cell white if apoptotic, and brown if necrotic. (Previously, we colored the nucleus based on live/dead status.) This improves compatibility with the model GUI. + ++ Changed the default value of `attachment_rate` from 10 to 0 (in the `Mechanics` class) to avoid unexpected triggering of automated spring adheions. + ++ Added a safety check to `operator[]` for Parameters, based on [PR145](https://github.com/MathCancer/PhysiCell/pull/145/). Thanks, Vincent Noel!! + ++ In PhysiBoSS, introduced a new state inheritance mechanism (global, and node-specific). + ++ PhisBoSS has a new optional start time, to initiate the intracellular model at t > 0. + ++ Updated PhysiBoSS Cell Lines sample project (flatten XML, initial positions as CSV). + +### Beta features (not fully supported): +#### 1.11.0 ++ Added `bool read_microenvironment_from_matlab( std::string mat_filename )` to `BioFVM_MultiCellDS`. This will read and overwrite from a stored microenvironment (in `mat_filename`, saved as a level 4 Matlab file) if it has the following format: + + Number of columns = number of voxels (must match the size as configured in the `PhysiCell_settings.xml` file) + + Number of rows = 3 + 1 + number of diffusing substrates (must match the size and ordering as configured in the `PhysiCell_settings.xml` file) + + Row 0: x coordinate of each voxel + + Row 1: y coordinate of each voxel + + Row 2: z coordinate of each voxel + + Row 3: volume of each voxel + + Rows j to end: value of (j-4)th substrate in each voxel + + Column ordering: + * For each z from low to high: + * For each y from low to high: + * for each x from low to high: + store voxel X[i] , Y[j], Z[k]. + + **Note:** This matches how PhysiCell saves the microenvironment. This will read any PhysiCell-saved microenvironment, so long as its sizes matches your current settings. + + **Note:** This may be fragile. It has only minimal error-checking. + + + Set default cell attachment rate to 0 in the template project and most sample projects to avoid unexpectedly triggering the new autmoated spring adhesions; users must affirmatively set a nonzero attachment rate to trigger this new automation in an individual cell. + + + In repsonse to [PR 123](https://github.com/MathCancer/PhysiCell/pull/123), `parameters.TYPE.find_index(search_name)` now returns -1 if the searched term isn't found. Thanks, Daniel Bergman! + +### Bugfixes: + +#### 1.11.0 ++ Fixed bug in cancer biorobots project that mistakenly set max cancer cell proliferation rate to 0.000072 instead of 0.00072 + ++ Fixed multiple broken signals/behaviors. + ++ Fixed calcification bug reported in issue [133](https://github.com/MathCancer/PhysiCell/issues/133). Thank you, @JulianoGianlupi! + ++ Fixed typo in cell signals that used `contact with dead dell` instead of `contact with dead cell` + ++ Changed default full data output to 60 minutes (to match the SVG output interval) for better compatibility with the model builder GUI. + ++ Fixed incorrect parameters for necrotic cell volume changes that prevented necrotic cell lysis and shrinkage. + ++ Merged Daniel Bergman's [PR 126](https://github.com/MathCancer/PhysiCell/pull/126), which fixes cell legend colors. Thank's Daniel! + ++ Improved safety checks in the cell orientation function, thanks to Randy Heiland's [PR 122](https://github.com/MathCancer/PhysiCell/pull/122). Thanks, Randy! + ++ Now forcing Mersenne Twister as random generator in PhysiBoSS (use or /dev/random by MaBoSS would max out system descriptor) + ++ MaBoSS BND/CFG parsing is now in an OpenMP critical block (flex/bison parser is not thread safe) + ++ Remove duplicate initialization of maximum attachment rate from the Phenotype.Mechanics constructor. + ++ Fixed bug in neighbor/attached graph output filenames (previously double-appended a suffix to the filenames). + +### Notices for intended changes that may affect backwards compatibility: ++ We intend to deprecate the unused phenotype variables `relative_maximum_attachment_distance`, `relative_detachment_distance`, and `maximum_attachment_rate` from `phenotype.mechanics.` + ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the future. + ++ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. + ++ Additional search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems + +**Version:** 1.10.4 + +**Release date:** 18 July 2022 + +## Overview: +PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. + +**Reference:** A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: [10.1371/journal.pcbi.1005991](https://dx.doi.org/10.1371/journal.pcbi.1005991) + +Visit http://MathCancer.org/blog for the latest tutorials and help. + +**Notable recognition:** ++ [2019 PLoS Computational Biology Research Prize for Public Impact](https://blogs.plos.org/biologue/2019/05/31/announcing-the-winners-of-the-2019-plos-computational-biology-research-prize/) + +### Key makefile rules: + +**`make`** : compiles the current project. If no + project has been defined, it first + populates the cancer heterogeneity 2D + sample project and compiles it + +**`make project-name`**: populates the indicated sample project. + Use "make" to compile it. + + * **`project-name`** choices: + * template + * biorobots-sample + * cancer-biorobots-sample + * cancer-immune-sample + * celltypes3-sample + * heterogeneity-sample + * pred-prey-farmer + * virus-macrophage-sample + * worm-sample + * ode-energy-sample + * physiboss-cell-lines-sample + * cancer-metabolism-sample + * interaction-sample + +**`make list-projects`** : list all available sample projects + +**`make clean`** : removes all .o files and the executable, so that the next "make" recompiles the entire project + +**`make data-cleanup`** : clears out all simulation data + +**`make reset`** : de-populates the sample project and returns to the original PhysiCell state. Use this when switching to a new PhysiCell sample project. + +**`make jpeg`** : uses ImageMagick to convert the SVG files in the output directory to JPG (with appropriate sizing to make movies). Supply `OUTPUT=foldername` to select a different folder. + +**`make movie`** : uses ffmpeg to convert the JPG files in the output directory an mp4 movie. Supply `OUTPUT=foldername` to select a different folder, or `FRAMERATE=framerate` to override the frame rate. + +**`make upgrade`** : fetch the latest release of PhysiCell and overwrite the core library and sample projects. + +### Key Links +**Homepage:** http://PhysiCell.MathCancer.org + +**Downloads:** http://PhysiCell.sf.net + +**Support:** https://sourceforge.net/p/physicell/tickets/ + +**Quick Start:** Look at QuickStart.md in the documentation folder. + +**User Guide:** Look at UserGuide.pdf in the documentation folder. + +**Setup and Training:** See last year's workshop and hackathon at https://github.com/PhysiCell-Training/ws2021 + +**Older Tutorials:** http://www.mathcancer.org/blog/physicell-tutorials/ + +**Latest info:** follow [@PhysiCell](https://twitter.com/PhysiCell) on Twitter (http://twitter.com/PhysiCell) + +See changes.md for the full change log. + +* * * +## Release summary: +Version 1.10.4 primarily fixes bugs in file output and the ode-energy sample, and refines thread safety in cell phagocytosis. + +The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. + +A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. +A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes in the 1.10.z versions +#### 1.10.4 ++ None in this version. See 1.10.0 +#### 1.10.3 ++ None in this version. See 1.10.0 +#### 1.10.2 ++ None in this version. See 1.10.0 +#### 1.10.1 ++ None in this version. See 1.10.0 +#### 1.10.0 ++ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. + + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. + + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. + + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. + + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. + + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. + + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. + + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. + ++ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. + + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). + + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` + ++ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. + + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. + + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. + + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + ++ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: + + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). + + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + ++ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of signals include: + + extracellular and intracellular substrate concentrations + + substrate gradients + + contact with dead cells + + contact with cells (of type X) + + damage + + pressure + + Use `display_signal_dictionary()` to quickly display a list of available signals. + + Substantial functionality to query signals + + `int find_signal_index( std::string signal_name )` : get the index of the named signal + + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals + + `std::string signal_name( int i );` display the name of the signal with the given index + + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell + + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell + + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices + + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals + + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index + + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name + ++ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of behaviors include: + + secretion, secretion target, uptake, and export rates + + cycle progression + + death rates + + motility parameters + + chemotactic parameters + + cell-cell adhesion and repulsion parameters + + cell adhesion affinities + + cell-BM adhesion and repulsion parameters + + phagocytosis rates + + attack rates + + fusion rates + + transformation rates + + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. + + Substantial functionality to query and set behaviors + + `int find_behavior_index( std::string response_name )` : get the index of the named behavior + + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. + + `std::string behavior_name( int i );` get the name of the behavior with the given index + + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors + + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype + + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype + + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype + + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype + + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype + + Substantial functionality to query the cell's current behavior + + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors + + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) + + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) + + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) + + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) + + Substantial functionality to query the cell's referece behaviors (from its cell definition) + + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors + + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) + + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) + + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) + + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) + ++ Created a new `interaction-sample` project to illustrate the new interactions and transformations: + + Blood vessels release resource + + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) + + Stem cells divide and differentiate into differentiated cells + + Differentiated cells divide until experiencing elevated pressure (to detect confluence) + + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. + + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria + + Macrophages phagocytose dead cells + + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria + + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria + + Accumulated damage kills bacteria. + + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. + +### Minor new features and changes: +#### 1.10.4 ++ None in this version. +#### 1.10.3 ++ Added `attachment_rate` and `detachment_rate` to `phenotype.mechanics` for use in a future standard attachment and detachment model. ++ Modernized output format: + + More complete cell data saved for each cell agent. + + Merged the previously separate cell matlab files for each time save + + Added more metadata to outputs ++ `Variables` and `Vector_Variables` in `Custom_Cell_Data` now have a new Boolean attribute `conserved_quantity` (defaulted to false). If this value is set to true, then the custom variable is divided evenly between daughter cells at division. ++ Custom cell data can now be designated as conserved by settings an attribute `conserved="true"` in the XMO configuration file. ++ Improved support for Apple M1 and M2 chips. ++ Refinements to PhysiBoSS. + +#### 1.10.2 ++ Added `operator<<` for vectors of ints and vectors of strings. So that `std::cout << v << std::endl;` will work if `v` is `std::vector` of `std::vector`. It was truly annoying that these were missing, so sorry! ++ Added `dead` to the signals dictionaries, which returns 0.0 or 1.0 based on `phenotype.death.dead`. ++ Added `time` to the signals dictionaries, which returns the current simulation time based on `PhysiCell_Globals.current_time`. ++ Added a brief protocol on how to add new signals and behaviors to the dictionaries in the `/protocols` directory. ++ Added new functions `double& apoptosis_rate()` and `double& necrosis_rate()` to easily read and write these rates. Access via `cell.phenotype.death.apoptosis_rate()` and `cell.phenotype.death.necrosis_rate()`. ++ Added new ease of access functions for secretion: + + `double& Secretion::secretion_rate( std::string name )` allows you to easily read/write the secretion rate of a substrate by name. For example: + ```pCell->phenotype.secretion.secretion_rate("oxygen") = 0.1``` + + `double& Secretion::uptake_rate( std::string name )` allows you to easily read/write the uptake rate of a substrate by name. For example: + ```pCell->phenotype.secretion.uptake_rate("oxygen") = 0.1``` + + `double& Secretion::saturation_density( std::string name )` allows you to easily read/write the secretion target of a substrate by name. For example: + ```pCell->phenotype.secretion.saturation_density("oxygen") = 38``` + + `double& Secretion::net_export_rate( std::string name )` allows you to easily read/write the net export rate of a substrate by name. For example: + ```pCell->phenotype.secretion.net_export_rate("oxygen") = -100``` + ++ Added new ease of access function for internalized substrates: + + `double& Molecular::internalized_total_substrate( std::string name )` allows you to easily read/write the total amount of internalized substrate by name. For example: + ```pCell->phenotype.molecular.internalized_total_substrate( "oxygen" ) = 0.01`` +#### 1.10.1 ++ None in this version. See 1.10.0. +#### 1.10.0 ++ All sample projects have a new rule "make name" to tell you the name of the executable. + ++ All sample projects output the executable name to screen for easier reference. + ++ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. + ++ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. + +### Beta features (not fully supported): +#### 1.10.4 ++ None in this version. +#### 1.10.3 ++ Each time outputs two cell interaction graphs (as text files): + + neighbor graph records which cells are within interaction distance for each cell agent, with format; + ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of interacting cells) + + attached cell graph records which cells are attached for each cell agent, with format; + ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of attached cells) + + We might split these into 3 files: + + an ID list that has the ID of each cell in order of appearence. + + neighbor list omits the preceding "ID:" since now each row corresponds to the index in the ID list + + attached cell list omits the preceding "ID:" since now each row corresponds to the index in the ID list + + Began experimenting with a planned `integrity` subclass to `phenotype` that will record multiple types of cell damage and associated damage and repair rates. It is not yet clear if we wil provide built-in support for damaged-driven apoptotic death and cycle arrest, as these are generally better left to modeler-driven hypotheses. + +None in this version. See 1.10.0. +#### 1.10.2 ++ None in this version. See 1.10.0. +#### 1.10.1 + + None in this version. See 1.10.0. + #### 1.10.0 ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) + ++ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) + ++ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + ++ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) + +### Bugfixes: +#### 1.10.4 ++ Fixed vectorized outputs in MultiCellDS that incorrectly assumed linear data ordering in std::vector. Thank you Randy Heiland! ++ Fixed errors in the ode-energy-sample project. Thank you Randy Heiland, Furkan Kurtoglu, and John Metzcar! ++ Improved thread safety in phagocytosis. Thank you Michael Getz! + +#### 1.10.3 ++ Fixed bug in `get_single_behavior` and `get_single_base_behavior` where querying any cycle exit rate or cycle entry mistakenly returned -1. ++ Corrected declaration of `standard_add_basement_membrane_interactions` in `PhysiCell_standard_models.h` to properly use phenotype by reference. Thank you Inês Gonçalves! ++ Removed the OpenMP pragma in `void Microenvironment::apply_dirichlet_conditions( void )` (around line 272) that tends to perform more poorly than serial code. + +#### 1.10.2 ++ Fixed error in `double get_single_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. + ++ Fixed error in `double get_single_base_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. + ++ Fixed bug in `add_PhysiCell_cells_to_open_xml_pugi()` that mistakenly used the wrong size (number of cell species rather than number of substrate species) when writing the chemotactic sensitivities. + ++ The cell `neighbors` list did not add non-adhesive cells within interaction distance. This is now fixed. + +#### 1.10.1 ++ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. + ++ Missing PhysiBoSS makefiles have been replaced. + ++ Fixed broken makefile for worms sample project. + +#### 1.10.0 ++ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. + ++ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. + ++ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. + ++ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! + +### Notices for intended changes that may affect backwards compatibility: ++ We intend to deprecate the unused phenotype variables `relative_maximum_attachment_distance`, `relative_detachment_distance`, and `maximum_attachment_rate` from `phenotype.mechanics.` + ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. + ++ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + + +**Version:** 1.10.3 + +**Release date:** 25 June 2022 + +## Overview: +PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. + +**Reference:** A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: [10.1371/journal.pcbi.1005991](https://dx.doi.org/10.1371/journal.pcbi.1005991) + +Visit http://MathCancer.org/blog for the latest tutorials and help. + +**Notable recognition:** ++ [2019 PLoS Computational Biology Research Prize for Public Impact](https://blogs.plos.org/biologue/2019/05/31/announcing-the-winners-of-the-2019-plos-computational-biology-research-prize/) + +### Key makefile rules: + +**`make`** : compiles the current project. If no + project has been defined, it first + populates the cancer heterogeneity 2D + sample project and compiles it + +**`make project-name`**: populates the indicated sample project. + Use "make" to compile it. + + * **`project-name`** choices: + * template + * biorobots-sample + * cancer-biorobots-sample + * cancer-immune-sample + * celltypes3-sample + * heterogeneity-sample + * pred-prey-farmer + * virus-macrophage-sample + * worm-sample + * ode-energy-sample + * physiboss-cell-lines-sample + * cancer-metabolism-sample + * interaction-sample + +**`make list-projects`** : list all available sample projects + +**`make clean`** : removes all .o files and the executable, so that the next "make" recompiles the entire project + +**`make data-cleanup`** : clears out all simulation data + +**`make reset`** : de-populates the sample project and returns to the original PhysiCell state. Use this when switching to a new PhysiCell sample project. + +**`make jpeg`** : uses ImageMagick to convert the SVG files in the output directory to JPG (with appropriate sizing to make movies). Supply `OUTPUT=foldername` to select a different folder. + +**`make movie`** : uses ffmpeg to convert the JPG files in the output directory an mp4 movie. Supply `OUTPUT=foldername` to select a different folder, or `FRAMERATE=framerate` to override the frame rate. + +**`make upgrade`** : fetch the latest release of PhysiCell and overwrite the core library and sample projects. + +### Key Links +**Homepage:** http://PhysiCell.MathCancer.org + +**Downloads:** http://PhysiCell.sf.net + +**Support:** https://sourceforge.net/p/physicell/tickets/ + +**Quick Start:** Look at QuickStart.md in the documentation folder. + +**User Guide:** Look at UserGuide.pdf in the documentation folder. + +**Setup and Training:** See last year's workshop and hackathon at https://github.com/PhysiCell-Training/ws2021 + +**Older Tutorials:** http://www.mathcancer.org/blog/physicell-tutorials/ + +**Latest info:** follow [@PhysiCell](https://twitter.com/PhysiCell) on Twitter (http://twitter.com/PhysiCell) + +See changes.md for the full change log. + +* * * +## Release summary: +Version 1.10.3 primarily fixes bugs and further refines the signal and behavior dictionaries, particularly with access to custom variables. It also allows users to designate custom variables as _conserved quantities_ that are divided evenly among daughter cells as division (e.g., melanosomes). Lastly, this release continues updates to PhysiBoSS and libRoadrunner to leverage newer core features and improve compatibiltiy, while also improving support for newer Mac (M1 and M2) architectures. + +The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. + +A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. +A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes in the 1.10.z versions +#### 1.10.3 ++ None in this version. See 1.10.0 +#### 1.10.2 ++ None in this version. See 1.10.0 +#### 1.10.1 ++ None in this version. See 1.10.0 +#### 1.10.0 ++ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. + + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. + + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. + + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. + + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. + + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. + + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. + + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. + ++ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. + + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). + + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` + ++ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. + + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. + + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. + + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + ++ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: + + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). + + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + ++ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of signals include: + + extracellular and intracellular substrate concentrations + + substrate gradients + + contact with dead cells + + contact with cells (of type X) + + damage + + pressure + + Use `display_signal_dictionary()` to quickly display a list of available signals. + + Substantial functionality to query signals + + `int find_signal_index( std::string signal_name )` : get the index of the named signal + + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals + + `std::string signal_name( int i );` display the name of the signal with the given index + + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell + + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell + + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices + + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals + + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index + + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name + ++ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of behaviors include: + + secretion, secretion target, uptake, and export rates + + cycle progression + + death rates + + motility parameters + + chemotactic parameters + + cell-cell adhesion and repulsion parameters + + cell adhesion affinities + + cell-BM adhesion and repulsion parameters + + phagocytosis rates + + attack rates + + fusion rates + + transformation rates + + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. + + Substantial functionality to query and set behaviors + + `int find_behavior_index( std::string response_name )` : get the index of the named behavior + + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. + + `std::string behavior_name( int i );` get the name of the behavior with the given index + + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors + + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype + + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype + + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype + + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype + + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype + + Substantial functionality to query the cell's current behavior + + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors + + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) + + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) + + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) + + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) + + Substantial functionality to query the cell's referece behaviors (from its cell definition) + + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors + + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) + + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) + + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) + + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) + ++ Created a new `interaction-sample` project to illustrate the new interactions and transformations: + + Blood vessels release resource + + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) + + Stem cells divide and differentiate into differentiated cells + + Differentiated cells divide until experiencing elevated pressure (to detect confluence) + + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. + + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria + + Macrophages phagocytose dead cells + + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria + + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria + + Accumulated damage kills bacteria. + + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. + +### Minor new features and changes: +#### 1.10.3 ++ Added `attachment_rate` and `detachment_rate` to `phenotype.mechanics` for use in a future standard attachment and detachment model. ++ Modernized output format: + + More complete cell data saved for each cell agent. + + Merged the previously separate cell matlab files for each time save + + Added more metadata to outputs ++ `Variables` and `Vector_Variables` in `Custom_Cell_Data` now have a new Boolean attribute `conserved_quantity` (defaulted to false). If this value is set to true, then the custom variable is divided evenly between daughter cells at division. ++ Custom cell data can now be designated as conserved by settings an attribute `conserved="true"` in the XMO configuration file. ++ Improved support for Apple M1 and M2 chips. ++ Refinements to PhysiBoSS. + +#### 1.10.2 ++ Added `operator<<` for vectors of ints and vectors of strings. So that `std::cout << v << std::endl;` will work if `v` is `std::vector` of `std::vector`. It was truly annoying that these were missing, so sorry! ++ Added `dead` to the signals dictionaries, which returns 0.0 or 1.0 based on `phenotype.death.dead`. ++ Added `time` to the signals dictionaries, which returns the current simulation time based on `PhysiCell_Globals.current_time`. ++ Added a brief protocol on how to add new signals and behaviors to the dictionaries in the `/protocols` directory. ++ Added new functions `double& apoptosis_rate()` and `double& necrosis_rate()` to easily read and write these rates. Access via `cell.phenotype.death.apoptosis_rate()` and `cell.phenotype.death.necrosis_rate()`. ++ Added new ease of access functions for secretion: + + `double& Secretion::secretion_rate( std::string name )` allows you to easily read/write the secretion rate of a substrate by name. For example: + ```pCell->phenotype.secretion.secretion_rate("oxygen") = 0.1``` + + `double& Secretion::uptake_rate( std::string name )` allows you to easily read/write the uptake rate of a substrate by name. For example: + ```pCell->phenotype.secretion.uptake_rate("oxygen") = 0.1``` + + `double& Secretion::saturation_density( std::string name )` allows you to easily read/write the secretion target of a substrate by name. For example: + ```pCell->phenotype.secretion.saturation_density("oxygen") = 38``` + + `double& Secretion::net_export_rate( std::string name )` allows you to easily read/write the net export rate of a substrate by name. For example: + ```pCell->phenotype.secretion.net_export_rate("oxygen") = -100``` + ++ Added new ease of access function for internalized substrates: + + `double& Molecular::internalized_total_substrate( std::string name )` allows you to easily read/write the total amount of internalized substrate by name. For example: + ```pCell->phenotype.molecular.internalized_total_substrate( "oxygen" ) = 0.01`` +#### 1.10.1 ++ None in this version. See 1.10.0. +#### 1.10.0 ++ All sample projects have a new rule "make name" to tell you the name of the executable. + ++ All sample projects output the executable name to screen for easier reference. + ++ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. + ++ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. + +### Beta features (not fully supported): +#### 1.10.3 ++ Each time outputs two cell interaction graphs (as text files): + + neighbor graph records which cells are within interaction distance for each cell agent, with format; + ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of interacting cells) + + attached cell graph records which cells are attached for each cell agent, with format; + ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of attached cells) + + We might split these into 3 files: + + an ID list that has the ID of each cell in order of appearence. + + neighbor list omits the preceding "ID:" since now each row corresponds to the index in the ID list + + attached cell list omits the preceding "ID:" since now each row corresponds to the index in the ID list + + Began experimenting with a planned `integrity` subclass to `phenotype` that will record multiple types of cell damage and associated damage and repair rates. It is not yet clear if we wil provide built-in support for damaged-driven apoptotic death and cycle arrest, as these are generally better left to modeler-driven hypotheses. + +None in this version. See 1.10.0. +#### 1.10.2 ++ None in this version. See 1.10.0. +#### 1.10.1 + + None in this version. See 1.10.0. + #### 1.10.0 ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) + ++ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) + ++ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + ++ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) + +### Bugfixes: +#### 1.10.3 ++ Fixed bug in `get_single_behavior` and `get_single_base_behavior` where querying any cycle exit rate or cycle entry mistakenly returned -1. ++ Corrected declaration of `standard_add_basement_membrane_interactions` in `PhysiCell_standard_models.h` to properly use phenotype by reference. Thank you Inês Gonçalves! ++ Removed the OpenMP pragma in `void Microenvironment::apply_dirichlet_conditions( void )` (around line 272) that tends to perform more poorly than serial code. + +#### 1.10.2 ++ Fixed error in `double get_single_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. + ++ Fixed error in `double get_single_base_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. + ++ Fixed bug in `add_PhysiCell_cells_to_open_xml_pugi()` that mistakenly used the wrong size (number of cell species rather than number of substrate species) when writing the chemotactic sensitivities. + ++ The cell `neighbors` list did not add non-adhesive cells within interaction distance. This is now fixed. + +#### 1.10.1 ++ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. + ++ Missing PhysiBoSS makefiles have been replaced. + ++ Fixed broken makefile for worms sample project. + +#### 1.10.0 ++ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. + ++ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. + ++ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. + ++ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! + +### Notices for intended changes that may affect backwards compatibility: ++ We intend to deprecate the unused phenotype variables `relative_maximum_attachment_distance`, `relative_detachment_distance`, and `maximum_attachment_rate` from `phenotype.mechanics.` + ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. + ++ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems + +**Version:** 1.10.2 + +**Release date:** 24 May 2022 + +## Overview: +PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. + +**Reference:** A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: [10.1371/journal.pcbi.1005991](https://dx.doi.org/10.1371/journal.pcbi.1005991) + +Visit http://MathCancer.org/blog for the latest tutorials and help. + +**Notable recognition:** ++ [2019 PLoS Computational Biology Research Prize for Public Impact](https://blogs.plos.org/biologue/2019/05/31/announcing-the-winners-of-the-2019-plos-computational-biology-research-prize/) + +### Key makefile rules: + +**`make`** : compiles the current project. If no + project has been defined, it first + populates the cancer heterogeneity 2D + sample project and compiles it + +**`make project-name`**: populates the indicated sample project. + Use "make" to compile it. + + * **`project-name`** choices: + * template + * biorobots-sample + * cancer-biorobots-sample + * cancer-immune-sample + * celltypes3-sample + * heterogeneity-sample + * pred-prey-farmer + * virus-macrophage-sample + * worm-sample + * ode-energy-sample + * physiboss-cell-lines-sample + * cancer-metabolism-sample + * interaction-sample + +**`make list-projects`** : list all available sample projects + +**`make clean`** : removes all .o files and the executable, so that the next "make" recompiles the entire project + +**make data-cleanup** : clears out all simulation data + +**make reset** : de-populates the sample project and returns to the original PhysiCell state. Use this when switching to a new PhysiCell sample project. + +**make jpeg** : uses ImageMagick to convert the SVG files in the output directory to JPG (with appropriate sizing to make movies). Supply `OUTPUT=foldername` to select a different folder. + +**make movie** : uses ffmpeg to convert the JPG files in the output directory an mp4 movie. Supply `OUTPUT=foldername` to select a different folder, or `FRAMERATE=framerate` to override the frame rate. + +**make upgrade** : fetch the latest release of PhysiCell and overwrite the core library and sample projects. + +**Homepage:** http://PhysiCell.MathCancer.org + +**Downloads:** http://PhysiCell.sf.net + +**Support:** https://sourceforge.net/p/physicell/tickets/ + +**Quick Start:** Look at QuickStart.md in the documentation folder. + +**User Guide:** Look at UserGuide.pdf in the documentation folder. + +**Tutorials:** http://www.mathcancer.org/blog/physicell-tutorials/ + +**Latest info:** follow [@PhysiCell](https://twitter.com/PhysiCell) on Twitter (http://twitter.com/PhysiCell) + +See changes.md for the full change log. + +* * * +## Release summary: +Version 1.10.2 introduces bugfixes to the behavior "dictionary" functiouns, data saves, and updating neighbor lists for nearby non-adhesive cells. It also introduces a number of ease-of-access functions to the phenotype for death rates, secretion, and internalized substrates. + +The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. + +A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. + +A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes in the 1.10.z versions +#### 1.10.2 ++ None in this version. See 1.10.0 +#### 1.10.1 ++ None in this version. See 1.10.0 +#### 1.10.0 ++ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. + + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. + + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. + + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. + + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. + + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. + + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. + + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. + ++ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. + + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). + + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` + ++ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. + + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. + + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. + + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + ++ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: + + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). + + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + ++ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of signals include: + + extracellular and intracellular substrate concentrations + + substrate gradients + + contact with dead cells + + contact with cells (of type X) + + damage + + pressure + + Use `display_signal_dictionary()` to quickly display a list of available signals. + + Substantial functionality to query signals + + `int find_signal_index( std::string signal_name )` : get the index of the named signal + + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals + + `std::string signal_name( int i );` display the name of the signal with the given index + + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell + + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell + + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices + + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals + + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index + + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name + ++ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of behaviors include: + + secretion, secretion target, uptake, and export rates + + cycle progression + + death rates + + motility parameters + + chemotactic parameters + + cell-cell adhesion and repulsion parameters + + cell adhesion affinities + + cell-BM adhesion and repulsion parameters + + phagocytosis rates + + attack rates + + fusion rates + + transformation rates + + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. + + Substantial functionality to query and set behaviors + + `int find_behavior_index( std::string response_name )` : get the index of the named behavior + + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. + + `std::string behavior_name( int i );` get the name of the behavior with the given index + + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors + + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype + + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype + + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype + + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype + + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype + + Substantial functionality to query the cell's current behavior + + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors + + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) + + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) + + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) + + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) + + Substantial functionality to query the cell's referece behaviors (from its cell definition) + + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors + + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) + + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) + + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) + + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) + ++ Created a new `interaction-sample` project to illustrate the new interactions and transformations: + + Blood vessels release resource + + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) + + Stem cells divide and differentiate into differentiated cells + + Differentiated cells divide until experiencing elevated pressure (to detect confluence) + + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. + + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria + + Macrophages phagocytose dead cells + + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria + + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria + + Accumulated damage kills bacteria. + + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. + +### Minor new features and changes: +#### 1.10.2 ++ Added `operator<<` for vectors of ints and vectors of strings. So that `std::cout << v << std::endl;` will work if `v` is `std::vector` of `std::vector`. It was truly annoying that these were missing, so sorry! ++ Added `dead` to the signals dictionaries, which returns 0.0 or 1.0 based on `phenotype.death.dead`. ++ Added `time` to the signals dictionaries, which returns the current simulation time based on `PhysiCell_Globals.current_time`. ++ Added a brief protocol on how to add new signals and behaviors to the dictionaries in the `/protocols` directory. ++ Added new functions `double& apoptosis_rate()` and `double& necrosis_rate()` to easily read and write these rates. Access via `cell.phenotype.death.apoptosis_rate()` and `cell.phenotype.death.necrosis_rate()`. ++ Added new ease of access functions for secretion: + + `double& Secretion::secretion_rate( std::string name )` allows you to easily read/write the secretion rate of a substrate by name. For example: + ```pCell->phenotype.secretion.secretion_rate("oxygen") = 0.1``` + + `double& Secretion::uptake_rate( std::string name )` allows you to easily read/write the uptake rate of a substrate by name. For example: + ```pCell->phenotype.secretion.uptake_rate("oxygen") = 0.1``` + + `double& Secretion::saturation_density( std::string name )` allows you to easily read/write the secretion target of a substrate by name. For example: + ```pCell->phenotype.secretion.saturation_density("oxygen") = 38``` + + `double& Secretion::net_export_rate( std::string name )` allows you to easily read/write the net export rate of a substrate by name. For example: + ```pCell->phenotype.secretion.net_export_rate("oxygen") = -100``` + ++ Added new ease of access function for internalized substrates: + + `double& Molecular::internalized_total_substrate( std::string name )` allows you to easily read/write the total amount of internalized substrate by name. For example: + ```pCell->phenotype.molecular.internalized_total_substrate( "oxygen" ) = 0.01`` + +#### 1.10.1 ++ None in this version. See 1.10.0. +#### 1.10.0 ++ All sample projects have a new rule "make name" to tell you the name of the executable. + ++ All sample projects output the executable name to screen for easier reference. + ++ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. + ++ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. + +### Beta features (not fully supported): +#### 1.10.2 ++ None in this version. See 1.10.0. +#### 1.10.1 + + None in this version. See 1.10.0. + #### 1.10.0 ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) + ++ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) + ++ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + ++ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) + +### Bugfixes: +#### 1.10.2 ++ Fixed error in `double get_single_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. + ++ Fixed error in `double get_single_base_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. + ++ Fixed bug in `add_PhysiCell_cells_to_open_xml_pugi()` that mistakenly used the wrong size (number of cell species rather than number of substrate species) when writing the chemotactic sensitivities. + ++ The cell `neighbors` list did not add non-adhesive cells within interaction distance. This is now fixed. + +#### 1.10.1 ++ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. + ++ Missing PhysiBoSS makefiles have been replaced. + ++ Fixed broken makefile for worms sample project. + +#### 1.10.0 ++ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. + ++ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. + ++ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. + ++ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. + ++ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * +**Version:** 1.10.1 + +**Release date:** 15 May 2022 + +## Release summary: + +Version 1.10.1 introduces bugfixes to increase XML parser robustness and to fix missing PhysiBoSS makefiles. + +The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. + +A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. + +A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes in the 1.10.z versions +#### 1.10.1 ++ None in this version. See 1.10.0 +#### 1.10.0 ++ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. + + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. + + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. + + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. + + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. + + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. + + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. + + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. + ++ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. + + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). + + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` + ++ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. + + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. + + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. + + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + ++ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: + + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). + + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + ++ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of signals include: + + extracellular and intracellular substrate concentrations + + substrate gradients + + contact with dead cells + + contact with cells (of type X) + + damage + + pressure + + Use `display_signal_dictionary()` to quickly display a list of available signals. + + Substantial functionality to query signals + + `int find_signal_index( std::string signal_name )` : get the index of the named signal + + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals + + `std::string signal_name( int i );` display the name of the signal with the given index + + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell + + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell + + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices + + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals + + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index + + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name + ++ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of behaviors include: + + secretion, secretion target, uptake, and export rates + + cycle progression + + death rates + + motility parameters + + chemotactic parameters + + cell-cell adhesion and repulsion parameters + + cell adhesion affinities + + cell-BM adhesion and repulsion parameters + + phagocytosis rates + + attack rates + + fusion rates + + transformation rates + + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. + + Substantial functionality to query and set behaviors + + `int find_behavior_index( std::string response_name )` : get the index of the named behavior + + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. + + `std::string behavior_name( int i );` get the name of the behavior with the given index + + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors + + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype + + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype + + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype + + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype + + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype + + Substantial functionality to query the cell's current behavior + + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors + + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) + + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) + + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) + + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) + + Substantial functionality to query the cell's referece behaviors (from its cell definition) + + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors + + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) + + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) + + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) + + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) + ++ Created a new `interaction-sample` project to illustrate the new interactions and transformations: + + Blood vessels release resource + + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) + + Stem cells divide and differentiate into differentiated cells + + Differentiated cells divide until experiencing elevated pressure (to detect confluence) + + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. + + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria + + Macrophages phagocytose dead cells + + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria + + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria + + Accumulated damage kills bacteria. + + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. + +### Minor new features and changes: +#### 1.10.1 ++ None in this version. See 1.10.0. +#### 1.10.0 ++ All sample projects have a new rule "make name" to tell you the name of the executable. + ++ All sample projects output the executable name to screen for easier reference. + ++ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. + ++ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. + +### Beta features (not fully supported): + #### 1.10.1 + + None in this version. See 1.10.0. + #### 1.10.0 ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) + ++ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) + ++ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + ++ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) + +### Bugfixes: +#### 1.10.1 ++ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. + ++ Missing PhysiBoSS makefiles have been replaced. + ++ Fixed broken makefile for worms sample project. + +#### 1.10.0 ++ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. + ++ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. + ++ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. + ++ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. + ++ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + +**Version:** 1.10.0 + +**Release date:** 13 May 2022 + +## Release summary: + +This release introduces major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. + +A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations + +A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes in the 1.10.z versions +#### 1.10.0 + ++ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. + + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. + + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. + + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. + + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. + + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. + + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. + + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ++ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. + ++ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. + + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). + + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. + + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` + ++ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. + + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. + + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. + + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + ++ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: + + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). + + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + ++ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of signals include: + + extracellular and intracellular substrate concentrations + + substrate gradients + + contact with dead cells + + contact with cells (of type X) + + damage + + pressure + + Use `display_signal_dictionary()` to quickly display a list of available signals. + + Substantial functionality to query signals + + `int find_signal_index( std::string signal_name )` : get the index of the named signal + + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals + + `std::string signal_name( int i );` display the name of the signal with the given index + + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell + + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell + + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices + + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals + + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index + + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name + ++ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. + + Major classes of behaviors include: + + secretion, secretion target, uptake, and export rates + + cycle progression + + death rates + + motility parameters + + chemotactic parameters + + cell-cell adhesion and repulsion parameters + + cell adhesion affinities + + cell-BM adhesion and repulsion parameters + + phagocytosis rates + + attack rates + + fusion rates + + transformation rates + + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. + + Substantial functionality to query and set behaviors + + `int find_behavior_index( std::string response_name )` : get the index of the named behavior + + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. + + `std::string behavior_name( int i );` get the name of the behavior with the given index + + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors + + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype + + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype + + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype + + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype + + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype + + Substantial functionality to query the cell's current behavior + + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors + + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) + + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) + + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) + + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) + + Substantial functionality to query the cell's referece behaviors (from its cell definition) + + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors + + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) + + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) + + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) + + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) + ++ Created a new `interaction-sample` project to illustrate the new interactions and transformations: + + Blood vessels release resource + + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) + + Stem cells divide and differentiate into differentiated cells + + Differentiated cells divide until experiencing elevated pressure (to detect confluence) + + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. + + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria + + Macrophages phagocytose dead cells + + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria + + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria + + Accumulated damage kills bacteria. + + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. + +### Minor new features and changes: + ++ All sample projects have a new rule "make name" to tell you the name of the executable. + ++ All sample projects output the executable name to screen for easier reference. + ++ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. + ++ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. + +### Beta features (not fully supported): + ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) + ++ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) + ++ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + ++ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) + +### Bugfixes: ++ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. + ++ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. + ++ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. + ++ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. + ++ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + +**Version:** 1.9.1 + +**Release date:** 13 September 2021 + +## Release summary: + +This release focuses primarily on bug fixes. It fixes memory leaks and other bugs in intracellular modeling, as well as several small bugs in parsing cell definitions in the XML configuration file. It also implements a basic_volume_model that only models total volume. (For internal consistency, it treats the entire cell as cytoplasm.) + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes: + ++ None in this release. + +### Minor new features and changes: + ++ Implemented basic_volume_model (see standard models), where nuclear volumes are set to zero, and cytoplasmic volumes are updated as normal. + +### Beta features (not fully supported): + ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) + ++ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) + ++ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + ++ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) + +### Bugfixes: ++ Fixed bug in legend function where on some rare occasions, the temporary cell could adversely interact with other cells prior to deletion. + ++ Remove an old error printout from standard_elastic_contact_function that causes problem with the ANCIENT version of gcc (4.8.x) that nanoHUB refuses to upgrade. + ++ Fixed Libroadrunner memory leak issue. + ++ Made minor bugfixes to parsing cell definitions in the XML configuration files: + + verify motility enabled flag is present before parsing its value + + fix bug when parsing multiple death models + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. + ++ We will most probably merge all of "core" and "modules" into "core." + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + +**Version:** 1.9.0 + +**Release date:** 12 July 2021 + +## Release summary: + +This release introduces intracellular modeling, i.e., models inside individual cells, for PhysiCell. We support three types of intracellular models: boolean networks, ordinary differential equations (ODEs), and dynamic flux balance analysis (dFBA). An intracellular model is part of a cell type's phenotype specification. Currently, we only support a single intracellular model per cell type; however, different *types* of models can be used for different cell types, e.g., a boolean network for cell type A and ODEs for cell type B. + +This new functionality has been a collaborative effort with the Institut Curie, the Barcelona Supercomputing Center, and the University of Washington. +We provide a unified C++ interface between each intracellular model and PhysiCell. + +The Systems Biology Markup Language (SBML) is used to define both the ODEs and FBA models; boolean networks are defined using MaBoSS's custom +configuration (.cfg and .bnd) files. (NOTE: PhysiCell does *not* support the full SBML specification; details are provided elsewhere.) + + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### Major new features and changes: + ++ First full support for intracellular models: boolean networks, ordinary differential equations (ODEs), and dynamic flux balance analysis (dFBA). + ++ Added an abstract `Intracellular` class in core/PhysiCell_phenotype.h. Concrete classes for the supported intracellular models provide the functionality in the abstract class. + ++ Added an `/addons` directory in the root directory. This is where the intracellular concrete classes and code are located. + ++ We adopt existing software for intracellular model solvers: MaBoSS for boolean networks, libRoadrunner for ODEs, and Clp for dFBA. However, to make it easier for modelers to use these solvers in PhysiCell, we provide automatic downloads of libraries (see next bullet). + ++ If a PhysiCell model uses an intracellular model, the PhysiCell Makefile will run a Python script (in the /beta directory) that checks to see if you have already downloaded the software (library) for the intracellular solver and, if not, downloads it and puts it in a directory within your PhysiCell project where it can be found and linked. The Python script will download the appropriate library for your operating system. + +### Minor new features and changes: + ++ Added `intracellular` XML element (inside `phenotype`) that specifies the type of intracellular model, its model definition file, its PhysiCell dt value to be evaluated, and relevant mappings between it and PhysiCell data. + ++ Added Python scripts in /beta to download intracellular solver libraries: setup_libroadrunner.py, setup_libmaboss.py, setup_fba.py + ++ Added new sample intracellular projects: physiboss_cell_lines, ode_energy, and cancer_metabolism + ++ Added parsing of `dt_intracellular` XML element in modules/PhysiCell_settings.cpp (associated with the `intracellular_dt` global parameter in PhysiCell_constants.{h,cpp}). +However, it is up to each intracellular model as to how, or if, it will be used. + ++ Added parsing of `intracellular_data` XML element in modules/PhysiCell_settings.cpp to determine. However, it is not currently used by the intracellular sample models. It may be used for debugging in the future. + ++ Updated the [Quickstart](documentation/Quickstart.md) guide, primarily to reflect necessary changes for intracellular solver libraries. + ++ Added `UniformInt()` to core/PhysiCell_utilities.cpp (used by intracellular boolean models) + ++ Added new functions to ./modules/PhysiCell_geometry to draw (unfilled) circles of cells + ++ Added new sample project: celltypes3 + ++ Removed sample projects: template2D, template3D + ++ Deleted deprecated code in core/PhysiCell_cell_container.cpp + ++ Bug fix and improvements to /beta/params_run.py to perform parameter explorations of models. + +### Beta features (not fully supported): + ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) + ++ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) + ++ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + ++ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) + +### Bugfixes: + ++ In core/PhysiCell_cell.cpp, replace `switch` statement with `if`/`else if` to prevent compiler errors related to `static const int` from PhysiCell_constants. + ++ core/PhysiCell_cell.cpp: assign_position(double x, double y, double z): make sure the current mechanics voxel is initialized. + ++ bug fix to update phenotype geometry when parsing and processing `volume` XML element + ++ The Makefile `reset` target now includes a `touch ./core/PhysiCell_cell.cpp` since its `.o` file can have intracellular dependencies. + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + +**Version:** 1.8.0 + +**Release date:** 9 March 2021 + +## Release summary: + +This release formally introduces Cell Definitions: a way to fully create cell types in the XML configuration file, including each cell type's initial phenotype and custom variables. This extends our recent work to shift specification of the microenvironment and boundary conditions to XML, and continues our trend towards a future release when many models can be designed and run without compiling any C++ at all. Most of the sample projects have been updated to use this new paradigm, including the a unified 2D/3D `template` project. We recommend using that template as the starting point for any new PhysiCell model. + +This release also introduces contact functions: a way to specify cell-cell contact interactions for any cells that you attach (using new, standardized attach and detach functions). Look at the `cancer-biorobots` and `biorobots` sample projects for examples for examples of the newly-introduced, standardized "spring" contact functions. The new `worm` sample project shows a more sophisticated example where cells exchange a differentiation factor across their contacts to model juxtacrine signaling. To help support contact interaction modeling, we include new search functions to easily report a vector of Cells that are nearby for use in your contact interactions. The default mechanics function also records a list of all currently (mechanically) interacting cells in state.neighbors. + +The release also add a number of features to improve the ease of code use: a copy of the XML configuration file is now saved in your output directory to help keep track of what parameters and settings generated the data. We auto-generate a `legend.svg` file (also in output) based on your coloring function and cell defintions. The sample projects' Makefiles now include new rules to create animated GIFs, convert SVG to JPG, create a MP4 movie, and even auto-download the latest version of PhysiCell to update an existing project. A key new feature is the ability to pre-specify cell locations in a CSV file. The template projects will auto-parse this list if enabled to place cells at the start of the simulation. We also provide new functionality to add a virtual wall to the simulation domain to help keep cells from leaving; this can be enabled or disabled from the XML configuration file. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ Full rollout of `Cell_Definition` in the XML configuration files. Many basic models can now be fully defined in XML with minimal or no C++. + ++ Unified the 2D and 3D template projects into a single "template" project. + ++ New `predator-prey-farmer` sample project. Prey look for and consume food that's released by farmers. Prey avoid predators, predators hunt and eat prey. + ++ Improved thread safety, particularly when cells ingest cells. + ++ Introduced new cell-cell contact functions with syntax: + +`void contact( Cell* pME, Phenotype& my_phenotype , Cell* pOther, Phenotype& other_phenotype, double dt )` + +These are exexcuted once per mechanics time step. Best practice is to either only read `pOther` and `other_phenotype`, or use OMP critical locks if writing data to `pOther` and `other_phenotype`. + +For any cell (`this`), the contact function will be executed for any other cell (other) in `this->state.attached_cells`. The modeler will still need to decide which cells to attach. + +All attached cells are automatically removed when a cell dies or divides. + ++ Added new attachment and detachment functions to the `Cell` class: +++ `void attach_cell( Cell* pAddMe );` Add `pAddme` to the cell's `state.attached_cells` for use in contact functions. +++ `void detach_cell( Cell* pRemoveMe );` Remove `pRemoveMe` from the cell's `state.attached_cells` list. +++ `void remove_all_attached_cells( void );` Remove all attached cells. + ++ Added additional attachment and detachment functions outside the `Cell` class: +++ `void attach_cells( Cell* pCell_1, Cell* pCell_2 );` Add `pCell_2` to `pCell_1->state.attached_cells` and add `pCell_1` to `pCell_2->state.attached_cells` +++ `void detach_cells( Cell* pCell_1 , Cell* pCell_2 );` Remove the attachments. + ++ Introduced a standardized cell-cell spring-like adhesion contact function: `standard_elastic_contact_function.` + +This will add an additional Hookean spring attraction to cells in `state.attached_cells`. The modeler will still need to decide when to attach or detach cells. (Recommended practice: use the `custom` function that is evaluated once per mechanics time step.) + ++ Introduced two new member search funtions for cells to facilitate contact functions: +++ `std::vector nearby_cells(void)` returns a vector of all cells in the nearby mechanics voxels, excluding the cell (`this`). +Users should still test the distance to these cells in their interaction functions. +++ `std::vector nearby_interacting_cells(void)` returns a vector of all cells in the nearby mechanics voxels that are within interaction distance, excluding the cell (`this`). This uses the same distance testing as in the default mechanics functions. + ++ Introduced two new search funtions outside the `Cell` class to facilitate contact functions: +++ `std::vector nearby_cells(Cell* pCell)` returns a vector of all cells in the nearby mechanics voxels, excluding the cell (`pCell`). +Users should still test the distance to these cells in their interaction functions. +++ `std::vector nearby_interacting_cells(Cell* pCell)` returns a vector of all cells in the nearby mechanics voxels that are within interaction distance, excluding the cell (`pCell`). This uses the same distance testing as in the default mechanics functions. + ++ The default mechanics function now automatically updates `state.neighbors` with a list of all cells which had non-zero mechanical interactions in the last mechanics time step. Use this as an inexpensive (``prepaid``) method to find nearby cells for your own contact functions. + ++ Introduced a new sample project `worm` which shows advanced interaction testing and contact testing. Individual cells aggregate based on chemotaxis towards a secreted quorum factor and test for contacts. Cells can form a maximum of `n` (default: 2) attachments with the built-in spring functions. Cells on the ends (1 attachment) hold a steady expression of a differentiation function (`head`). This factor is exchanged between interior cells (2 attachments) to model juxtacrine signaling, using a contact function. End cells determine if they are a head or a tail based by comparing their expresoin with their linked neibhbor. This introduces asymmmetry that allows the "worms" to crawl directionally. + ++ All sample projects now copy the configuration file to the output directory, to help keep track of settings and parameters used to create a simulation result. + ++ Updated the sample projects to use the new Cell_Definitions and contact functions. + ++ Users can now pre-specify cell positions by creating a CSV file: +++ Each row corresponds to a cell: x,y,z,typeID +++ TypeID is the integer index of a `Cell_Definition` (ideally defined in XML!) +++ Call the function `load_cells_csv( std::string filename )` to load these possitions and place the cells in corresponding positions. Ideally, cally this function at the end of `setup_tissue()`. The template projects will call this function automatically if a cell CSV file is specified in the `initial_conditions` section of the XML configuration file. +++ The `template` project already uses this function in the right place. See `worm-sample` for project that uses it. + +### Minor new features and changes: + ++ Cell definitions can now be defined by XML files. See the note above. This functionality may be additionally refined or modified in the next few releases while still in beta. + ++ All sample projects have a `make jpeg` rule that uses ImageMagick to convert SVG snapshots into JPG files. + ++ All sample projects have a `make movie` that uses ffmepg to convert JPG snapshots to an mp4 animation. + ++ The `make upgrade` rule will check for and download the most recent version of PhysiCell, overwriting these core functions (and sample projects) without overwriting your project code. + ++ A new `paint_by_number_cell_coloring` coloring function colors each cell type with a unique color. (Currently there is a maximum of 13 pre-defined colors for 13 cell types.) Apoptotic cells are black, and necrotic cells are brown. + ++ Cycle and Death in the XML `Cell_Definitions` no longer require a `code` as long as the `name` is correct. + ++ Revised template project to a barebones minimum. + ++ Removed beta-testing sample project. + ++ Added functionality to auto-generate an SVG legend based on the currently defined XML funtions and coloring function. + +### Beta features (not fully supported): + ++ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + ++ Started creating new functions to fill geometric shapes with cells of a chosen type. + +### Bugfixes: + ++ In response to SourceForge ticket #43, fixed the bug where Dirichlet conditions weren't properly applied to individual boundaries. + ++ Cleaned up code as suggested in SourceForge Ticket #42. + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ Read saved simulation states (as MultiCellDS digital snapshots) + ++ Integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ Integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ Create an angiogenesis sample project + ++ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ Improved plotting options in SVG + ++ Further update sample projects to make use of more efficient interaction testing available + ++ Major refresh of documentation. + +* * * + +**Version:** 1.7.1 + +**Release date:** 2 June 2020 + +## Release summary: + +This release introduces bug fixes (particularly the placement of daughter cells after division), introduces new functions for uniformly random sampling of the unit circle and unit sphere, and refines the beta implementation of XML-based cell definitions. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ No major changes. See 1.7.0 for most recent major changes. + +### Minor new features and changes: + ++ Created new function std::vector UniformOnUnitSphere( void ) that returns a (uniformly) random vector (x,y,z) on the unit sphere. + ++ Created new function std::vector UniformOnUnitCircle( void ) that returns a (uniformly) random vector (x,y,0) on the unit circle (in the z = 0 plane). + ++ Created std::vector LegacyRandomOnUnitSphere() that reproduces old behaviors of creating a random vector on the unit sphere. Never use this except if trying to replicate old results. Always use UniformOnUnitSphere() instead. + ++ Changed default placement of daughter cells to use UniformOnUnitCircle(), in response to longstanding "future plan" to "introduce improvements to placement of daughter cells after division." + ++ All sample projects now check for in their XML config files. + ++ Template projects calculate gradients and perform internal substrate tracking by default. + ++ Moved the bool is_active from "protected" to "public" in the Basic_Agent class in BioFVM_basic_agent.h, so that cells be be moved back into the domain and reactivated as needed. + ++ Changed beta implementation of XML cell definitions: + + In cycle, transition_rates renamed to phase_transition_rates. PhysiCell will give a deprecatoin warning for transition_rates until the official release of XML cell definitions. + + In death, rates renamed to death_rates. PhysiCell will give a deprecatoin warning for transition_rates until the official release of XML cell definitions. + + In cycle and death, "phase_durations" can now be used in place of phase_transition rates. This may be more intuitive for some modelers. + ++ See 1.7.0 for other recent minor changes. + +### Beta features (not fully supported): + ++ Cell definitions can now be defined by XML files. See the note above. This functionality may be additionally refined or modified in the next few releases while still in beta. + +### Bugfixes: + ++ In response to SourceForge ticket 26, fixed placement of parent cell in Cell::divide() + ++ Removed errant Cell_Definition in the new template sample project. + ++ Added an extra check for bad chemotaxis definitions in response ot SourceForge ticket 28. + ++ Fixed bugs in processing of the "death" section of XML cell definitions. + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Methods or scripts to make "upgrading" PhysiCell easier for existing projects (to avoid overwriting the config file, Makefile, or custom files. + ++ Current "template" project will be rolled into a new "predator-prey" sample project, and "template" will be tidied up. + ++ Further XML-based simulation setup. + ++ current sample projects will be refactored to use XML cdell definitions. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ improved plotting options in SVG + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems. + +**Version:** 1.7.0 + +**Release date:** 12 May 2020 + +## Release summary: + +This release (1) adds "net export" as a new form of more generalized substrate secretion, (2) adds helper funtions for cell size and volume for esier configuration, (3) adds a new, standardized chemotaxis function, (4) adds 1D diffusion, and (5) introduces XML-based cell definitions as a beta feature. It also incorporates a variety of bugfixes. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ Added "net_export_rates" to "secretion" part of Phenotype, and to the Basic_Agent class in BioFVM. This is in response to SourceForge ticket 19. + ++ Added new helper functions to help users to more easily set the *target* cell size: + + void Cell::set_target_volume( double new_volume ) sets the target total cell volume, while preserving the desired nuclear:cytoplasmic ratio and desired fluid fraction. In the default cell volume model, the cell will now approach this value by shrinking or growing. + + void Cell::set_target_radius( double new_radius ) behaves similarly, but using a radius instead. + ++ Added Cell::set_radius( double new_radius ) to set the cell's current radius to the new value, preserving the nuclear:cytoplasmic ratio and fluid fraction. Note that this does not change the target values, so the cell will shrink or grow back towards its current target size. + ++ Added 1-D diffusion solvers to BioFVM (useful for some coarse-grained problems). It solves for diffusion in the x-direction only. Use it by setting: + + microenvironment.diffusion_decay_solver = diffusion_decay_solver__constant_coefficients_LOD_1D + + Use this right after setup_microenvironment() in your main.cpp file. Future versions will include an XML option to use 1D. Most users will never need this. + ++ Added a standardized chemotaxis function to the standard models: + + void chemotaxis_direction( Cell* pCell , Phenotype& phenotype , double dt ); + + This sets: + + phenotype.motility.motility_bias_direction = direction * grad( index ), where + + direction = phenotype.motility.chemotaxis_direction + (1 to go up gradient, -1 to go down gradient) + index = phenotype.motility.chemotaxis_index + (the index of one of hte diffusing substrates) + ++ Added Cell_Definitions in XML (beta feature) in response to SourceForge ticket 5. Users will be able to set the cell defaults definition by XML, as well as additional cell definitions that "inherit" phenotype parameters from cell defaults. This vastly reduces teh amount of necessary C++ to define a model. The new "template" sample project unifies 2D and 3D model specification using the new XML-based cell definitions. The next few releases will refine documentation and roll teh new XML-based cell definitions out to all the other sample projects. + +### Minor new features and changes: + ++ Created get_cell_definition(std::string) to return by reference the matching cell definition (search by name). Returns cell_defaults if nothing found. + ++ Created get_cell_definition(int) to return by reference the matching cell definition (search by type). Returns cell_defaults if nothing found. + ++ added int chemotaxis_index and chemotaxis_direction to the Motility class to assist with a new standard chemotaxis function. + ++ scale_all_secretion_by_factor also scales net_export_rates. + ++ sync_to_current_microenvironment and sync_to_microenvironment set up net_export_rates + ++ Secretion::advance now updates net_export processes + ++ Secretion::set_all_secretion_to_zero and Secretion::scale_all_secretion_by_factor act on net_export_rates as well. + ++ Cell::turn_off_reactions acts on net_export_rates as well. + ++ BioFVM::Basic_Agent::simulate_secretion_and_uptake now updates net_export processes, including impact on internal tracked substrate totals. (And all appropriate initializatoin functions have been updated. + ++ Updated documentation to reflect the new net export rates. + ++ Updated the documentation to fully state the biotransport PDEs (for better clarity), including notes on the dimensions of the parameters. + ++ Deprecated the following (unimplemented) function from the Volume class definition, as promised: +``` + void update( Cell* pCell, Phenotype& phenotype, double dt ) +``` + ++ Added a new registry (unsorted map) of all cell definitions called cell_definitions_by_name and a vector of cell definitions called cell_definitions_by_index. + ++ The Cell_Definition default constructor and copy constructor automatically register all new cell definitions in cell_definitions_by_index; + ++ Created a display_cell_definitions(std::ostream&) function to quickly list all cell definitions and key information. + ++ Created build_cell_definitions_maps() to create cell_definitions_by_name and cell_definitions_by_type. This should go at the end of create_cell_types(). + ++ Created find_cell_definition(std::string) to return a pointer to the matching cell definition (search by name). Returns NULL if nothing found. + ++ Created find_cell_definition(int) to return a pointer to the matching cell definition (search by type). Returns NULL if nothing found. + ++ Created unit tests for cell definitions + ++ Deprecated oxygen_index, glucose_index, TUMOR_TYPE, and VESSEL_TYPE from PhysiCell_Constants as promised. + ++ Minor source code cleanup in PhysiCell_settings.cpp. + ++ All sample projects now automatically build (and display) the registries of cell definitions via build_cell_definitions_maps() and display_cell_definitions(). + ++ added the following std::vector to Microenvironment_Options to facilitate setting Dirichlet conditions on specific boundaries for specific substates: Dirichlet_all, Dirichlet_xmin, Dirichlet_xmax, Dirichlet_ymin, Dirichlet_ymax, Dirichlet_zmin, Dirichlet_zmax, Dirichlet_interior. + ++ Minor cleanup in BioFVM_microenvironment.cpp + ++ Microenvironment::update_dirichlet_node(voxel_index,substrate_index,value) now sets dirichlet_activation_vectors[voxel_index][substrate_index] = true; + ++ Microenvironment::set_substrate_dirichlet_activation( int substrate_index , bool new_value ) now sets dirichlet_activation_vectors[voxel_index][substrate_index] for ALL Dirichlet nodes. + ++ Microenvironment::apply_dirichlet_conditions() now checks the Dirichlet activation vector of the individual voxel. + ++ Microenvironment::resize_voxels() and the various Microenvironment::resize_space() functions now resize dirichlet_activation_vectors, using the default dirichlet_activation_vector as the initial uniform activation vector. + ++ Microenvironment::resize_densities() and the various Microenvironment::add_density() functions now resize dirichlet_activation_vector and use it to intialize dirichlet_activation_vectors at every voxel. + ++ The various Microenvironment::add_density() functions now + ++ Added function Microenvironment::set_substrate_dirichlet_activation( int index, std::vector& new_value ) to set the entire vector of activation at a specific voxel. + + +### Beta features (not fully supported): + ++ Cell definitions can now be defined by XML files. See the note above. This functionality may be additionally refined in the next few releases while still in beta. + + +### Bugfixes: + ++ In response to SourceForge ticket 25, added cell_defaults.phenotype.molecular.sync_to_microenvironment( µenvironment ); to the create_cell_types() functions in the 2D and 3D template projects. + ++ In response to SourceForge ticket 18, update_cell_and_death_parameters_O2_based() now checks for deterministic necrosis. + ++ In response to GitHub issue 33, fixed issue where data-cleanup makefile rule gets a list of too many files. Rolled the new rule through to all the sample Makefiles as well. + +``` +data-cleanup: + rm -f *.mat + rm -f *.xml + rm -f *.svg + rm -rf ./output + mkdir ./output + touch ./output/empty.txt +``` ++ Updated Cell::Cell(), create_cell(), create_cell(Cell_Defintion), and convert_to_cell_definition() to call set_total_volume( phenotype.volume.total ). This makes sure that BioFVM knows the correct volume at the time of creation (or major update) so that it can save the correct values to outputs. This is in response to GitHub issue 22. + ++ Removed the false statement from the user manual that stated that the cytoplasmic:nuclear ratio is between 0 and 1. + ++ Removed the false statement from the user manual that stated that relative cell rupture volume is between 0 and 1. + ++ Updated the list of PhysiCell_Constants in response to SourceForge ticket 11. + ++ The various Microenvironment::add_density() functions now only set dirichlet_activation_vector = true for the newly added substrate, rather than *all* of them. This new vector is then used to initialize the activation vectors at every voxel. + ++ Microenvironment::get_substrate_dirichlet_activation() mistakenly returned a double. Now it returns bool. + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ We will introduce improvements to placement of daughter cells after division. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ improved plotting options in SVG + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems. + +**Version:** 1.6.1 + +**Release date:** 26 January 2020 + +## Release summary: + +This release fixes minor bugs and improves the documentation. It also adds some minor new capabilities, such as setting time step sizes in the XML configuration file. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ List here. + +### Minor new features and changes: + ++ "make list-projects" now displayed to standard output a list of all the sample projects. + ++ dt_diffusion, dt_mechanics, and dt_phenotype can now be set via the XML configuration file in the options section. + ++ Added documentation on the time step sizes to the User Guide. + ++ Preliminary work to support Travis CI testing. + ++ Updated documentation to note that Cell::start_death is the preferred method to trigger cell death, and NOT Death::trigger_death. + ++ Updated Microenvironment::compute_all_gradient_vectors to now compute one-sized gradients on edge voxels. (Previously, no gradient was computed here.) + ++ Updated Microenvironment::compute_all_gradient_vectors to check if there is no z-direction (i.e., 2D) and exit early if so. + ++ Updated Microenvironment::compute_all_gradient_vectors to check if there is no y-direction (i.e., 1D) and exit early if so. + ++ Made PhysiCell_constants.cpp (and added this to the core of all project makefiles) so that dt and other variables can be non-static (i.e., set by XML options). + ++ Added "make checkpoint" rule to makefiles. This zips up the user-custom stuff (./config, ./, ./custom_modules) into a timestamped zip file. Use this before upgrading PhysiCell to make sure you keep your own Makefile, etc. + +### Beta features (not fully supported): + ++ List here. + +### Bugfixes: + ++ BioFVM's diffusion_decay_solver__constant_coefficients_LOD_3D, diffusion_decay_solver__constant_coefficients_LOD_2D check for regular meshes instead of uniform meshes. + ++ Biorobots sample project fixed bugs on searching for substrates vs. searching for cell types. + ++ In BioFVM_vectors, the normalize functions now return a zero vector if the vector's norm is less than 1e-16. This is for John Metzcar. + ++ In PhysiCell_Cell.cpp, made fixes to Cell::divide() and Cell::assign_position() to fix a bug where cells dividing on the edge of the domain woudl place a daughter cell at (0,0,0). Thanks, Andrew Eckel! + ++ Code cleanup in PhysiCell_cell_container in Cell_Container::update_all_cells() as suggested by Andrew Eckel. Thanks! + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ We will introduce improvements to placement of daughter cells after division. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + ++ We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + ++ We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ improved plotting options in SVG + +* * * + +**Version:** 1.6.0 + +**Release date:** 20 August 2019 + +## Release summary: + +This release introduces a new XML-based configuration for the chemical microenvironment. All +the sample projects have been updated to use this new functionality. There is no change +in APIs or high-level usage / syntax for end users; old projects should continue to work without +modification, although we highly recommend migrating to the simplified microenvironment setup. +A short blog tutorial on this new functionality can be found at + +http://mathcancer.org/blog/setting-up-the-physicell-microenvironment-with-xml + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ XML-based setup of the chemical microenvironment. + +### Minor new features and changes: + ++ Updated template2D sample project: + + Refined "reset" and "data-cleanup" rules in Makefile + + Converted project to use the new XML-based microenvironment setup. + ++ Updated template3D sample project: + + Refined "reset" and "data-cleanup" rules in Makefile + + Converted project to use the new XML-based microenvironment setup. + ++ Updated heterogeneity sample project: + + Refined "reset" and "data-cleanup" rules in Makefile + + Converted project to use the new XML-based microenvironment setup. + ++ Updated cancer immune sample rpoject: + + Refined "reset" and "data-cleanup" rules in Makefile + + Converted project to use the new XML-based microenvironment setup. + ++ Updated virus macrophage sample project: + + Refined "reset" and "data-cleanup" rules in Makefile + + Converted project to use the new XML-based microenvironment setup. + + Enabled gradient calculations (were previously off, although we wanted macrophage chemotaxis) + ++ Updated biorobots sample project: + + Refined "reset" and "data-cleanup" rules in Makefile. + + Converted project to use the new XML-based microenvironment setup. + + Note that values in user_parameters will override values in microenvironment_setup. + + Improved project to properly search for substrate indices instead of hard coding them. + ++ Updated cancer biorobots sample project: + + Refined "reset" rule in Makefile. + + Converted project to use the new XML-based microenvironment setup. + + Improved project to properly search for substrate indices instead of hard coding them. + ++ Refined "reset" and "data-cleanup" rules in default Makefile + ++ Created new function to access the (private) microenvironment dirichlet_activation_vector: + + double Microenvironment::get_substrate_dirichlet_activation( int substrate_index ); + ++ Updated the main microenvironment display function Microenvironment::display_information to summarize the initial and boundary conditions for each substrate + ++ Wrote two new functions to parse the XML in microenvironment_setup to add substrates and +options: + + bool setup_microenvironment_from_XML( pugi::xml_node root_node ) + + bool setup_microenvironment_from_XML( void ) +The second one assumes you already defined the root node and access the +global (pugi)xml node for it. + ++ The main XML parsing function now calls setup_microenvironment_from_XML(), just before processing user-defined parameters. + +### Beta features (not fully supported): + ++ anim_svg.py - now plots correctly sized cells; manually step via arrow keys + ++ anim_svg_cycle.py - same as above, but automatically cycles through .svg files + +### Bugfixes: + ++ None. + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ We will introduce improvements to placement of daughter cells after division. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ improved plotting options in SVG + +* * * + +**Version:** 1.5.2 + +**Release date:** 11 June 2019 + +## Release summary: + +This minor release fixes bugs that affected the release of internalized substrates at cell death on Linux and OSX operating systems, relating to system differences in order of evaluating destructor functions. The release of internalized substrates has been moved to a new function, and placed in cell death functions. There is no change in APIs or high-level usage / syntax for end users. + +Users should also consult the release notes for 1.5.0. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ None + +### Minor new features and changes: + ++ Introduced new function Basic_Agent::release_internalized_substrates() to explicitly release a cell's internalized substrates, rather assuming it can be properly done in the Basic_Agent destructor function. + ++ Removed the Basic_Agent destructor function to allow the compiler to automatically generate this. + ++ Very minor revisions to the release protocol. + ++ Minor updates to the user guide to reflect the release_internalized_substrates() function. + +### Beta features (not fully supported): + ++ anim_svg.py - now plots correctly sized cells; manually step via arrow keys + ++ anim_svg_cycle.py - same as above, but automatically cycles through .svg files + +### Bugfixes: + ++ Move code for internalized substrate release from the Basic_Agent destructor to the new Basic_Agent::release_internalized_substrates() function. + ++ Basic_Agent::release_internalized_substrates() is now called from delete_cell(int) in PhysiCell_cell.cpp. + ++ Basic_Agent::release_internalized_substrates() explicitly sets internalized_substrates to a zero vector, just in case users want to call this function on non-dead cells. + ++ Cell::Cell() now initializes updated_current_mechanics_voxel_index = 0 (avoids a possible segfault in GDB) + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ We will introduce improvements to placement of daughter cells after division. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ improved plotting options in SVG + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems. + +**Version:** 1.5.1 + +**Release date:** 7 June 2019 + +## Release summary: + +This minor release fixes bugs in the new virus-macrophage sample project. Users should also consult the reslease notes for 1.5.0. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ None + +### Minor new features and changes: + ++ None + +### Beta features (not fully supported): + ++ None + +### Bugfixes: + ++ In the virus-macrophage sample project, switch cell death (in epithelial_function) from apoptosis to cell_lysis to demonstrate the new function. + ++ In the virus-macrophage sample project, enable internalized substrate tracking in the setup_microenvironment() function. + ++ In the virus-macrophage sample project, use a slower viral replication rate. (Should take 240 minutes to reach the lysis threshold.) + ++ In the virus-macrophage sample project, switched to a maximum simulation time of 24 hours (1440 minutes). + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ We will introduce improvements to placement of daughter cells after division. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ improved plotting options in SVG + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems. + +**Version:** 1.5.0 + +**Release date:** 7 June 2019 + +## Release summary: + +This release introduces the ability to track the net internalization of diffusible substrates from the microenvironment, conserving mass with the diffusion-reaction partial differentiatial equations in BioFVM. This is part of longer-term plans to support molecular-scale models (e.g., as encoded by SBML). It also introduces the ability for cells to ingest other cells (and acquire their internalized substrates and volume), the ability for cells to release their internalized substrates back to the microenvironment after death, and a new cell death model (lysis). + +To illustrate these new capabilities, this release introduces a new sample project called virus-macrophage-sample. In this project, virus particles diffuse through the microenvironment, are uptaken by cells, replicate within cells, and trigger lytic death after reaching a threshold. Lysed cells release their virus particles to further diffuse through the environment. Macrophages move by random migration, test for contact with cells, and ingest / phagocytose cells based upon their viral load. Macrophages degrade their internalized viral particles. + +This release also added clearer methods to specify the microenvironment initial conditions, and improved documentation. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ Added functionality in BioFVM to (optionally) track the total amount of substrates in each cell, based upon tracking uptake and secretion. Note that without additional, user-defined functions to internally create or consume substrate (e.g., synthesizing proteins, or using oxygen in metabolism), this can result in negative internal values (if cells only secrete but no internal creation functions have been set) or unbounded positive values (if cells uptake a substrate but do not consume it). In particular, Basic_Agents (and hence Cells) now have: +++ std::vector* internalized_substrates (tracks internalized substrates) +++ std::vector* fraction_released_at_death (sets the fraction of each substrate that is released at cell death) +++ std::vector* fraction_transferred_when_ingested (sets the fraction of each substrate that is transferred to a predatory cell if the cell is eaten). + +Users should access these via the cell's (new) molecular portion of the phenotype. See below. + +In BioFVM::Microenvironment_Options class, we added: +++ bool track_internalized_substrates_in_each_agent. Set this to true to enable the tracking. + ++ In BioFVM::Microenvironment_Options, we added the ability to set the (uniform) microenvironment initial conditions, via: +++ std::vector initial_condition_vector. + +If this has size zero, then BioFVM will use the std::vector Dirichlet_condition_vector as a reasonable guess at initial conditions as in prior versions. + ++ We added a new function to Basic_Agent (and hence Cell) to facilitate registering with the microenvironment: +++ void Basic_Agent::register_microenvironment( Microenvironment* microenvironment_in ) + +This function will ensure that the secretion, uptake, and internalization tracking data structures of the individual cell agent are properly matched to the microenvironment. + ++ Added new "Molecular" block to Phenotype, for storing internalized substrates and for eventual inclusion of molecular-scale models (via SBML). The major elements are: +++ std::vector internalized_substrates (tracks internalized substrates) +++ std::vector fraction_released_at_death (sets the fraction of each substrate that is released at cell death) +++ std::vector fraction_transferred_when_ingested (sets the fraction of each substrate that is transferred to a predatory cell if the cell is eaten). + ++ Added lyse_cell() to Cell, to allow a cell to immediately be lysed and potentially release its internalized substrates. Lysed cells are removed from the simulation. + ++ Added ingest_cell(Cell*) to Cell, to allow a cell to ingest (e.g., phagocytose) another cell, acquire its volume, and also (optionally) acquire its internalized substrates. This should be useful for immunology. + +### Minor new features and changes: + ++ Added void Microenvironment::update_dirichlet_node( int voxel_index , int substrate_index , double new_value ) based on pc4nanobio changes, which allows you to update a single substrate's dirichlet condition at specific voxel, rather than all of them. + ++ Added void sync_to_microenvironment( Microenvironment* pMicroenvironment ) to Phenotype to facilitate syncing the cell's phenotype to the microenvironment (and subsequently calls the functions in phenotype.secretion and phenotype.molecular). This isn't used yet, but perhaps it should be. + +### Beta features (not fully supported): + ++ None + +### Bugfixes: + ++ Updated BioFVM's operator<< on std::vector so that it doesn't output x="value", y="value", z = "value" for 3-D vectors. + ++ Fixed the search for cycle phase indices in the 2D and 3D template projects, to make sure it searches teh flow_cytometry_separated_cycle_model model and not the Ki67_advanced model, as part of the create_cell_types() function in the custom.cpp files. + ++ In PhysiCell_standard_models, standard_volume_update_function is now fixed to update phenotype.volume.fluid. (This was not used in any mechanics or other calculations, so it does not affect prior modeling results.) + ++ Removed repeated parameters (attached_worker_migration_bias, unattached_worker_migration_bias) in the cancer biorobots sample project. + ++ trigger_death() now works. + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + ++ We will introduce improvements to placement of daughter cells after division. + ++ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems. + +**Version:** 1.4.1 + +**Release date:** 2 October 2018 + +## Release summary: + +This release improves includes minor bug fixes for compiling in older versions of MinGW, and simplified XML MultiCellDS outputs that no longer record the relative pathing to .mat files. (This allows users to read data from their actual locations, rather than from a parent directory.) This release includes minor code cleanups in BioFVM for cleaner compiling in Ubuntu. Lastly, we have make small refinements to the sample projects and makefiles to default data saving to the ./output directory, and to prevent future releases from excluding the output directory from the zip releases. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ None + +### Minor new features and changes: + ++ Changed the MultiCellDS outputs to only store the filename, and not the full relative path, in the tags. This makes it simpler to load MultiCellDS outputs from matlab and other platforms. (No longer need to read from a directory higher up to make the relative pathing correct.) + ++ Did major cleanup on BioFVM so that it compiles cleanly on Ubuntu. + ++ All sample projects output to the ./output directory + +### Beta features (not fully supported): + ++ None + +### Bugfixes: + ++ Updated the Parameter constructor functions to create a specialized version for std::string, to fix odd compiling bugs on older versions of MinGW. (Worked in 7.1.0, but not in 5.3.0.) Now, Parameter for T = bool, int, or double get initialized to value = (T) 0. And Parameter for T = std::string gets initialized to "none". I had hoped to do a unified version, but value = (T) 0 for std::string acts like a NULL pointer. + ++ All Makefiles ensure that the reset and data-cleanup rules leave at least empty.txt in ./output, so that future releases are never missing the output directory. + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + ++ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. (Likely in next release.) + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + ++ (optionally) track internalized substrate, coupled with BioFVM + +* * * + +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems. + +**Version:** 1.4.0 + +**Release date:** 26 September 2018 + +## Release summary: + +This release improves the use of XML parsing in configuring simulations, notably (1) reading the domain parameters instead of hard-coded values, and (2) parsing a block in the XML config files to populate a global parameters data structure of Boolean, integer, double, and std::string variables. Users can efficiently query these from within any function anywhere in a PhysiCell project. + +**NOTE:** OSX users must now define PHYSICELL_CPP system variable. See the documentation. + +### Major new features and changes: + ++ User Parameters! + ++ Parsing XML to set domain size for all sample projects. + +### Minor new features and changes: + ++ Updated all the sample projects to use the improved XML parsing; + ++ New functions in PhysiCell_pugixml: + + 1) std::string xml_get_my_name( pugi::xml_node node ); + + This helps to easily extract the name of an XML node. (e.g., returns bob.) + + 2) bool xml_get_my_bool_value( pugi::xml_node node ); + + This gets the Boolean value of an XML node. (e.g., true returns true.) + + 3) int xml_get_my_int_value( pugi::xml_node node ); + + This gets the integer value of an XML node. (e.g., 42 returns 42.) + + 4) double xml_get_my_double_value( pugi::xml_node node ); + + This gets the double value of an XML node. (e.g., 42.03 returns 42.03.) + + 5) std::string xml_get_my_string_value( pugi::xml_node node ); + ++ Updated all Makefiles to copy main.cpp, the Makefile, and ./config/PhysiCell_settings.xml to backup copies prior to populating any sample project. + ++ Updated the heterogeneity sample project: + + 1) Use the domain settings from the XML config file + + 2) Use the XML config file options to set the initial tumor size and oncoprotein distribution. + + 3) Get the random seed from the XML config file. + + 4) Rewrote the custom coloring function to scale from min oncoprotein value (blue) to max oncoprotein value (yellow). + ++ Updated template2D sample project: + + 1) Use the domain settings from the XML config file + + 2) Use the XML config file to set the motile cell parameters + + 3) Get the random seed from the XML config file. + + 4) Updated to use the my_coloring_function coloring function. Made sure the my_coloring_function used false_cell_coloring_cytometry as its starting point. + ++ Updated template3D sample project: + + 1) Use the domain settings from the XML config file + + 2) Use the XML config file to set the motile cell parameters + + 3) Get the random seed from the XML config file. + + 4) Updated to use the my_coloring_function coloring function. Made sure the my_coloring_function used false_cell_coloring_cytometry as its starting point. + ++ Updated biorobots sample project: + + 1) Use the domain settings from the XML config file + + 2) Use the XML config file to set parameters and colors throughout the biorobots.cpp file + + 3) Get the random seed from the XML config file + ++ Updated cancer immune sample project: + + 1) Use the domain settings from the XML config file + + 2) Use the XML config file to set parameters throughout the cancer_immune_3D.cpp file + + 3) Get the random seed from the XML config file + ++ New function in ./core/PhysiCell_utilities: + + int choose_event( std::vector ); + + If probabilities is a vector of n probabilities (for n events), and the sum of the probabilities is 1, then this chooses one of those n events according to these probabilities and returns the index of the selected event. + ++ Moved from README.txt to README.md to support markdown and improve releases on both SourceForge and GitHub. + ++ Moved from changes.txt to changes.md to support markdown and improve releases on both SourceForge and GitHub. + +### Beta features (not fully supported): + ++ None + +### Bugfixes: + ++ Updated the "reset" rules so that the default config file is restored (in all the sample makefiles). + ++ Removed a cout from Mechanics::set_relative_equilibrium_distance() from ./core/PhysiCell_phenotype.* + +### Notices for intended changes that may affect backwards compatibility: + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. + +### Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. (Likely in next release.) + ++ Add cell differentiation functionality to Phenotype, to be executed during cell division events. + ++ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) + ++ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) + +* * * + +PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.3.3 +Release date: 16 September 2018 + +Release summary: + +This release introduces simplifications in versioning to facilitate +faster release cycles. It also introduces functions to register and +list citations for third-part add-ons. The goal is to encourage end- +users to properly cite PhysiCell and add-on products used in their +projects. + +NOTE: OSX users must now define PHYSICELL_CPP system variable. + See the documentation. + +Major new features and changes: + ++ none + +Minor new features and changes: + ++ Moved all version information to VERSION.txt to facilitate + faster release cycles. + ++ Updated all the Makefiles to set VERSION via + + VERSION := $(shell grep . VERSION.txt | cut -f1 -d:) + ++ Moved detailed citation information to CITATION.txt to + facilitate faster release cycles. + ++ Changed std::string PhysiCell_version to + std::string PhysiCell_Version for more consistency with + prior BioFVM work. + ++ Added new static string to PhysiCell.h: + static std::string PhysiCell_DOI + ++ Added new functions to PhysiCell_utilities to query + PhysiCell versioning: + + std::string get_PhysiCell_version( void ); + + void get_PhysiCell_version( std::string& pString ); + ++ Added the following function to PhysiCell_utilities to + display a list of all software versions and citations + used in the code: + + void display_citations( std::ostream& os ); + void display_citations( void ); + + For example, use display_citations( std::cout ), or use + an output file stream. Note that display_citations(void) + calls display_citation(std::cout); + ++ Updated all the sample projects to use display_citations(); + +Beta features (not fully supported): + ++ Added ./protocols/ directory to include release and other + instructions, to help train new developer contributors. + Perhaps this should be called "checklists" ? + ++ Added the following functions to PhysiCell_utilities to + register third-party software citations in a global list, + ready for query and display: + + void add_software_citation( std::string name , + std::string version, std::string DOI, std::string URL ); + +Bugfixes: + ++ None + +Notices for intended changes that may affect backwards compatibility: + ++ We will probably move from README.txt to README.md to support + markdown and improve releases on both SourceForge and GitHub. + ++ We will probably move from changes.txt to changes.md to support + markdown in the long-term change logs. + ++ We intend to merge Custom_Variable and Custom_Vector_Variable in the + very near future. + +Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models + (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions + for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code + (See http://dx.doi.org/10.1093/bioinformatics/bty766. ) + ++ Develop contact-based cell-cell interactions. (Likely in next release.) + ++ Add a new standard phenotype function that uses mechanobiology, + where high pressure can arrest cycle progression. + (See https://twitter.com/MathCancer/status/1022555441518338048.) + (Likely in next release.) + ++ Add module for standardized pharmacodynamics, as prototyped in the + nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as + an optional standard module in ./modules (but not as a core component) + +======================================================================= + +PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.3.2 +Release date: 24 August 2018 + +Release summary: + +This release fixes a small gradient bug that I swear I had fixed before. + +NOTE: OSX users must now define PHYSICELL_CPP system variable. + See the documentation. + +Major new features and changes: + ++ none + +Minor new features and changes: + ++ none + +Beta features (not fully supported): + ++ none + +Bugfixes: + ++ In BioFVM, Microenvironment::compute_gradient_vector(int), removed "static" + from "static std::vector indices(3,0)" to prevent rare segfaults. + ++ In BioFVM, Microenvironment::compute_gradient_vector(int), replaced "static" + for "bool gradient_constants_defined = false". Yep, I removed static from + the wrong line in 1.3.1 + ++ Correct some errors in both the README.txt and changes.txt files. + +Notices for intended changes that may affect backwards compatibility: + ++ None. + +Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models + (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions + for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code + (See https://doi.org/10.1101/267070.) + ++ Develop contact-based cell-cell interactions. (Likely in next release.) + ++ Add a new standard phenotype function that uses mechanobiology, + where high pressure can arrest cycle progression. + (See https://twitter.com/MathCancer/status/1022555441518338048.) + (Likely in next release.) + ++ Add module for standardized pharmacodynamics, as prototyped in the + nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as + an optional standard module in ./modules (but not as a core component) + +======================================================================= + +PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.3.1 +Release date: 31 July 2018 + +Release summary: + +This release introduces a new cycle model with an active cycling +state and a quiescent state. It also adds new functions to the +Mechanics class to make it easier to modify the cell-cell interaction +distance (while maintaining equilibrium cell-cell spacing), or +to modify the equilibrium cell-cell spacing. The release also +includes major reliability and performance improvements to +how gradients are calculated. + +As usual, the release also contains minor bugfixes and +improvements. + +NOTE: OSX users must now define PHYSICELL_CPP system variable. + See the documentation. + +Major new features and changes: + ++ Implemented a new cell cycle model (cycling_quiescent), + where quiescent cells can enter a cycling state. This + model uses identical parameters to the Ki67-basic cycle + model, but decouples the conceptual model from Ki67 + immunohistochemistry. + + Updated the documentation and coloring functions accordingly. + + Updated update_cell_and_death_parameters_O2_based() to + support the new cycling_quiescent cycle model. + ++ update_all_cells(t,dt,dt,dt) now checks to see if gradient + calculations are enabled, and if so, computes it once per dt_mechanics. + + This improves code performance by 2x to 3x in gradient-enabled codes, + because we no longer need to calculate gradients once per dt_diffusion + time step. (Gradients are only needed for cell velocity calculations, + and occasionally for phenotype decisions.) + + All sample projects have been updated to make use of this. + + Also, removed the explicit gradient calculations from the template + and sample projects. + ++ Added a new function to Mechanics class to simplify changes to cell + interaction distances: + + void set_relative_maximum_adhesion_distance( double new_value ); + + Here, new_value is a multiple of the cell's (mean equivalent) radius. + Our default is 1.25. This function preserves the cell's "repulsion" + strength and adjusts the strength of cell-cell adhesion to maintain + its prior equilibrium cell-cell spacing. + ++ Added a new function to Mechanics class to simplify changes to cell + equilibrium distances. + + void set_relative_equilibrium_distance( double new_value ); + + Here, new_value is a multiple of the cell's (mean equivalent) radius. + The default is around 1.9. This function preserves the cell's "repulsion" + and the maximum interaction distance, and it adjusts the strength of + cell-cell adhesion to match the new equilibrium cell-cell spacing. + + Note that this function performs a "sanity check" to ensure that you have + not given a value greater than 2.0. + ++ Added a new function to Mechanics class to simplify changes to cell + equilibrium distances. + + void Mechanics::set_absolute_equilibrium_distance( Phenotype& phenotype, + double new_value ) + + Here, new_value is the new equilibrium spacing (in units of microns). + The function internally requires the cell's mean equivalent radius, + and so you pass the cell's phenotype (by reference) as an additional + argument. + + Note that this function performs a "sanity check" to ensure that you have + not given a value greater than 2.0 * mean_cell_radius. + + Also note that PhysiCell internally uses a relative spacing, so the + absolute spacing will change from the value you set, over time. + ++ Updated User_Guide to reflect new cell cycle model, + including reference parameters chosen for consistency with + the other cycle models. + +Minor new features and changes: + ++ Added the following constants to support the new cycle model + + static const int cycling = 17; + static const int quiescent = 18; + static const int cycling_quiescent_model = 7; + ++ Added new coloring function: false_cell_coloring_cycling_quiescent + ++ Removed the (never-used) Mechanics.maximum_adhesion_distance. + ++ Removed the legacy template_projects folder. + +Beta features (not fully supported): + ++ Added a function pointer to the Cell_Functions class for intended + contact-based cell-cell interaction, like delta-Notch signaling. + + void (*contact_function)(Cell* pMyself, Phenotype& my_phenotype, + Cell* pOther, Phenotype& other_phenotype, double dt ); + + It would be up to the user to define these functions and decide + if the functions modify pMyself, pOther, or both. For now, + the code will initialize the pointer to NULL and won't use it. + ++ Open to comments on handling cell-cell contact functions. Here's what + I have in mind: + + notation: cell i interacts with cell j with function f(i,j). + + Each cell agent can hold one contact-based interaction function f, + to be stored as a pointer in the cell's instance of the Cell_Functions + class. + + We use the containers (and their interaction testing structures) to + identify all interactions (i,j,f), and add it to a vector of interactions. + The interaction (i,j,f) is added to the list so long as (j,i,f) is not + already in the list, to avoid double-counting the interaction. + + The code will seek through the "container" interaction testing + data structure, probably at the cell mechanics time scale, and update / + recreate the vector of contact-based interactions (i,j,f). + + The code would likely go through the vector of interactions and + execute the codes once per dt_diffusion time step, since I would + imagine molecular biology (with faster time scales) is intended here. + + Since f(i,j) can potentially modify both cell i and cell j, it's probably + not thread-safe. So we'll probably need that in a non-parallel loop. + + We will probably add a new time scale for interactions, dt_interactions, + and update the interaction list on that time scale. + + For faster checking if (i,j,f) or (j,i,f) is already in the vector, + we'll probably want some sort of hash map in addition to the vector + of interactions. + + We'll probably implement this all in something like + PhysiCell_contact_interctions.*, and add a global enable/disable option. + I'd imagine we'd add code to the "update_all_cells" to keep this + as simple to the users as possible. + + We should probably update each cell's "neighbors" data structure at + when we're doing all this testing. + + In a longer-term update, we could leverage that for simpler interaction + testing during velocity updates. + +Bugfixes: + ++ Added missing "omp_set_num_threads(PhysiCell_settings.omp_num_threads)" + in the main-heterogeneity.cpp file for the heterogeneity sample project. + ++ In BioFVM, Microenvironment::compute_gradient_vector(int), removed "static" + from "static std::vector indices(3,0)" to prevent rare segfaults. + ++ Changed root above the comment lines in output files for + better Python parsing compatibility. Thanks, rheiland! + ++ MultiCellDS outputs used size 3 for all custom vector variables, instead + of actual size. Fixed to read the size from the vector. + ++ Fixed the ostream operator for Vector_Variable to correctly output all + the vector.value elements, rather than the original hard-coded output + of 3 elements regardless of size. + +Notices for intended changes that may affect backwards compatibility: + ++ None + +Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models + (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions + for molecular-scale modeling + ++ integrate Boolean network support from PhysiBoSS into the mainline code + (See https://doi.org/10.1101/267070.) + ++ Develop contact-based cell-cell interactions. (Likely in next release.) + ++ Add a new standard phenotype function that uses mechanobiology, + where high pressure can arrest cycle progression. + (See https://twitter.com/MathCancer/status/1022555441518338048.) + (Likely in next release.) + ++ Add module for standardized pharmacodynamics, as prototyped in the + nanobio project. (See https://nanohub.org/resources/pc4nanobio.) + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as + an optional standard module in ./modules (but not as a core component) + +======================================================================= + +PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.3.0 +Release date: 23 February 2018 + +Overview: +PhysiCell is a flexible open source framework for building +agent-based multicellular models in 3-D tissue environments. + +Reference: A Ghaffarizadeh, R Heiland, SH Friedman, + SM Mumenthaler, and P Macklin, PhysiCell: an Open Source + Physics-Based Cell Simulator for Multicellular Systems, + PLoS Comput. Biol. 14(2): e1005991, 2018. + DOI: 10.1371/journal.pcbi.1005991 + +Visit http://MathCancer.org/blog for the latest tutorials and help. + +Release summary: +This release introduces two new cell cycle models (G0/G1 -> +S -> G2/M) and (G0/G1 -> S -> G2 -> M), introduces XML-based +configuration files, and allows new user control on how +often and where data are stored. + +As usual, the release also contains minor bugfixes and +improvements. + +NOTE: OSX users must now define PHYSICELL_CPP system variable. + See the documentation. + +Major new features and changes: ++ implemented new cell cycle models: + + flow_cytometry_cycle_model: G0/G1 -> S -> G2/M + flow_cytometry_separated_cycle_model: G0/G1 -> S -> G2 -> M + + along with documentation and updated coloring functions + ++ The oxygen-based phenotype models now support the new cycle + model. + ++ Added XML file parsing for use in settings files. + ++ XML configuration file (in ./config/PhysiCell_settings.xml) + sets data destination (as a subfolder) and save + frequency. Legacy saves are now off by default. + ++ Users can select a different XML file at command line + + ./project_name settings_file.xml + + (Assuming you preserved the structure of the template + projects.) + ++ Updated User_Guide to reflect new XML parsing capabilities. + ++ Updated User_Guide to reflect new cell cycle models, + including reference parameters chosen for consistency with + the other cycle models. + +Minor new features and changes: ++ Added PhysiCell_pugixml.* for easier extraction of parameter + arguments from XML files + ++ Added PhysiCell_settings.* to include parsing of XML parameter + files, and parameter values stored in a unified data structure. + ++ Added parsing of settings file to separately set frequency of + saving full output (MultiCellDS), SVG outputs, and "legacy" + outputs from USC era. + ++ Added options to specify the folder of saved data. + ++ Added option to read the number of OMP threads from a setting file. + ++ Added "beta" directory where we will put new features that are still + undergoing testing + ++ Minor updates to the Quickstart guide. + ++ Added new function: to display the simulation status: + + void display_simulation_status( std::ostream& os ); + + e.g., display_simulation_status( std::cout ); + ++ writePov() uses a user-specified output folder. + ++ log_output() uses a user-specified output folder. + ++ added "beta-testing" sample project. Populate it by the rule: + make beta-testing + ++ added flow_cytometry_separated_cycle_model to the PhysiCell constants. + ++ added G1pm_phase and G1ps_phase to the PhysiCell constants. + ++ Added new coloring function: false_cell_coloring_cytometry + ++ added support for the new cytometry cycle models to the oxygen-based + phenotype model (update_cell_and_death_parameters_O2_based) + ++ updated user manual to reflect new cytometry models + ++ updated template2D and template3D projects to use to use the + new cytometry models and coloring schemes. Also reduced to + 1 mm x 1 mm (2D) and 1 mm^3 (3D) for faster demos. + ++ removed archives directory + +Beta features (not fully supported): + ++ XML functions moved from beta to production. + +Bugfixes: + ++ Changed instances of uniform_random() (from BioFVM) to + UniformRandom() (from PhysiCell) so that all calls to the PRNG + used the same random seed and same PRNG. Thanks, olliemcdonald! + ++ Fixed typo in "Dirichlet" in user documentation. Thanks, luissv7! + ++ Removed .git directory that was accidentally included in releases + ++ Updated PhysiCell_MultiCellDS.cpp + (add_PhysiCell_cells_to_open_xml_pugi) so that we exit(-1) with a + meaningful error message if we cannot open a matlab subfile + for writing. + ++ Updated PhysiCell_pathology.cpp (SVG_plot) so that we exit(-1) + with a meaningful error message if we cannot open an SVG file + for writing. + +Notices for intended changes that may affect backwards compatibility: + ++ template_projects folder will be removed + +Planned future improvements: + ++ Further XML-based simulation setup. + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models + (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions + for molecular-scale modeling + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as + an optional standard module in ./modules (but not as a core component) + +======================================================================= + +PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.2.2 +Release date: 4 November 2017 + +Overview: +PhysiCell is a flexible open source framework for building +agent-based multicellular models in 3-D tissue environments. + +Reference: Ghaffarizadeh et al., PLoS Comput Biol (2017) + preprint URL: https://doi.org/10.1101/088773 + +Visit http://MathCancer.org/blog for the latest tutorials and help. + +Key makefile rules: + +make : compiles the current project. If no + project has been defined, it first + populates the cancer heterogeneity 2D + sample project and compiles it + +make : populates the indicated sample project. + Use "make" to compile it. + + choices: + template2D + template3D + biorobots-sample + cancer-biorobots-sample + heterogeneity-sample + cancer-immune-sample + +make clean : removes all .o files and the executable, so that + the next "make" recompiles the entire project + +make data-cleanup : clears out all simulation data + +make reset : de-populates the sample project and returns to + the original PhysiCell state. Use this when + switching to a new PhysiCell sample project. + + +Homepage: http://PhysiCell.MathCancer.org +Downloads: http://PhysiCell.sf.net +Support: https://sourceforge.net/p/physicell/tickets/ + +Quick Start: Look at QuickStart.pdf in the documentation folder. +User Guide: Look at UserGuide.pdf in the documentation folder. + +Tutorials: http://www.mathcancer.org/blog/physicell-tutorials/ + +Latest info: follow @MathCancer on Twitter (http://twitter.com/MathCancer) + +See changes.txt for the full change log. + +Release summary: +This release reduces the complexity of Makefiles (especially for +OSX users), restructures the 2D and 3D project templates as +sample projects, fixes a minor bug in SVG pathology outputs, +improves copying of Cell_Definitions, and fixes minor bugs in +BioFVM (primarily related to Dirichlet conditions). + +NOTE: OSX users must now define PHYSICELL_CPP system variable. + See the documentation. + +PhysiCell is currently under scientific peer review. + +Major new features and changes: ++ none + +Minor new features and changes: ++ Restructured the 2D template project to have the same structure as a + typical project, with setup functions related functions in + ./custom_modules/*, etc. Moved it to ./sample_projects/template2D/ + ./template_projects/ will be deprecated. + + To populate this project, use: + + make template2D + + To compile: + + make + + To de-populate the sample project and return to the "clean"PhysiCell state: + + make reset + make clean (to remove object files) + ++ Restructured the 3D template project to have the same structure as a + typical project, with setup functions related functions in + ./custom_modules/*, etc. Moved it to ./sample_projects/template3D/ + ./template_projects/ will be deprecated. + + To populate this project, use: + + make template3D + + To compile: + + make + + To de-populate the sample project and return to the "clean"PhysiCell state: + + make reset + make clean (to remove object files) + ++ Simplified Makefiles: populating a sample project and compiling it + + make + + To compile: + + make + + To reset to original state: + + make reset + + Current values: + template2D + template3D + biorobots-sample + cancer-biorobots-sample + heterogeneity-sample + cancer-immune-sample + ++ Simplified Makefiles: Makefiles check for system variable + PHYSICELL_CPP to set the compiler (CC). OSX users must set + this environment variables. See the online tutorials and the + user guide. + ++ Simplified Makefiles: "make data-cleanup" removes .svg, .mat, .xml, and + data inside ./data + ++ Updated documentation on how to add new substrates. + ++ Updated documentation on applying Dirichlet conditions to only + specific substrates. + ++ Added new function to copy the properties of a Cell Definition to + the cell. + + void Cell::convert_to_cell_definition( Cell_Definition& cd ) + +Bugfixes: + ++ Fixed a small error in SVG plots, where tissues were flipped with + y was vertically flipped. + ++ Used register_microenvironment(Microenvironment*) to improve + compatibiltiy with other operating systems and compilers. + ++ Added copy constructor and copy assignnment functions to the + Cell_Definition is. + ++ Removed the unnecessary "wha???" from BioFVM_microenvironment.cpp. + ++ Updated Dirichlet_condition_vector = ones (instead of zeros) in + Microenvironment_Options::Microenvironment_Options() default + constructor. + ++ Microenvironment::resize_densities( int new_size ) no longer + overwrites previous dirichlet values when extending the size. + ++ No longer overwrites existing Dirichlet_condition_vector elements + or set default_microenvironment_options.use_oxygen_as_first_field + to false. + ++ Microenvironment::set_density(int,std::string,std::string) and + Microenvironment::set_density(int,std::string,std::string,double,double) + were modified to be compatibility. + ++ Only set default_microenvironment_options.use_oxygen_as_first_field = false + if index = 0, when samplign the oxygen. + ++ Updated save_PhysiCell_to_MultiCellDS_xml_pugi() to save much more + phenotype information and all custom variables for each cell. + ++ Updated read_MultiCellDS_XML.m (in ./matlab) to read these + newly expanded data files. + ++ Includes a sneak preview of BioFVM 1.1.7, which includes bugfixes + mentioned above. + +Notices for intended changes that may affect backwards compatibility: + ++ None at this time + +Planned future improvements: + ++ parse XML configuration files + ++ read saved simulation states (as MultiCellDS digital snapshots) + ++ "mainline" prototype cell attach/detach mechanics as standard models + (currently in the biorobots and immune examples) + ++ integrate SBML-encoded systems of ODEs as custom data and functions + for molecular-scale modeling + ++ create an angiogenesis sample project + ++ create a small library of angiogenesis and vascularization codes as + an optional standard module in ./modules (but not as a core component) + +======================================================================= + +PhysiCell: PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.2.1 +Release date: 1 September 2017 + +Homepage: http://PhysiCell.MathCancer.org +Downloads: http://PhysiCell.sf.net + +Release summary: +This release introduces a improved MultiCellDS outputs, new matlab +functions to read the MultiCellDS outputs, experimental functions +for povray routines (for 3-D raytracing), some bugfixes, and +new sample projects in cancer heterogeneity, synthetic multicellular +bioengineering, and cancer immunology. + +PhysiCell is currently under scientific peer review. + +Major new features and changes: ++ Updated save_PhysiCell_to_MultiCellDS_xml_pugi() to save much more + phenotype information and all custom variables for each cell. + ++ Updated read_MultiCellDS_XML.m (in ./matlab) to read these + newly expanded data files. + ++ Included new matlab functions for fast 3-D data exploration: + + simple_plot.m -- quickly plots (as a surface) all the cells + simple_cutaway_plot.m -- same as above, but with a cutaway view + composite_cutaway_plot.m -- plots cutaway view of live and dead + cells, colored separately. + ++ Wrote new POV-ray functions for future raytracing utilities. See + ./modules/PhysiCell_POV.* + ++ Add the following new sample projects: + + biorobots: simulates a system of director, worker, and cargo + cells that coordinate to deliver cellular cargo to the + directors. Uses motility, custom mechanics, and other functions. + + build via: make biorobots-sample && make project + + cancer biorobots: modifies the above project so that worker + cells take cargo to hypoxic tumor regions. cargo cells + release a drug once they are detached from worker cells. + tumor cells have a damage and apoptosis model. + + build via: make cancer-biorobots-sample && make project + + heterogeneity: simulates proliferation of a heterogeneous + tumor. Note the loss of symmetry and selection/evolution. + + build via: make heterogeneity-sample && make project + + cancer immunology: simulates an immune system attack on a + tumor with heterogeneous proliferation and immunogenicity + characteristics. In 3D! + + build via: make cancer-immune-sample && make project + +Minor new features and changes: + ++ Added double NormalRandom( double mean, double standard_deviation ) + to PhysiCell_utilities.* This will generate normally-distributed + random numbers. + ++ Includes a sneak preview of BioFVM 1.1.7, which includes bugfixes on + how boundary conditions were initialized. + +bugfixes: + ++ Removed annoying "cout" lines in: + + void standard_live_phase_entry_function(Cell*,Phenotype&,double). + + They were leftover from debugging. Sorry! + ++ In the templates, we updated to: + + while( t < t_max + 0.1*diffusion_dt ) + { + + so that the simulations run all the way to the final time, + instead of exiting too early by dt time. + ++ Fixed a bug in Motility::Motility() where the migration bias was + initialized to (1,0,0). + ++ Made adhesion and repulsion symmetric across cells (in add_potentials) + ++ got rid of debug_temp_a in (in add_potentials) + ++ if default_microenvironment_options.simulate_2D == true, we now + set velocity[2] = 0.0 in the velocity functions. + +======================================================================= + +Version: 1.2.0 +Release date: 30 July 2017 + +Homepage: http://PhysiCell.MathCancer.org +Downloads: http://PhysiCell.sf.net + +Release summary: +This release introduces a major reworking to simplify cell pheno- +types and cells. It includes a generalized cell cycle model that +can also be used to represent death cycle models. It includes an +improved motility representation. Changing cell secretion and +uptake rates is more straightforward, because all interfacing +with BioFVM is automated. + +A new, comprehensive user guide is included on all the major +functions and classes in PhysiCell, including examples. + +This release also includes bugfixes and corrections. Due +to the extensive redevelopment, this change log is not 100% +fine-grained. + +PhysiCell is currently under scientific peer review. + +Major new features and changes: ++ Completely reworked the Phenoytype class to be much more + straightforward, and safe to change throughout the + simulation. + ++ The Phenotype class includes elements on cell cycling, death, + volume, geometry, mechanics, motility, and secretion (and uptake). + ++ Completely reworked representation of cell cycle models as + Cycle_Model: a directed graph of Phases, linked by Phase_Links. + A Cycle_Model is bundled with key parameters (Cycle_Data) into + the Cycle element of the Phenotype. + ++ Cycle models can include user-specified arrest functions between + Phases (e.g., contact inhibition). + ++ Cycle Phases can have user-specified "entry" and "exit" functions + to be executed upon entering or leaving a Phase (e.g., mutations). + ++ Created new classes Death_Parameters and Death to represent + cell death models as Cycle_Model. + ++ Updated the classes for Mechanics, Volume, and Geometry. + ++ Completely reworked the Motility class to represent cell + migration as a combination of random and directed motility. + Notions of persistence time are included. Users can supply + custom functions to update the cell's migration bias. + ++ Added the cell calcification model to the general volume update + function. + ++ Deprecated all code in core/PhysiCell_digital_cell_line.* + ++ Added apoptosis_death_model, necrosis_death_model, + autophagy_death_model, and live_cells_cycle_model to + PhysiCell_Constants. + ++ Added new function Cell::flag_for_division() for simpler + construction of cycle models, and to allow users to push a cell + to divide at any time. + ++ Added new function Cell::flag_for_removal() for simpler + construction of cycle models, and to allow users to push a cell + to be removed at any time. + ++ Volume::multiply_by_ratio() now also divides the target volumes by + this ratio. + ++ Created a new Cell_Functions class to more readily bundle the + Cell object's function pointers. + ++ Rewrote the Custom_Cell_Data class, so that custom data are no + longer hard-coded by the user in the class, but instead added + during runtime. Moved PhysiCell_custom.h/cpp into the core + directory. + ++ The Cell_Definition class includes a pointer to the default + Microenvironment, as well as a default Cell_Functions, + Cell_Parameters, Custom_Cell_Data, and Phenotype. Newly created + cells all copy from the Cell_Defaults. + ++ Bundled the following phenotype update functions into a single + Phenotype::advance_all_nonmechanics_models( Cell* , double ) + function: + Phenotype::update_function() // update cell phenotype parameters + Phenotype::volume.update() // update cell volume + Phenotype::geometry.update() // update radius, etc. + Phenotype::death.check_for_death() // check for death + Phenotype::cycle.advance_cycle() // advance the current cycle model + ++ PhysiCell_Container uses the above function on each cell to + ensure that the correct custom functions are used. It also uses + the cell's Cell::Cell_Functions::update_velocity() to update + the cell's state. For now, users need to remember to include + the motility update functions in their update_velocity() function + if they replace the default. Lastly, PhysiCell_Container calls teh + Cell::Cell_Functions::custom_cell_rule at the end of the main loop. + ++ Created new functions to directly trigger cell death. + ++ Created new functions to access cell neighbor information. + ++ Updated the examples for compatibility. + +Minor new features and changes: ++ Added PhysiCell_constants::custom_phase to the constants. + ++ Changed Cell:is_movable to Cell_is_movable to better express its + purpose of setting a cell to rigid (unmovable) or movable. + ++ Fixed Cell:turn_off_reactions(double) to completely turn off all + BioFVM uptake/secretion, rather than cut them by an order of + magnitude. + ++ Replaced scores of (if some_double == 0) conditionals with + if( fabs( some_double ) < tolerance ), since you it is best practice + to never check for equality of a floating point or double. + ++ Started substituting more efficient axpy and += operators + (from BioFVM) for many of the vector operations in PhysiCell_cell.cpp. + ++ Where possible, inserted { } into if / then / else logic for + increased code clarity and robustness to newline and whitespace + changes. + ++ Moved most default / standard mechanics functions from PhysiCell_cell.* to + PhysiCell_standard_models.*. + ++ Added constants for time step sizes, time units, and spatial units to + PhysiCell_constants.h, and removed isolated (and sometimes non- + synchronized) timestep constants throughout the code. + ++ Added State::simple_pressure for future use in mechanics-induced cycle + regulation. + ++ Added std::vector& Cell:cells_in_my_container(void) to more + easily access a list of cells in the cell's current mechanics voxel. + ++ and more. + ++ Simplified the Makefile for easier cross-platform compiling. Users + do not need to change MARCH any more. + +Bugfixes and Corrections: + ++ Fixed typo "max_cell_interactive_ditstance_in_voxel" to + "max_cell_interactive_ditstance_in_voxel" in the Cell_Container class. + ++ Throughout the code, replaced any logic of the form + (if some_double == some_other_double ) with better practice of + if( fabs( some_double - some_other_double ) < tolerance ), since + floating point numbers aren't often equal. + ++ In PhysiCell_cell_container, the function find_escaping_face_index() + had a return type of int, but it was possible for none of the statements + to evaulate "true". The function now returns -1 for the case that + there is no escaping_face_index. Thus, the return type is always defined. + ++ Cell::assign_position() now sets: + is_out_of_domain = true; + is_active = false; + is_movable = false; + if the cell is out of bounds. This should prevent segfaults when cells + are assigned positions out of bounds (e.g., during division). + ++ Cell::update_position() now sets: + is_out_of_domain = true; + is_active = false; + is_movable = false; + if the cell moves out of bounds. This should prevent segfaults when cells + move out of bounds (e.g., by mechanics). + +======================================================================= + +Version: 1.1.1 +Release date: 16 May 2017 + +Homepage: http://PhysiCell.MathCancer.org +Downloads: http://PhysiCell.sf.net + +Release summary: +This release includes usability fixes and enhancements, including +more basic "template" projects, simpler project startup, improved SVG +visualization support, and cleanup on the Makefile. + +PhysiCell is currently under scientific peer review. + +Major new features and changes: ++ Added template3D.cpp and template2D.cpp template projects. See the + template_projects directory. + ++ Added Makefile rules to seed the 2D projects. To create and compile + the 2D template: + make template2D && make + To create and compile the 3D template: + make template3D && make + + To further edit your project, modify main.cpp in the root PhysiCell + directory. Follow the online tutorials for further functionality. + ++ Added preliminary MultiCellDS support, with MultiCellDS outputs. These + are added via modules/PhysiCell_MultiCellDS.cpp + ++ Many usability improvements listed in "minor new features" below. + ++ Finished implementation of SVG support, to plot the simulation through a + cross-section (fixed z-value). + ++ Digital pathology: Improved coloring functions for the main cell cycle + models, and virtual H&E (hematoxylin and eosin): + +Minor new features and changes: ++ Created new function in PhysiCell_cell_container to simplify initialization + of the mechanics data structures: + + Cell_Container* create_cell_container_for_microenvironment( + BioFVM::Microenvironment& m , double mechanics_voxel_size ); + ++ Usability feature: If BioFVM::default_microenvironment has not yet been + declared when calling create_cell_container_for_microenvironment(), then + it is set to "m" in the new function above. + ++ Usability feature: If the BioFVM::default_microenvironment has been set + then Cell* create_cell( void ) now uses this to call + Cell::register_microenvironment(µenvironment). + ++ Changed Cell_Parameters from a struct to a class. + ++ Usability feature: Created a new Cell_Defaults class, with a + global PhysiCell::cell_defaults. Now, you can set these + default functions and parameters at the start of your program, and + all new cells are set to use these defaults. + ++ Usability feature: Traced code and determined that calling Cell::set_phenotype() + calls Basic_Agent::set_total_volume() (Cell extends Basic_Agent), which sets + Basic_Agent::volume_is_changed to true. This, in turn, makes the next call + to Basic_Agent::simulate_secretion_and_uptake() call + Basic_Agent::set_internal_uptake_constants(). So, it is unnecessary to + call this function in typical initialization. + ++ Usability feature: Cell:set_phenotype() now automatically calls + Basic_Agent::set_internal_uptake_constants(). You no longer need to + manually call this function *if* using the set_phenotype() function. + ++ Usability feature: The default Cell constructor (Cell::Cell) uses + the default functions in PhysiCell::default_cell_functions, instead + of hard-coded defaults. The default constructor for Default_Cell_Functions + has sensible defaults for cell mechanics and volume regulation to + match the PhysiCell method paper. Phenotype-related functions are left + empty. + ++ Usability feature: The create_cell() function now assigns the default + microenvironment to the newly created cell, and assigns the + cell functions in PhysiCell::default_cell_functions. + ++ Changed default -march flag to -march=native, according to benchmarks + on gcc 5x at phoronix: + http://www.phoronix.com/scan.php?page=news_item&px=GCC-Optimizations-E3V5-Levels + ++ Changed the -O3 flag to -Ofast, which tends to produce slightly faster + code by the phoronix link above. + ++ Updated to a pre-release copy of BioFVM 1.1.6. + ++ Included the matlab functions first created for BioFVM, which can now be + found in the matlab directory. + ++ Fixed read_MultiCellDS_xml.m function to work when there are no cells. + ++ Fixed read_MultiCellDS_xml.m function to display the current number of + cells, when there are < 3 cells. + ++ Added modules/PhysiCell_standard_modules.h to start organizing non-core, + standard parts of MultiCellDS. This will inintially include SVG, + pathology, and MultiCellDS modules. + ++ Removed matlab output from log_output in PhysiCell_utilities.cpp. This + only saved the microenvironment (but not cells), and it is no longer + needed with new MultiCellDS output support. + ++ Changed the default SVG length scale bar in PhysiCell_pathology to + 100 microns (previously 1000 microns). + ++ Updated the archive rules to use the more-common "tar" command. Use + "make tar" and "make untar". Archives are stored in the archives + directory. + ++ Added a void up_orientation( Cell* pCell, double dt ) to + PhysiCell_standard_models.cpp, which sets orientation = [0,0,1] + and polarity = 1.0. This is useful for 2-D simulations. + ++ Digital Pathology coloring functions: + simple_cell_coloring: cell nucleus is blue, cytoplasm is red, and + outlines are black + + false_cell_coloring_Ki67: for any Ki67-based cell cycle model, + green cells are Ki67+ prior to mitosis (or any Ki67+ cell in + the simplified Ki67 models), magenta cells are Ki67+ after + mitosis, red cells are apoptotic, and brown cells are necrotic. + + hematoxylin_and_eosin_cell_coloring: "stains" nuclear solids with + hematoxylin, "stains" cytoplasmic solids with eosin, and simulates + light transmission / absorbtion through a thin slice to approximate + microscopy and image acquisition. Note that cells with little water + will appear dark (e.g., apoptotic debris, especially after the + cytoplasm has blebbed), and cells with lots of water (e.g., onsosis + in early necrotic cells) will appear faint. + + false_cell_coloring_live_dead: live cells are green, apoptotic cells + are red, and necrotic cells are brown. + ++ Added Phenotype::get_current_phase_code(void) to + PhysiCell_digital_cell_line.cpp to more easily get the cell's current + phenotypic state. (Especially useful for virtual pathology.) + +Bugfixes and Corrections: ++ Fixed typo Time_Settings.cell_cylce_dt_default to + Time_Settings.cell_cycle_dt_default in PhysiCell_cell_container. + ++ Removed unused declaration Cell::initialize_functions( void ); + ++ Changed the default "update_cell_and_death_parameters" function from + "update_cell_and_death_parameters_O2_based" to "empty_function". + Examples and models should choose this *explicitly*. + ++ Cell::set_orientation( Cell* pCell ) changed to + Cell::set_orientation( Cell* pCell, double dt ) to be consistent with other + cell member functions. + ++ In void Cell::assign_orientation(), set polarity = 0.0 if a + set_orientation(Cell*,double) function is not set (NULL). + ++ Removed irrelevant data elements in the Custom_Cell_Data class. + +Notices for intended changes that may affect backwards compatibility: + ++ Will rename the current "Phenotype" class to "Old_Phenotype" + ++ Will introduce a new Phenotype class with a much simpler structure. + ++ Will rewrite the represetation of cell cycle and death phases. + ++ Will rewrite the standard phenotype models in the simpler representatio. + ++ Will stop requiring use of the Digital_Cell_Line class for initializing + simulations. + ++ Will deprecate update_cell_and_death_parameters, and instead use + update_phenotype_parameters. + ++ Will stop using the oxygen-dependent phenotype rule as default. + +PhysiCell 1.1.1 includes an advance copy of BioFVM 1.1.6. Here are the changes: + +/* fixes and changes in BioFVM 1.1.6 */ + ++ correct typos in citation information in all source files + ++ updated citation information + ++ added void set_default_microenvironment( Microenvironment* M ) declaration to + BioFVM_Microenvironment.h + ++ set volume_is_changed = false in Basic_Agent::set_internal_uptake_constants(); + ++ Set the MultiCellDS options Booleans to extern bool in BioFVM_MultiCellDS.h + so that PhysiCell can read these options. + ++ Updated the simlified_data field in MultiCellDS XML output to include a + new "source" attribute with value "BioFVM". + ++ Added Microenvironment::find_substrate_index( std::string ) to make it + easier to find . + ++ Added Basic_Agent::nearest_gradient( int substrate_index ) to directly + access the gradient of the indicated substrate at the agent's + current_voxel_index. + ++ Added Basic_Agent::nearest_gradient_vector( void ) to directly + access a vector of gradients (one for each substrate in the + microenvironment) at the agent's current_voxel_index. + ++ Added Microenvironment::is_dirichlet_node( int voxel_index ) to + easily check if the voxel is a Dirichlet node. + ++ Updated Microenvironment::update_dirichlet_node() and + Microenvironment::remove_dirichlet_node() to check against + mesh.voxels[].is_Dirichlet to provide a cheap and early exit + if the node isn't Dirichlet in the first place. + ++ Changed to a thread-safe data structure for Dirichlet nodes + (e.g., if a custom cell function in an OMP loop adds or removes + Dirichlet nodes). + ++ Added new class Microenvironment_Options, with a default + default_microenvironment_options, to simplify Microenvironment + setup. The defaults are dx = dy = dz = 20 microns, on 1 cubic mm. + ++ Added function initialize_microenvironment() to set up the + microenvironment using the options in + default_microenvironment_options. The code sets oxygen as the + default field, with D = 1e5 micron^2/min, and decay rate = 0.1 1/min + (a 1 mm diffusion length scale). If + default_microenvironment_options.outer_Dirichlet_conditions = true, + then we set a 38 mmHg condition on the outer edges, corresponding to + 5% oxygenation (physioxic conditions). + +======================================================================= + +PhysiCell: PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.1.0 +Release date: 16 May 2017 + +Homepage: http://PhysiCell.MathCancer.org +Downloads: http://PhysiCell.sf.net + +Release summary: +This release includes usability fixes and enhancements, including +more basic "template" projects, simpler project startup, improved SVG +visualization support, and cleanup on the Makefile. + +PhysiCell is currently under scientific peer review. + +Major new features and changes: ++ Added template3D.cpp and template2D.cpp template projects. See the + template_projects directory. + ++ Added Makefile rules to seed the 2D projects. To create and compile + the 2D template: + make template2D && make + To create and compile the 3D template: + make template3D && make + + To further edit your project, modify main.cpp in the root PhysiCell + directory. Follow the online tutorials for further functionality. + ++ Added preliminary MultiCellDS support, with MultiCellDS outputs. These + are added via modules/PhysiCell_MultiCellDS.cpp + ++ Many usability improvements listed in "minor new features" below. + ++ Finished implementation of SVG support, to plot the simulation through a + cross-section (fixed z-value). + ++ Digital pathology: Improved coloring functions for the main cell cycle + models, and virtual H&E (hematoxylin and eosin): + +Minor new features and changes: ++ Created new function in PhysiCell_cell_container to simplify initialization + of the mechanics data structures: + + Cell_Container* create_cell_container_for_microenvironment( + BioFVM::Microenvironment& m , double mechanics_voxel_size ); + ++ Usability feature: If BioFVM::default_microenvironment has not yet been + declared when calling create_cell_container_for_microenvironment(), then + it is set to "m" in the new function above. + ++ Usability feature: If the BioFVM::default_microenvironment has been set + then Cell* create_cell( void ) now uses this to call + Cell::register_microenvironment(µenvironment). + ++ Changed Cell_Parameters from a struct to a class. + ++ Usability feature: Created a new Cell_Defaults class, with a + global PhysiCell::cell_defaults. Now, you can set these + default functions and parameters at the start of your program, and + all new cells are set to use these defaults. + ++ Usability feature: Traced code and determined that calling Cell::set_phenotype() + calls Basic_Agent::set_total_volume() (Cell extends Basic_Agent), which sets + Basic_Agent::volume_is_changed to true. This, in turn, makes the next call + to Basic_Agent::simulate_secretion_and_uptake() call + Basic_Agent::set_internal_uptake_constants(). So, it is unnecessary to + call this function in typical initialization. + ++ Usability feature: Cell:set_phenotype() now automatically calls + Basic_Agent::set_internal_uptake_constants(). You no longer need to + manually call this function *if* using the set_phenotype() function. + ++ Usability feature: The default Cell constructor (Cell::Cell) uses + the default functions in PhysiCell::default_cell_functions, instead + of hard-coded defaults. The default constructor for Default_Cell_Functions + has sensible defaults for cell mechanics and volume regulation to + match the PhysiCell method paper. Phenotype-related functions are left + empty. + ++ Usability feature: The create_cell() function now assigns the default + microenvironment to the newly created cell, and assigns the + cell functions in PhysiCell::default_cell_functions. + ++ Changed default -march flag to -march=native, according to benchmarks + on gcc 5x at phoronix: + http://www.phoronix.com/scan.php?page=news_item&px=GCC-Optimizations-E3V5-Levels + ++ Changed the -O3 flag to -Ofast, which tends to produce slightly faster + code by the phoronix link above. + ++ Updated to a pre-release copy of BioFVM 1.1.5. + ++ Included the matlab functions first created for BioFVM, which can now be + found in the matlab directory. + ++ Fixed read_MultiCellDS_xml.m function to work when there are no cells. + ++ Fixed read_MultiCellDS_xml.m function to display the current number of + cells, when there are < 3 cells. + ++ Added modules/PhysiCell_standard_modules.h to start organizing non-core, + standard parts of MultiCellDS. This will inintially include SVG, + pathology, and MultiCellDS modules. + ++ Removed matlab output from log_output in PhysiCell_utilities.cpp. This + only saved the microenvironment (but not cells), and it is no longer + needed with new MultiCellDS output support. + ++ Changed the default SVG length scale bar in PhysiCell_pathology to + 100 microns (previously 1000 microns). + ++ Updated the archive rules to use the more-common "tar" command. Use + "make tar" and "make untar". Archives are stored in the archives + directory. + ++ Added a void up_orientation( Cell* pCell, double dt ) to + PhysiCell_standard_models.cpp, which sets orientation = [0,0,1] + and polarity = 1.0. This is useful for 2-D simulations. + ++ Digital Pathology coloring functions: + simple_cell_coloring: cell nucleus is blue, cytoplasm is red, and + outlines are black + + false_cell_coloring_Ki67: for any Ki67-based cell cycle model, + green cells are Ki67+ prior to mitosis (or any Ki67+ cell in + the simplified Ki67 models), magenta cells are Ki67+ after + mitosis, red cells are apoptotic, and brown cells are necrotic. + + hematoxylin_and_eosin_cell_coloring: "stains" nuclear solids with + hematoxylin, "stains" cytoplasmic solids with eosin, and simulates + light transmission / absorbtion through a thin slice to approximate + microscopy and image acquisition. Note that cells with little water + will appear dark (e.g., apoptotic debris, especially after the + cytoplasm has blebbed), and cells with lots of water (e.g., onsosis + in early necrotic cells) will appear faint. + + false_cell_coloring_live_dead: live cells are green, apoptotic cells + are red, and necrotic cells are brown. + ++ Added Phenotype::get_current_phase_code(void) to + PhysiCell_digital_cell_line.cpp to more easily get the cell's current + phenotypic state. (Especially useful for virtual pathology.) + +Bugfixes and Corrections: ++ Fixed typo Time_Settings.cell_cylce_dt_default to + Time_Settings.cell_cycle_dt_default in PhysiCell_cell_container. + ++ Removed unused declaration Cell::initialize_functions( void ); + ++ Changed the default "update_cell_and_death_parameters" function from + "update_cell_and_death_parameters_O2_based" to "empty_function". + Examples and models should choose this *explicitly*. + ++ Cell::set_orientation( Cell* pCell ) changed to + Cell::set_orientation( Cell* pCell, double dt ) to be consistent with other + cell member functions. + ++ In void Cell::assign_orientation(), set polarity = 0.0 if a + set_orientation(Cell*,double) function is not set (NULL). + ++ Removed irrelevant data elements in the Custom_Cell_Data class. + +Notices for intended changes that may affect backwards compatibility: + ++ Will rename the current "Phenotype" class to "Full_Phenotype" + ++ Will introduce a new Phenotype class with a much simpler structure. + ++ Will rewrite the represetation of cell cycle and death phases. + ++ Will rewrite the standard phenotype models in the simpler representatio. + ++ Will stop requiring use of the Digital_Cell_Line class for initializing + simulations. + ++ Will deprecate update_cell_and_death_parameters, and instead use + update_phenotype_parameters. + ++ Will stop using the oxygen-dependent phenotype rule as default. + +PhysiCell 1.1.0 includes an advance copy of BioFVM 1.1.5. Here are the changes: + +/* fixes in BioFVM 1.1.5 */ + ++ correct typos in citation information in all source files + ++ updated citation information + ++ added void set_default_microenvironment( Microenvironment* M ) declaration to + BioFVM_Microenvironment.h + ++ set volume_is_changed = false in Basic_Agent::set_internal_uptake_constants(); + ++ Set the MultiCellDS options Booleans to extern bool in BioFVM_MultiCellDS.h + so that PhysiCell can read these options. + ++ Updated the simlified_data field in MultiCellDS XML output to include a + new "source" attribute with value "BioFVM". + +======================================================================= + +PhysiCell: PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D +Multicellular Systems. + +Version: 1.0.0 +Release date: 12 September 2016 + +Homepage: http://PhysiCell.MathCancer.org +Downloads: http://PhysiCell.sf.net + +Release summary: +This is the initial public release of PhysiCell: an Open Source Physics-Based +Cell Simulator for 3-D Multicellular Systems. It is currently under scientific +peer review. + +Major new features: ++ Simulating large systems of cells in 3-D tissues on desktop machine ++ Cells move and change based on biomechanical and physical rules ++ Built upon BioFVM to couple processes with the substrates' concentrations + in the microenvironment ++ Implements multiple realistic cell cycle and cell death models ++ Performance linearly scales with the number of the cells ++ Preliminary support for MultiCellDS (http://MultiCellDS.org) ++ Includes examples for 3-D ductal carcinoma in situ (DCIS) and hanging + drop tumor spheroids + +Bugfixes: ++ Not applicable. + +======================================================================= + +PhysiCell: an open source physics-based multicell simulator + +Version: 0.5.0 +Release date: 2 Auguust + +Homepage: http://PhysiCell.MathCancer.org +Downloads: http://PhysiCell.sf.net + +Release summary: +Pre-release. Not for public use. Not supported. + +New features: ++ First code bundling. + +Bugfixes: ++ Nothing to see here. Move along. + diff --git a/changes.md b/changes.md index d620a38a7..bd8b19229 100644 --- a/changes.md +++ b/changes.md @@ -1,8 +1,8 @@ # PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems -**Version:** 1.10.4 +**Versions:** 1.11.0 - -**Release date:** 18 July 2022 +**Release dates:** 20 March 2023 - ## Overview: PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. @@ -16,7 +16,7 @@ Visit http://MathCancer.org/blog for the latest tutorials and help. ### Key makefile rules: -**`make`** : compiles the current project. If no +**`make`**: compiles the current project. If no project has been defined, it first populates the cancer heterogeneity 2D sample project and compiles it @@ -38,6 +38,7 @@ Visit http://MathCancer.org/blog for the latest tutorials and help. * physiboss-cell-lines-sample * cancer-metabolism-sample * interaction-sample + * mechano-sample **`make list-projects`** : list all available sample projects @@ -74,249 +75,185 @@ See changes.md for the full change log. * * * ## Release summary: -Version 1.10.4 primarily fixes bugs in file output and the ode-energy sample, and refines thread safety in cell phagocytosis. - -The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. - -A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. -A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. +Version 1.11.0 adds several notable features, fixes bugs, and further expands the "signals" and "behaviors" that can be read and written with a simple API to facilitate building models. In particular, we add a brand new CSV format for initial cell positions (with more robust naming of cells by their human-readable names, a "header" line, and ability to extensively add and specificy individual cell properties), a new ability to save and load user projects in the `user_projects` directory, automated dynamic formation and breakage of spring-based cell-cell adhesions (based upon the cell-cell adhesion affinities, attachment rates, and detachment rates), automated inclusion of spring-based adhesions (at the mechanics time step) without need for the user to explicitly supply a spring function, a new "mechano" sample project to illustrate the new automated spring functionality, and updates to PhysiBoSS to ensure compatibility with the rapidly improving PhysiCell Studio. In addition, there is new capability of adding a background coloring (e.g., an oxygen heatmap) to SVG ouptuts--see the `interaction-sample` for an illustration (use the alternate XML config file to enable). This release includes several bugfixes, the most critical of which is to update the parameters for necrotic cells (which had previously been misset in the XML files, thus disabling necrotic cell lysis and shrinking). **NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. **NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. -### Major new features and changes in the 1.10.z versions -#### 1.10.4 -+ None in this version. See 1.10.0 -#### 1.10.3 -+ None in this version. See 1.10.0 -#### 1.10.2 -+ None in this version. See 1.10.0 -#### 1.10.1 -+ None in this version. See 1.10.0 -#### 1.10.0 -+ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. - + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. - + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. - + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. - + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. - + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. +### Major new features and changes in the 1.11.z versions +#### 1.11.0 ++ New and improved (v2) cell CSV format for cell import. This allows more intuitive statement of initial cell positions. The first line of your CSV file must be: -+ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. - + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. - + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. + ```x,y,z,cell type``` -+ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. + Every subsequent line is a single cell, now referencing cell types by their human-readable names (as defined in your XML configuration file) rather than requiring the integer `ID`. So, a sample second line to place a CD8 T cell at (30,-10,12) would be: -+ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. - + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). - + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` + ```30,-10,12,CD8 T cell``` -+ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. - + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. - + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. - + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. + Moreover, the new format allows you to initialize a variety of individual cell properties, including (total) `volume` and any supported cell beheavior. For example, if your cell definitions have custom variables `GFP` ond `oncoprotein`, then you can extend the first header line to: -+ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: - + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). - + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. + ```x,y,z,cell type,custom:GFP,custom:oncoprotein``` -+ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of signals include: - + extracellular and intracellular substrate concentrations - + substrate gradients - + contact with dead cells - + contact with cells (of type X) - + damage - + pressure - + Use `display_signal_dictionary()` to quickly display a list of available signals. - + Substantial functionality to query signals - + `int find_signal_index( std::string signal_name )` : get the index of the named signal - + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals - + `std::string signal_name( int i );` display the name of the signal with the given index - + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell - + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell - + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices - + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals - + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index - + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name + And then subsequent cells look like this: -+ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of behaviors include: - + secretion, secretion target, uptake, and export rates - + cycle progression - + death rates - + motility parameters - + chemotactic parameters - + cell-cell adhesion and repulsion parameters - + cell adhesion affinities - + cell-BM adhesion and repulsion parameters - + phagocytosis rates - + attack rates - + fusion rates - + transformation rates - + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. - + Substantial functionality to query and set behaviors - + `int find_behavior_index( std::string response_name )` : get the index of the named behavior - + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. - + `std::string behavior_name( int i );` get the name of the behavior with the given index - + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors - + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype - + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype - + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype - + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype - + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype - + Substantial functionality to query the cell's current behavior - + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors - + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) - + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) - + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) - + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) - + Substantial functionality to query the cell's referece behaviors (from its cell definition) - + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors - + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) - + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) - + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) - + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) + ```30,-10,12,CD8 T cell,0.5,3.2``` + + You can tell our parser to skip specifying a specific variable with `s` or `S` or an empty entry. Here, the first cell would skip writing the initial value of the GFP, and teh second would skip initializing the oncoprotein: -+ Created a new `interaction-sample` project to illustrate the new interactions and transformations: - + Blood vessels release resource - + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) - + Stem cells divide and differentiate into differentiated cells - + Differentiated cells divide until experiencing elevated pressure (to detect confluence) - + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. - + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria - + Macrophages phagocytose dead cells - + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria - + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria - + Accumulated damage kills bacteria. - + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. + ```30,-10,12,CD8 T cell,,3.2``` + ```50,13,-4,M0 Macrophage,0.5,s``` -### Minor new features and changes: -#### 1.10.4 -+ None in this version. -#### 1.10.3 -+ Added `attachment_rate` and `detachment_rate` to `phenotype.mechanics` for use in a future standard attachment and detachment model. -+ Modernized output format: - + More complete cell data saved for each cell agent. - + Merged the previously separate cell matlab files for each time save - + Added more metadata to outputs -+ `Variables` and `Vector_Variables` in `Custom_Cell_Data` now have a new Boolean attribute `conserved_quantity` (defaulted to false). If this value is set to true, then the custom variable is divided evenly between daughter cells at division. -+ Custom cell data can now be designated as conserved by settings an attribute `conserved="true"` in the XMO configuration file. -+ Improved support for Apple M1 and M2 chips. -+ Refinements to PhysiBoSS. + We will continue to automatically support older CSV cell files; any cells CSV file missing the first line of headers will be processed in the old format. -#### 1.10.2 -+ Added `operator<<` for vectors of ints and vectors of strings. So that `std::cout << v << std::endl;` will work if `v` is `std::vector` of `std::vector`. It was truly annoying that these were missing, so sorry! -+ Added `dead` to the signals dictionaries, which returns 0.0 or 1.0 based on `phenotype.death.dead`. -+ Added `time` to the signals dictionaries, which returns the current simulation time based on `PhysiCell_Globals.current_time`. -+ Added a brief protocol on how to add new signals and behaviors to the dictionaries in the `/protocols` directory. -+ Added new functions `double& apoptosis_rate()` and `double& necrosis_rate()` to easily read and write these rates. Access via `cell.phenotype.death.apoptosis_rate()` and `cell.phenotype.death.necrosis_rate()`. -+ Added new ease of access functions for secretion: - + `double& Secretion::secretion_rate( std::string name )` allows you to easily read/write the secretion rate of a substrate by name. For example: - ```pCell->phenotype.secretion.secretion_rate("oxygen") = 0.1``` - + `double& Secretion::uptake_rate( std::string name )` allows you to easily read/write the uptake rate of a substrate by name. For example: - ```pCell->phenotype.secretion.uptake_rate("oxygen") = 0.1``` - + `double& Secretion::saturation_density( std::string name )` allows you to easily read/write the secretion target of a substrate by name. For example: - ```pCell->phenotype.secretion.saturation_density("oxygen") = 38``` - + `double& Secretion::net_export_rate( std::string name )` allows you to easily read/write the net export rate of a substrate by name. For example: - ```pCell->phenotype.secretion.net_export_rate("oxygen") = -100``` ++ Ability to save and load user projects + + Use `make save PROJ=project_name` to save your project to a folder in `./user_projects` named `project_name`. For example: -+ Added new ease of access function for internalized substrates: - + `double& Molecular::internalized_total_substrate( std::string name )` allows you to easily read/write the total amount of internalized substrate by name. For example: - ```pCell->phenotype.molecular.internalized_total_substrate( "oxygen" ) = 0.01`` -#### 1.10.1 -+ None in this version. See 1.10.0. -#### 1.10.0 -+ All sample projects have a new rule "make name" to tell you the name of the executable. + ```make save PROJ=new_tumor_sample``` -+ All sample projects output the executable name to screen for easier reference. + saves your project as `new_tumor_sample`. In particular, it saves your `Makefile`, `main.cpp`, everything in `./config`, and everything in `./custom_modules`. -+ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. + + Use `make load PROJ=project_name` to load your project from a folder in `./user_projects` named `project_name`. For example: -+ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. + ```make load PROJ=new_tumor_sample``` -### Beta features (not fully supported): -#### 1.10.4 -+ None in this version. -#### 1.10.3 -+ Each time outputs two cell interaction graphs (as text files): - + neighbor graph records which cells are within interaction distance for each cell agent, with format; - ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of interacting cells) - + attached cell graph records which cells are attached for each cell agent, with format; - ID: ID1, ID2, ID3, ... (Cell ID: and the IDs of attached cells) - + We might split these into 3 files: - + an ID list that has the ID of each cell in order of appearence. - + neighbor list omits the preceding "ID:" since now each row corresponds to the index in the ID list - + attached cell list omits the preceding "ID:" since now each row corresponds to the index in the ID list - + Began experimenting with a planned `integrity` subclass to `phenotype` that will record multiple types of cell damage and associated damage and repair rates. It is not yet clear if we wil provide built-in support for damaged-driven apoptotic death and cycle arrest, as these are generally better left to modeler-driven hypotheses. + loads your project from `new_tumor_sample`. In particular, it loads your `Makefile`, `main.cpp`, everything in `./config`, and everything in `./custom_modules`. + ++ Extended `cell_interactions` to include a vector `immunogenicities`: for a cell, `immunogenicity[j]` is how immunogenic this cell is to the jth cell type. By default, these will all be set to 1. (See next point.) -None in this version. See 1.10.0. -#### 1.10.2 -+ None in this version. See 1.10.0. -#### 1.10.1 - + None in this version. See 1.10.0. - #### 1.10.0 -+ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. ++ Updated the built-in "attack" model: + $$\textrm{Probability cell } i \textrm{ attacks cell } j \textrm{ in } [t,t+\Delta t] = \textrm{attack}\_{ij} \cdot \textrm{immunogenicity}\_{ji} \Delta t $$ + By setting $\textrm{immunogenicity}\_{ji} = 1$ as teh default value, we maintain compatibiltiy with prior models. This is a way to further modulate immunogenic and cytotoxic interactions. -+ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) ++ Began migrating built-in sample projects to be compatible with the model builder GUI and the upcoming PhysiCell Studio, including: + + template + + biorobots (updates spring constant from 0.05 to 0.5) + + heterogeneity + + cancer biorobots (updates spring constant from 0.05 to 0.5) -+ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) ++ Added new signals: + + `apoptotic` returns 1 if a cell is apoptotic, and 0 otherwise + + `necrotic` returns 1 if a cell is necrotic, and 0 otherwise -+ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) + As always, access these via `double get_single_signal(Cell* pCell,std::string sig_name)`. -+ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) ++ Added new behaviors: + + `immunogenicity to [cell type]` is the cell's immunogenicity to a specific cell type. The probability that cell `i` attacks cell `j` in $[t,t+\Delta t]$ is $\textrm{attack}\_{ij} \cdot \textrm{immunogenicity}\_{ji} \Delta t.$ + + `cell attachment rate` is the rate at which the cell forms spring links with other cells. + + `cell detachment rate` is the rate at which spring links break. + + `maximum number of cell attachments` is the maximum number of spring links. + + `is_movable` can be set to 0 (false) to make an agent rigid: it will exert forces on other cells, but it itself cannot be moved. This behavior right now is somewhat fragile if used dynmaically, but can reliably be used during tissue setup. + + As always, access these via `double get_single_behavior(Cell* pCell,std::string beh_name)` and `void set_single_behavior(Cell* pCell,std::string beh_name,double new_value)`. + ++ Added new standard model `void dynamic_attachments(Cell*, Phenotype& ,double);` This function can automate dynamic attachments and detachments. When calling this function for cell $i$: + + For each current attachment, it detaches with probability $\textrm{detachment rate}\_i \Delta t$ + + For each cell $j$ in the neighbors list, it forms an attachment with probability + $$\textrm{Prob attach } i \textrm{ to cell } j = \textrm{adhesion affinity}\_j \cdot \textrm{attachment rate}\_i \cdot \Delta t.$$ + + The attachment is only formed if both cell $i$ and $j$ have not exceeded their maximum number of + attachments. + ++ Added a new `spring_attachments` (of type `std::vector`) to cell `state` to track automated formation and removal of spring-link adhesions separately of the user-focused `attached` data struture. This will allow users to continue managing the `attachments` structure on their own for custom contact functions, without interference from automated springs (see more below). + ++ Added new standard model `void dynamic_spring_attachments(Cell*, Phenotype& ,double);` This functions exactly as the `dynamic_attachments` function, except it stores attached cells to `cell.state.spring_attachments` to avoid interfering with the user-managed `cell.state.attachments` data struture. + ++ **Automated spring attachments / detachments:** the new `dynamic_spring_attachments` function is automatically called at every mechancis time step, with cell-cell spring attachment and detachment based on the cells' current rates. Each cell evaluates spring-like elastic adhesion betwen itslef and cells in `cell.state.spring_attachments` to add to its own velocity. Some notes: + + Each cell automatically removes all its spring attachments during division + + Each cell automatically removes all its spring attachments at the *end* of death. If you want dead cells to have increased detachment, add a rule accordingly using the built-in behavior dictionary. + + If a cell is not movable (`is_movable = false`), then it is not moved by springs, but it can exert spring forces on other cells, allowing it to act as an "anchor". + + This automated spring functionality is completely independent of (and does not interfere with) the user-defined contact function and user-manageed `cell.state.attached` data structure. + + **WARNING:** If in a past life you set `phenotype.mechanics.attachment_rate` to a nonzero rate, you may find yourself surprised with unintended spring adhesions as this new automation kicks in. Please review and revise your configuration file as necessary. + + You can disable this behavior in the XML configuration file: + ``` + + + true + + ++ Added a new `mechano-sample` project that shows automated dynamic attachment and detachment of cells: + + Constant cancer cell birth and death + + Basic mechano feedback: high-pressure sets cancer cell birth to zero + + Cancer cell phenotype sets high detachment rate upon death. + + Automated connection of cancer, basement membrane (BM) agents with spring links using the built-ins noted above. No user intervention or code required beyond setting nonzero rates. + + Cancer cells manually set to apoptose at 10000 min. + ++ Updated PhysiBoSS to remove cell definition "inheritance," (with "flat", self-standing cell definitions), to make it compatible with PhysiCell Studio. Hereafter, all properties of each cell definition must be explicitely defined. + +### Minor new features and changes: +#### 1.11.0 ++ Updated the `paint_by_number_cell_coloring` coloring function to paint the entire cell white if apoptotic, and brown if necrotic. (Previously, we colored the nucleus based on live/dead status.) This improves compatibility with the model GUI. + ++ Changed the default value of `attachment_rate` from 10 to 0 (in the `Mechanics` class) to avoid unexpected triggering of automated spring adheions. + ++ Added a safety check to `operator[]` for Parameters, based on [PR145](https://github.com/MathCancer/PhysiCell/pull/145/). Thanks, Vincent Noel!! + ++ In PhysiBoSS, introduced a new state inheritance mechanism (global, and node-specific). + ++ PhisBoSS has a new optional start time, to initiate the intracellular model at t > 0. + ++ Updated PhysiBoSS Cell Lines sample project (flatten XML, initial positions as CSV). + ++ Started combining change log into a more compact format: Each release family (1.y.z, such as 1.10.z) receives an extended entry with new changes grouped by minor release. This allows major releases to be grouped with subsequent minor feature enhancements and bug fixes, for a much shorter change log that's easier to read. README will document all changes of the current release family. + +### Beta features (not fully supported): +#### 1.11.0 ++ Added `bool read_microenvironment_from_matlab( std::string mat_filename )` to `BioFVM_MultiCellDS`. This will read and overwrite from a stored microenvironment (in `mat_filename`, saved as a level 4 Matlab file) if it has the following format: + + Number of columns = number of voxels (must match the size as configured in the `PhysiCell_settings.xml` file) + + Number of rows = 3 + 1 + number of diffusing substrates (must match the size and ordering as configured in the `PhysiCell_settings.xml` file) + + Row 0: x coordinate of each voxel + + Row 1: y coordinate of each voxel + + Row 2: z coordinate of each voxel + + Row 3: volume of each voxel + + Rows j to end: value of (j-4)th substrate in each voxel + + Column ordering: + * For each z from low to high: + * For each y from low to high: + * for each x from low to high: + store voxel X[i] , Y[j], Z[k]. + + **Note:** This matches how PhysiCell saves the microenvironment. This will read any PhysiCell-saved microenvironment, so long as its sizes matches your current settings. + + **Note:** This may be fragile. It has only minimal error-checking. + + + Set default cell attachment rate to 0 in the template project and most sample projects to avoid unexpectedly triggering the new autmoated spring adhesions; users must affirmatively set a nonzero attachment rate to trigger this new automation in an individual cell. + + + In repsonse to [PR 123](https://github.com/MathCancer/PhysiCell/pull/123), `parameters.TYPE.find_index(search_name)` now returns -1 if the searched term isn't found. Thanks, Daniel Bergman! + ### Bugfixes: -#### 1.10.4 -+ Fixed vectorized outputs in MultiCellDS that incorrectly assumed linear data ordering in std::vector. Thank you Randy Heiland! -+ Fixed errors in the ode-energy-sample project. Thank you Randy Heiland, Furkan Kurtoglu, and John Metzcar! -+ Improved thread safety in phagocytosis. Thank you Michael Getz! -#### 1.10.3 -+ Fixed bug in `get_single_behavior` and `get_single_base_behavior` where querying any cycle exit rate or cycle entry mistakenly returned -1. -+ Corrected declaration of `standard_add_basement_membrane_interactions` in `PhysiCell_standard_models.h` to properly use phenotype by reference. Thank you Inês Gonçalves! -+ Removed the OpenMP pragma in `void Microenvironment::apply_dirichlet_conditions( void )` (around line 272) that tends to perform more poorly than serial code. +#### 1.11.0 ++ Fixed bug in cancer biorobots project that mistakenly set max cancer cell proliferation rate to 0.000072 instead of 0.00072 -#### 1.10.2 -+ Fixed error in `double get_single_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. ++ Fixed multiple broken signals/behaviors. -+ Fixed error in `double get_single_base_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. ++ Fixed calcification bug reported in issue [133](https://github.com/MathCancer/PhysiCell/issues/133). Thank you, @JulianoGianlupi! -+ Fixed bug in `add_PhysiCell_cells_to_open_xml_pugi()` that mistakenly used the wrong size (number of cell species rather than number of substrate species) when writing the chemotactic sensitivities. ++ Fixed typo in cell signals that used `contact with dead dell` instead of `contact with dead cell` -+ The cell `neighbors` list did not add non-adhesive cells within interaction distance. This is now fixed. ++ Changed default full data output to 60 minutes (to match the SVG output interval) for better compatibility with the model builder GUI. -#### 1.10.1 -+ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. ++ Fixed incorrect parameters for necrotic cell volume changes that prevented necrotic cell lysis and shrinkage. -+ Missing PhysiBoSS makefiles have been replaced. ++ Merged Daniel Bergman's [PR 126](https://github.com/MathCancer/PhysiCell/pull/126), which fixes cell legend colors. Thank's Daniel! -+ Fixed broken makefile for worms sample project. ++ Improved safety checks in the cell orientation function, thanks to Randy Heiland's [PR 122](https://github.com/MathCancer/PhysiCell/pull/122). Thanks, Randy! -#### 1.10.0 -+ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. ++ Now forcing Mersenne Twister as random generator in PhysiBoSS (use or /dev/random by MaBoSS would max out system descriptor) -+ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. ++ MaBoSS BND/CFG parsing is now in an OpenMP critical block (flex/bison parser is not thread safe) -+ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. ++ Remove duplicate initialization of maximum attachment rate from the Phenotype.Mechanics constructor. -+ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! ++ Fixed bug in neighbor/attached graph output filenames (previously double-appended a suffix to the filenames). ### Notices for intended changes that may affect backwards compatibility: + We intend to deprecate the unused phenotype variables `relative_maximum_attachment_distance`, `relative_detachment_distance`, and `maximum_attachment_rate` from `phenotype.mechanics.` -+ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. ++ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the future. + We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. -+ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. ++ Additional search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. + We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. @@ -344,10 +281,11 @@ None in this version. See 1.10.0. * * * +# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems -**Version:** 1.10.3 +**Versions:** 1.10.0 - 1.10.4 -**Release date:** 25 June 2022 +**Release dates:** 13 May 2022 - 18 July 2022 ## Overview: PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. @@ -418,19 +356,35 @@ Visit http://MathCancer.org/blog for the latest tutorials and help. See changes.md for the full change log. * * * -## Release summary: +## Release summaries: +The 1.10.z releases introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. + +**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. + +**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. + +### 1.10.4 (18 July 2022): +Version 1.10.4 primarily fixes bugs in file output and the ode-energy sample, and refines thread safety in cell phagocytosis. + +### 1.10.3 (25 June 2022): Version 1.10.3 primarily fixes bugs and further refines the signal and behavior dictionaries, particularly with access to custom variables. It also allows users to designate custom variables as _conserved quantities_ that are divided evenly among daughter cells as division (e.g., melanosomes). Lastly, this release continues updates to PhysiBoSS and libRoadrunner to leverage newer core features and improve compatibiltiy, while also improving support for newer Mac (M1 and M2) architectures. -The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. +### 1.10.2 (24 May 2022): +Version 1.10.2 introduces bugfixes to the behavior "dictionary" functiouns, data saves, and updating neighbor lists for nearby non-adhesive cells. It also introduces a number of ease-of-access functions to the phenotype for death rates, secretion, and internalized substrates. -A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. -A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. +### 1.10.1 (15 May 2022): +Version 1.10.1 introduces bugfixes to increase XML parser robustness and to fix missing PhysiBoSS makefiles. -**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. +### 1.10.0 (13 May 2022): +The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. -**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. +A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. + +A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. ### Major new features and changes in the 1.10.z versions +#### 1.10.4 ++ None in this version. See 1.10.0 #### 1.10.3 + None in this version. See 1.10.0 #### 1.10.2 @@ -542,6 +496,8 @@ A blog post and tutorial on the new signal and behavior dictionaries can be foun + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. ### Minor new features and changes: +#### 1.10.4 ++ None in this version. #### 1.10.3 + Added `attachment_rate` and `detachment_rate` to `phenotype.mechanics` for use in a future standard attachment and detachment model. + Modernized output format: @@ -584,6 +540,8 @@ A blog post and tutorial on the new signal and behavior dictionaries can be foun + `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. ### Beta features (not fully supported): +#### 1.10.4 ++ None in this version. #### 1.10.3 + Each time outputs two cell interaction graphs (as text files): + neighbor graph records which cells are within interaction distance for each cell agent, with format; @@ -613,6 +571,11 @@ None in this version. See 1.10.0. + Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) ### Bugfixes: +#### 1.10.4 ++ Fixed vectorized outputs in MultiCellDS that incorrectly assumed linear data ordering in std::vector. Thank you Randy Heiland! ++ Fixed errors in the ode-energy-sample project. Thank you Randy Heiland, Furkan Kurtoglu, and John Metzcar! ++ Improved thread safety in phagocytosis. Thank you Michael Getz! + #### 1.10.3 + Fixed bug in `get_single_behavior` and `get_single_base_behavior` where querying any cycle exit rate or cycle entry mistakenly returned -1. + Corrected declaration of `standard_add_basement_membrane_interactions` in `PhysiCell_standard_models.h` to properly use phenotype by reference. Thank you Inês Gonçalves! @@ -678,798 +641,40 @@ None in this version. See 1.10.0. * * * +end of 1.10.x changes + +* * * + # PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems -**Version:** 1.10.2 +**Versions:** 1.9.0 - 1.9.1 -**Release date:** 24 May 2022 +**Release dates:** 12 July 2021 - 13 September 2021 -## Overview: -PhysiCell is a flexible open source framework for building agent-based multicellular models in 3-D tissue environments. +## Release summaries: +Version 1.9.z introduces intracellular modeling, i.e., models inside individual cells, for PhysiCell. We support three types of intracellular models: boolean networks, ordinary differential equations (ODEs), and dynamic flux balance analysis (dFBA). An intracellular model is part of a cell type's phenotype specification. Currently, we only support a single intracellular model per cell type; however, different *types* of models can be used for different cell types, e.g., a boolean network for cell type A and ODEs for cell type B. -**Reference:** A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: [10.1371/journal.pcbi.1005991](https://dx.doi.org/10.1371/journal.pcbi.1005991) +### Version 1.9.1 (13 September 2021): +Version 1.9.1 release focuses primarily on bug fixes. It fixes memory leaks and other bugs in intracellular modeling, as well as several small bugs in parsing cell definitions in the XML configuration file. It also implements a basic_volume_model that only models total volume. (For internal consistency, it treats the entire cell as cytoplasm.) -Visit http://MathCancer.org/blog for the latest tutorials and help. +### Version 1.9.0 (12 July 2021): +Version 1.9.0 introduces intracellular modeling, i.e., models inside individual cells, for PhysiCell. We support three types of intracellular models: boolean networks, ordinary differential equations (ODEs), and dynamic flux balance analysis (dFBA). An intracellular model is part of a cell type's phenotype specification. Currently, we only support a single intracellular model per cell type; however, different *types* of models can be used for different cell types, e.g., a boolean network for cell type A and ODEs for cell type B. -**Notable recognition:** -+ [2019 PLoS Computational Biology Research Prize for Public Impact](https://blogs.plos.org/biologue/2019/05/31/announcing-the-winners-of-the-2019-plos-computational-biology-research-prize/) +This new functionality has been a collaborative effort with the Institut Curie, the Barcelona Supercomputing Center, and the University of Washington. We provide a unified C++ interface between each intracellular model and PhysiCell. -### Key makefile rules: - -**`make`** : compiles the current project. If no - project has been defined, it first - populates the cancer heterogeneity 2D - sample project and compiles it - -**`make project-name`**: populates the indicated sample project. - Use "make" to compile it. - - * **`project-name`** choices: - * template - * biorobots-sample - * cancer-biorobots-sample - * cancer-immune-sample - * celltypes3-sample - * heterogeneity-sample - * pred-prey-farmer - * virus-macrophage-sample - * worm-sample - * ode-energy-sample - * physiboss-cell-lines-sample - * cancer-metabolism-sample - * interaction-sample - -**`make list-projects`** : list all available sample projects - -**`make clean`** : removes all .o files and the executable, so that the next "make" recompiles the entire project - -**make data-cleanup** : clears out all simulation data - -**make reset** : de-populates the sample project and returns to the original PhysiCell state. Use this when switching to a new PhysiCell sample project. - -**make jpeg** : uses ImageMagick to convert the SVG files in the output directory to JPG (with appropriate sizing to make movies). Supply `OUTPUT=foldername` to select a different folder. - -**make movie** : uses ffmpeg to convert the JPG files in the output directory an mp4 movie. Supply `OUTPUT=foldername` to select a different folder, or `FRAMERATE=framerate` to override the frame rate. - -**make upgrade** : fetch the latest release of PhysiCell and overwrite the core library and sample projects. - -**Homepage:** http://PhysiCell.MathCancer.org - -**Downloads:** http://PhysiCell.sf.net - -**Support:** https://sourceforge.net/p/physicell/tickets/ - -**Quick Start:** Look at QuickStart.md in the documentation folder. - -**User Guide:** Look at UserGuide.pdf in the documentation folder. - -**Tutorials:** http://www.mathcancer.org/blog/physicell-tutorials/ - -**Latest info:** follow [@PhysiCell](https://twitter.com/PhysiCell) on Twitter (http://twitter.com/PhysiCell) - -See changes.md for the full change log. - -* * * -## Release summary: -Version 1.10.2 introduces bugfixes to the behavior "dictionary" functiouns, data saves, and updating neighbor lists for nearby non-adhesive cells. It also introduces a number of ease-of-access functions to the phenotype for death rates, secretion, and internalized substrates. - -The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. - -A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. - -A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. - -**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. - -**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. - -### Major new features and changes in the 1.10.z versions -#### 1.10.2 -+ None in this version. See 1.10.0 -#### 1.10.1 -+ None in this version. See 1.10.0 -#### 1.10.0 -+ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. - + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. - + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. - + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. - + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. - + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. - + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. - + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. - -+ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. - + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). - + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` - -+ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. - + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. - + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. - + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - -+ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: - + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). - + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - -+ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of signals include: - + extracellular and intracellular substrate concentrations - + substrate gradients - + contact with dead cells - + contact with cells (of type X) - + damage - + pressure - + Use `display_signal_dictionary()` to quickly display a list of available signals. - + Substantial functionality to query signals - + `int find_signal_index( std::string signal_name )` : get the index of the named signal - + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals - + `std::string signal_name( int i );` display the name of the signal with the given index - + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell - + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell - + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices - + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals - + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index - + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name - -+ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of behaviors include: - + secretion, secretion target, uptake, and export rates - + cycle progression - + death rates - + motility parameters - + chemotactic parameters - + cell-cell adhesion and repulsion parameters - + cell adhesion affinities - + cell-BM adhesion and repulsion parameters - + phagocytosis rates - + attack rates - + fusion rates - + transformation rates - + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. - + Substantial functionality to query and set behaviors - + `int find_behavior_index( std::string response_name )` : get the index of the named behavior - + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. - + `std::string behavior_name( int i );` get the name of the behavior with the given index - + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors - + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype - + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype - + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype - + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype - + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype - + Substantial functionality to query the cell's current behavior - + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors - + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) - + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) - + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) - + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) - + Substantial functionality to query the cell's referece behaviors (from its cell definition) - + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors - + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) - + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) - + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) - + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) - -+ Created a new `interaction-sample` project to illustrate the new interactions and transformations: - + Blood vessels release resource - + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) - + Stem cells divide and differentiate into differentiated cells - + Differentiated cells divide until experiencing elevated pressure (to detect confluence) - + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. - + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria - + Macrophages phagocytose dead cells - + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria - + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria - + Accumulated damage kills bacteria. - + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. - -### Minor new features and changes: -#### 1.10.2 -+ Added `operator<<` for vectors of ints and vectors of strings. So that `std::cout << v << std::endl;` will work if `v` is `std::vector` of `std::vector`. It was truly annoying that these were missing, so sorry! -+ Added `dead` to the signals dictionaries, which returns 0.0 or 1.0 based on `phenotype.death.dead`. -+ Added `time` to the signals dictionaries, which returns the current simulation time based on `PhysiCell_Globals.current_time`. -+ Added a brief protocol on how to add new signals and behaviors to the dictionaries in the `/protocols` directory. -+ Added new functions `double& apoptosis_rate()` and `double& necrosis_rate()` to easily read and write these rates. Access via `cell.phenotype.death.apoptosis_rate()` and `cell.phenotype.death.necrosis_rate()`. -+ Added new ease of access functions for secretion: - + `double& Secretion::secretion_rate( std::string name )` allows you to easily read/write the secretion rate of a substrate by name. For example: - ```pCell->phenotype.secretion.secretion_rate("oxygen") = 0.1``` - + `double& Secretion::uptake_rate( std::string name )` allows you to easily read/write the uptake rate of a substrate by name. For example: - ```pCell->phenotype.secretion.uptake_rate("oxygen") = 0.1``` - + `double& Secretion::saturation_density( std::string name )` allows you to easily read/write the secretion target of a substrate by name. For example: - ```pCell->phenotype.secretion.saturation_density("oxygen") = 38``` - + `double& Secretion::net_export_rate( std::string name )` allows you to easily read/write the net export rate of a substrate by name. For example: - ```pCell->phenotype.secretion.net_export_rate("oxygen") = -100``` - -+ Added new ease of access function for internalized substrates: - + `double& Molecular::internalized_total_substrate( std::string name )` allows you to easily read/write the total amount of internalized substrate by name. For example: - ```pCell->phenotype.molecular.internalized_total_substrate( "oxygen" ) = 0.01`` - -#### 1.10.1 -+ None in this version. See 1.10.0. -#### 1.10.0 -+ All sample projects have a new rule "make name" to tell you the name of the executable. - -+ All sample projects output the executable name to screen for easier reference. - -+ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. - -+ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. - -### Beta features (not fully supported): -#### 1.10.2 -+ None in this version. See 1.10.0. -#### 1.10.1 - + None in this version. See 1.10.0. - #### 1.10.0 -+ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. - -+ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) - -+ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) - -+ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) - -+ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) - -### Bugfixes: -#### 1.10.2 -+ Fixed error in `double get_single_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. - -+ Fixed error in `double get_single_base_behavior()` where the `cell-cell adhesion elastic constant` behavior was not found. - -+ Fixed bug in `add_PhysiCell_cells_to_open_xml_pugi()` that mistakenly used the wrong size (number of cell species rather than number of substrate species) when writing the chemotactic sensitivities. - -+ The cell `neighbors` list did not add non-adhesive cells within interaction distance. This is now fixed. - -#### 1.10.1 -+ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. - -+ Missing PhysiBoSS makefiles have been replaced. - -+ Fixed broken makefile for worms sample project. - -#### 1.10.0 -+ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. - -+ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. - -+ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. - -+ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! - -### Notices for intended changes that may affect backwards compatibility: - -+ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. - -+ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. - -+ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. - -+ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. - -+ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. - -### Planned future improvements: - -+ Further XML-based simulation setup. - -+ Read saved simulation states (as MultiCellDS digital snapshots) - -+ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) - -+ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) - -+ Create an angiogenesis sample project - -+ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) - -+ Improved plotting options in SVG - -+ Further update sample projects to make use of more efficient interaction testing available - -+ Major refresh of documentation. - -* * * -**Version:** 1.10.1 - -**Release date:** 15 May 2022 - -## Release summary: - -Version 1.10.1 introduces bugfixes to increase XML parser robustness and to fix missing PhysiBoSS makefiles. - -The 1.10.0 release introduced major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. - -A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations. - -A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. - -**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. - -**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. - -### Major new features and changes in the 1.10.z versions -#### 1.10.1 -+ None in this version. See 1.10.0 -#### 1.10.0 -+ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. - + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. - + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. - + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. - + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. - + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. - + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. - + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. - -+ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. - + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). - + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` - -+ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. - + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. - + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. - + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - -+ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: - + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). - + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - -+ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of signals include: - + extracellular and intracellular substrate concentrations - + substrate gradients - + contact with dead cells - + contact with cells (of type X) - + damage - + pressure - + Use `display_signal_dictionary()` to quickly display a list of available signals. - + Substantial functionality to query signals - + `int find_signal_index( std::string signal_name )` : get the index of the named signal - + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals - + `std::string signal_name( int i );` display the name of the signal with the given index - + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell - + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell - + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices - + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals - + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index - + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name - -+ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of behaviors include: - + secretion, secretion target, uptake, and export rates - + cycle progression - + death rates - + motility parameters - + chemotactic parameters - + cell-cell adhesion and repulsion parameters - + cell adhesion affinities - + cell-BM adhesion and repulsion parameters - + phagocytosis rates - + attack rates - + fusion rates - + transformation rates - + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. - + Substantial functionality to query and set behaviors - + `int find_behavior_index( std::string response_name )` : get the index of the named behavior - + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. - + `std::string behavior_name( int i );` get the name of the behavior with the given index - + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors - + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype - + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype - + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype - + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype - + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype - + Substantial functionality to query the cell's current behavior - + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors - + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) - + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) - + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) - + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) - + Substantial functionality to query the cell's referece behaviors (from its cell definition) - + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors - + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) - + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) - + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) - + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) - -+ Created a new `interaction-sample` project to illustrate the new interactions and transformations: - + Blood vessels release resource - + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) - + Stem cells divide and differentiate into differentiated cells - + Differentiated cells divide until experiencing elevated pressure (to detect confluence) - + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. - + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria - + Macrophages phagocytose dead cells - + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria - + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria - + Accumulated damage kills bacteria. - + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. - -### Minor new features and changes: -#### 1.10.1 -+ None in this version. See 1.10.0. -#### 1.10.0 -+ All sample projects have a new rule "make name" to tell you the name of the executable. - -+ All sample projects output the executable name to screen for easier reference. - -+ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. - -+ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. - -### Beta features (not fully supported): - #### 1.10.1 - + None in this version. See 1.10.0. - #### 1.10.0 -+ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. - -+ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) - -+ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) - -+ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) - -+ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) - -### Bugfixes: -#### 1.10.1 -+ XML parsing has been made more robust to "survive" using an incorrect substrate in the `chemotactic_sensitivities` section. - -+ Missing PhysiBoSS makefiles have been replaced. - -+ Fixed broken makefile for worms sample project. - -#### 1.10.0 -+ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. - -+ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. - -+ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. - -+ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! - -### Notices for intended changes that may affect backwards compatibility: - -+ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. - -+ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. - -+ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. - -+ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. - -+ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. - -### Planned future improvements: - -+ Further XML-based simulation setup. - -+ Read saved simulation states (as MultiCellDS digital snapshots) - -+ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) - -+ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) - -+ Create an angiogenesis sample project - -+ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) - -+ Improved plotting options in SVG - -+ Further update sample projects to make use of more efficient interaction testing available - -+ Major refresh of documentation. - -* * * - -**Version:** 1.10.0 - -**Release date:** 13 May 2022 - -## Release summary: - -This release introduces major new phenotype functionality, including standardized support for cell-cell interactions (phagocytosis, cell attack that increases a tracked damage variable, and cell fusion), cell transformations, advanced chemotaxis, and cell adhesion affinities for preferential adhesion. This release also includes new, auto-generated "dictionaries" of signals and behaviors to facilitate writing cell behavioral models and intracellular models, as well as standardized Hill and linear response functions for use in intracellular models. Lastly, this release includes a number of bugfixes, most notably pseudorandom number generators with improved thread safety. - -A blog post and tutorial on the new phenotype elements can be found at http://www.mathcancer.org/blog/introducing-cell-interactions-and-transformations - -A blog post and tutorial on the new signal and behavior dictionaries can be found at http://www.mathcancer.org/blog/introducing-cell-signal-and-behavior-dictionaries. - -**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. - -**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. - -### Major new features and changes in the 1.10.z versions -#### 1.10.0 - -+ Created `Cell_Interactions` in `Phenotype` as a standard representation of essential cell-cell interactions, including phagocytosis, "attack", and fusion. - + Users can set phagocytosis rates for dead cells via `phenotype.cell_interactions.dead_phagocytosis_rate`. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. - + Users can set phagocytosis rates for each live cell type via `phenotype.cell_interactions.live_phagocytosis_rates`. There is one rate for each cell type in the simulation. Cells automatically phagocytose live and dead neighbors at each mechancis time step based upon the phagocytosis rates. Phagocytosis absorbs the target cell's volume and internal contents and flags the target for removal. The cell will eventually shrink back towards its target volume. - + For convenience, the phagocytosis rates can be accessed (read or written) via `phenotype.cell_interactions.live_phagocytosis_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set attack rates for live cells via `phenotype.cell_interactions.attack_rates`. There is one rate for each cell type in the simulation. Cells automaticaly attack neighbors at each mechanics time step based upon the rates. An attack event increases the target cell's `cell.state.damage` by `damage_rate * dt_mechanics` and `cell.state.total_attack_time` by `dt_mechanics`. It is up to the scientist user to set additional hypotheses that increases cell death with accumulated damage or attack time. - + For convenience, the attack rates can be accessed via `phenotype.cell_interactions.attack_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - + Users can set fusion rates for live cells via `phenotype.cell_interactions.fusion_rates`. There is one rate for each cell type in the simulation. Cells automaticaly fuse with at each mechanics time step based upon the rates. Fusion will merge the two cells' volumes and internal contents, add their nuclei (recorded in `cell.state.number_of_nuclei`), and move the combine cell to the prior center of volume. The combined cell's new target volume is the sum of the two original cells' target volumes. - + For convenience, the fusion rates can be accessed via `phenotype.cell_interactions.fusion_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Created `Cell_Transformations` in `Phenotype` as a standard representation of cell transformations such as differentation or transdifferentiation. - + Users can set transformation rates for each live cell type via `phenotype.cell_transformations_transformation_rates`. There is one rate for each cell type in the simulation. Cells automatically attempt to transform to these types at each phenotype time step based upon the phagocytosis rates. - + For convenience, the transformation rates can be accessed (read or written) via `phenotype.cell_transformations.transformation_rate(name)` where `name` (a `std::string`) is the human-readable name of a cell type. - -+ Updated `Cell_State` to track the number of nuclei (for fusion), total damage (e.g., for cell attack) and total attack time. - -+ Added a new `advanced_chemotaxis` function with data stored in `phenotype.motility` to allow chemotaxis up a linear combination of gradients. - + `cell.phenotype.motility.chemotactic_sensitivities` is a vector of chemotactic sensitivies, one for each substrate in the environment. By default, these are all zero for backwards compatibility. A positive sensitivity denotes chemotaxis up a corresponding substrate's gradient (towards higher values), whereas a negative sensitivity gives chemotaxis against a gradient (towards lower values). - + For convenience, you can access (read and write) a substrate's chemotactic sensitivity via `phenotype.motility.chemotactic_sensitivity(name)`, where `name` is the human-readable name of a substrate in the simulation. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * grad(rho_0) + sensitivity_1 * grad(rho_1) + ... + sensitivity_n * grad(rho_n)`. - + If the user sets `cell.cell_functions.update_migration_bias = advanced_chemotaxis_function_normalized`, then these sensitivities are used to set the migration bias direction via `d_mot = sensitivity_0 * |grad(rho_0)| + sensitivity_1 * |grad(rho_1)| + ... + sensitivity_n * |grad(rho_n)|.` - -+ Added a new `adhesion_affinities` to `phenotype.mechanics` to allow preferential adhesion. - + `cell.phenotype.mechanics.adhesion_affinities` is a vector of adhesive affinities, one for each cell type in the simulation. By default, these are all one for backwards compatibility. - + For convenience, you can access (read and write) a cell's adhesive affinity for a specific cell type via `phenotype.mechanics.adhesive_affinity(name)`, where `name` is the human-readable name of a cell type in the simulation. - + The standard mechanics function (based on potentials) uses this as follows. If cell `i` has an cell-cell adhesion strength `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has a cell-cell adhesion strength of `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - + The standard elastic spring function (`standard_elastic_contact_function`) uses this as follows. If cell `i` has an elastic constant `a_i` and an adhesive affinity `p_ij` to cell type `j` , and if cell `j` has an elastic constant `a_j` and an adhesive affinity `p_ji` to cell type `i`, then the strength of their adhesion is `sqrt( a_i p_ij a_j p_ji )`. Notice that if `a_i = a_j` and `p_ij = p_ji`, then this reduces to `a_i a_pj`. - -+ `PhysiCell_basic_signaling` now includes standard Hill and linear response functions: - + `Hill_response_function( double s, double half_max , double hill_power )` is a Hill function responding to signal `s` with a half-max of `half_max` and Hill coefficient of `hill_power`. We note that this function is an order of magnitude faster when the `hill_power` is an integer (e.g., 1 or 2) rather than a non-integer power (e.g., 1.4). - + `double linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 0.0 (for inputs `s` below `s_min`) to 1.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - + `double decreasing_linear_response_function( double s, double s_min , double s_max )` is a linear ramping from 1.0 (for inputs `s` below `s_min`) to 0.0 (for inputs `s` above `s_max`). The outputs are clamped to the range [0,1]. - -+ We introduced a "dictionary" of standard signals that can be used as inputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of signals include: - + extracellular and intracellular substrate concentrations - + substrate gradients - + contact with dead cells - + contact with cells (of type X) - + damage - + pressure - + Use `display_signal_dictionary()` to quickly display a list of available signals. - + Substantial functionality to query signals - + `int find_signal_index( std::string signal_name )` : get the index of the named signal - + `std::vector find_signal_indices( std::vector signal_names );` get a vector of indices for a vector of named signals - + `std::string signal_name( int i );` display the name of the signal with the given index - + `std::vector get_signals( Cell* pCell );` get a vector of all known signals for the cell - + `std::vector get_cell_contact_signals( Cell* pCell );` get a vector of the cell contact associated signals for the cell - + `std::vector get_selected_signals( Cell* pCell , std::vector indices );` get a vector of signals for the cell, with the supplied indices - + `std::vector get_selected_signals( Cell* pCell , std::vector names );` get a vector of signals for the cell, with the supplied human-readable names of the signals - + `double get_single_signal( Cell* pCell, int index );` get a single signal for the cell with the indicated index - + `double get_single_signal( Cell* pCell, std::string name );` get a single signal for the cell with the indicated human-readable name - -+ We introduced a "dictionary" of standard behaviors that can be used as outputs to intracellular and rule-based models. This dictionary is automatically constructed at the start of each simulation based upon the combinations of signaling substrates and cell types. - + Major classes of behaviors include: - + secretion, secretion target, uptake, and export rates - + cycle progression - + death rates - + motility parameters - + chemotactic parameters - + cell-cell adhesion and repulsion parameters - + cell adhesion affinities - + cell-BM adhesion and repulsion parameters - + phagocytosis rates - + attack rates - + fusion rates - + transformation rates - + Use `display_behavior_dictionary()` to quickly see a list of posible behaviors. - + Substantial functionality to query and set behaviors - + `int find_behavior_index( std::string response_name )` : get the index of the named behavior - + `std::vector find_behavior_indices( std::vector behavior_names )` get the indices for the given vector of behavior names. - + `std::string behavior_name( int i );` get the name of the behavior with the given index - + `std::vector create_empty_behavior_vector();` create an empty vector for the full set of behaviors - + `void set_behaviors( Cell* pCell , std::vector parameters );` write the full set of behaviors to the cell's phentoype - + `void set_selected_behaviors( Cell* pCell , std::vector indices , std::vector parameters );` write the selected set of behaviors (with supplied indices) to the cell's phenotype - + `void set_selected_behaviors( Cell* pCell , std::vector names , std::vector parameters );` write the selected set of behaviors (with supplied names) to the cell's phenotype - + `void set_single_behavior( Cell* pCell, int index , double parameter );` write a single behavior (by index) to the cell phentoype - + `void set_single_behavior( Cell* pCell, std::string name , double parameter );` write a single behavior (by name) to the cell phentoype - + Substantial functionality to query the cell's current behavior - + `std::vector get_behaviors( Cell* pCell );` get all the cell's current behaviors - + `std::vector get_behaviors( Cell* pCell , std::vector indices );` get a subset of behaviors (with given indices) - + `std::vector get_behaviors( Cell* pCell , std::vector names );` get a subset of behaviors (with given names) - + `double get_single_behavior( Cell* pCell , int index );` get a single behavior (by index) - + `double get_single_behavior( Cell* pCell , std::string name );` get a single behavior (by name) - + Substantial functionality to query the cell's referece behaviors (from its cell definition) - + `std::vector get_base_behaviors( Cell* pCell );` get all the cell's base behaviors - + `std::vector get_base_behaviors( Cell* pCell , std::vector indices );` get a subset of base behaviors (with given indices) - + `std::vector get_base_behaviors( Cell* pCell , std::vector names );` get a subset of base behaviors (with given names) - + `double get_single_base_behavior( Cell* pCell , int index );` get a single base behavior (by index) - + `double get_single_base_behavior( Cell* pCell , std::string name );` get a single base behavior (by name) - -+ Created a new `interaction-sample` project to illustrate the new interactions and transformations: - + Blood vessels release resource - + Virulet bacteria colonize near vessels (by chemotaxis up towards a secreted quorum factor and resource) - + Stem cells divide and differentiate into differentiated cells - + Differentiated cells divide until experiencing elevated pressure (to detect confluence) - + Bacteria-secreted virulence factor kills stem and differentiated cells. Dead cells release debris. - + Macrophages chemotax towards quorum factor and debris and secrete pro-inflammatory factor in presence of dead cells or bacteria - + Macrophages phagocytose dead cells - + CD8+ T cells chemotax towards pro-inflamatory factor and attack bacteria - + Neutrophils chemotax towards pro-inflammatory factor and phagocytose live bacteria - + Accumulated damage kills bacteria. - + With default parameters, bacteria kill off cells ot form abscesses, until death attracts macrophages to activate immune response to kill the invaders, after which the tissue can regrow. - -### Minor new features and changes: - -+ All sample projects have a new rule "make name" to tell you the name of the executable. - -+ All sample projects output the executable name to screen for easier reference. - -+ `Cell_Definition` has a new Boolean `is_movable`, so that all cells of a type can be set to non-movable. (Default: `is_movable = true`;) This allows you to use agents as rigid objects or barriers. - -+ `create_cell( Cell_Definition )` now uses "`is_movable`" from the cell definition. - -### Beta features (not fully supported): - -+ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. - -+ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) - -+ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) - -+ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) - -+ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) - -### Bugfixes: -+ When the `cell_defaults` definition has been altered, new cell types may unwittingly copy nonzero parameter values from this default. Now, immediately after copying `cell_defaults`, the XML parsing will reset motility to off (with `NULL` function for bias direction), reset all secretion/uptake/export to zero, reset all cell interactions and transformations to zero. It will then continue to parse the XML file. Set `legacy_cell_defaults_copy = true` in the config file to override this bugfix. - -+ We refactored the pseudorandom number generator (at the basis of `UniformRandom()`) to improve thread safety. Previously, all threads shared a single PRNG, which was not thread safe. For newer fast processors with many threads, this could lead to sufficiently many "collisions" to introduce subtle biases in some cases (particularly for purely Brownian motion that is not dominated by chemotaxis, proliferation, and other behaviors). This is now corrected by creating a PRNG for each thread, each with its own seed. We used `std::seed_seq` to determinstically set a good spread of seeds to prevent correlation between the PRNGs, with the convention that the 0th thread's seed is either the user-specified seed or a random seed. This preserves original single-thread behavior from prior versions. - -+ Random motility now uses `UniformOnUnitCircle()` (in 2D) and `UniformOnUnitSphere()` (in 3D) to choose the random component of the migration direction, rather than hand-coding selection of the random vector. - -+ In response to PR 91 (https://github.com/MathCancer/PhysiCell/pull/91): Previoulsy, if the make jpeg rule fails, the `__*.txt` temporary files are left in place, so a subsequent "make jpeg" fails until these files are manually removed. Replacing `>>` (append) with `>` (overwrite) fixes the problem. Thanks [saikiRA1011](https://github.com/saikiRA1011)! - -### Notices for intended changes that may affect backwards compatibility: - -+ We intend to merge `Custom_Variable` and `Custom_Vector_Variable` in the very near future. - -+ We may change the role of `operator()` and `operator[]` in `Custom_Variable` to more closely mirror the functionality in `Parameters`. - -+ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. - -+ We will change the timing of when `entry_function`s are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather than both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to execute the entry function at the next cycle call. This should make daughter cells independently execute the entry function. - -+ We might make `trigger_death` clear out all the cell's functions, or at least add an option to do this. - -### Planned future improvements: - -+ Further XML-based simulation setup. - -+ Read saved simulation states (as MultiCellDS digital snapshots) - -+ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) - -+ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) - -+ Create an angiogenesis sample project - -+ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) - -+ Improved plotting options in SVG - -+ Further update sample projects to make use of more efficient interaction testing available - -+ Major refresh of documentation. - -* * * - -**Version:** 1.9.1 - -**Release date:** 13 September 2021 - -## Release summary: - -This release focuses primarily on bug fixes. It fixes memory leaks and other bugs in intracellular modeling, as well as several small bugs in parsing cell definitions in the XML configuration file. It also implements a basic_volume_model that only models total volume. (For internal consistency, it treats the entire cell as cytoplasm.) +The Systems Biology Markup Language (SBML) is used to define both the ODEs and FBA models; boolean networks are defined using MaBoSS's custom +configuration (.cfg and .bnd) files. (NOTE: PhysiCell does *not* support the full SBML specification; details are provided elsewhere.) **NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. **NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. - + ### Major new features and changes: +#### Version 1.9.1: + None in this release. -### Minor new features and changes: - -+ Implemented basic_volume_model (see standard models), where nuclear volumes are set to zero, and cytoplasmic volumes are updated as normal. - -### Beta features (not fully supported): - -+ Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. - -+ [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) - -+ Added a simple Qt GUI for plotting cells only (plot_cells.py and vis_tab_cells_only.py in /beta) - -+ Added a simple Qt GUI for plotting substrates and cells (plot_data.py and vis_tab.py in /beta) - -+ Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) - -### Bugfixes: -+ Fixed bug in legend function where on some rare occasions, the temporary cell could adversely interact with other cells prior to deletion. - -+ Remove an old error printout from standard_elastic_contact_function that causes problem with the ANCIENT version of gcc (4.8.x) that nanoHUB refuses to upgrade. - -+ Fixed Libroadrunner memory leak issue. - -+ Made minor bugfixes to parsing cell definitions in the XML configuration files: - + verify motility enabled flag is present before parsing its value - + fix bug when parsing multiple death models - -### Notices for intended changes that may affect backwards compatibility: - -+ We intend to merge Custom_Variable and Custom_Vector_Variable in the very near future. - -+ We may change the role of operator() and operator[] in Custom_Variable to more closely mirror the functionality in Parameters. - -+ Some search functions (e.g., to find a substrate or a custom variable) will start to return -1 if no matches are found, rather than 0. - -+ We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. - -+ We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. - -+ We will most probably merge all of "core" and "modules" into "core." - -### Planned future improvements: - -+ Further XML-based simulation setup. - -+ Read saved simulation states (as MultiCellDS digital snapshots) - -+ Add cell differentiation functionality to Phenotype, to be executed during cell division events. - -+ Add a new standard phenotype function that uses mechanobiology, where high pressure can arrest cycle progression. (See https://twitter.com/MathCancer/status/1022555441518338048.) - -+ Add module for standardized pharmacodynamics, as prototyped in the nanobio project. (See https://nanohub.org/resources/pc4nanobio.) - -+ Create an angiogenesis sample project - -+ Create a small library of angiogenesis and vascularization codes as an optional standard module in ./modules (but not as a core component) - -+ Improved plotting options in SVG - -+ Further update sample projects to make use of more efficient interaction testing available - -+ Major refresh of documentation. - -* * * - -**Version:** 1.9.0 - -**Release date:** 12 July 2021 - -## Release summary: - -This release introduces intracellular modeling, i.e., models inside individual cells, for PhysiCell. We support three types of intracellular models: boolean networks, ordinary differential equations (ODEs), and dynamic flux balance analysis (dFBA). An intracellular model is part of a cell type's phenotype specification. Currently, we only support a single intracellular model per cell type; however, different *types* of models can be used for different cell types, e.g., a boolean network for cell type A and ODEs for cell type B. - -This new functionality has been a collaborative effort with the Institut Curie, the Barcelona Supercomputing Center, and the University of Washington. -We provide a unified C++ interface between each intracellular model and PhysiCell. - -The Systems Biology Markup Language (SBML) is used to define both the ODEs and FBA models; boolean networks are defined using MaBoSS's custom -configuration (.cfg and .bnd) files. (NOTE: PhysiCell does *not* support the full SBML specification; details are provided elsewhere.) - - -**NOTE 1:** MacOS users need to define a PHYSICELL_CPP environment variable to specify their OpenMP-enabled g++. See the [Quickstart](documentation/Quickstart.md) for details. - -**NOTE 2:** Windows users need to follow an updated (from v1.8) MinGW64 installation procedure. This will install an updated version of g++, plus libraries that are needed for some of the intracellular models. See the [Quickstart](documentation/Quickstart.md) for details. - -### Major new features and changes: - +#### Version 1.9.0: + First full support for intracellular models: boolean networks, ordinary differential equations (ODEs), and dynamic flux balance analysis (dFBA). + Added an abstract `Intracellular` class in core/PhysiCell_phenotype.h. Concrete classes for the supported intracellular models provide the functionality in the abstract class. @@ -1481,7 +686,10 @@ configuration (.cfg and .bnd) files. (NOTE: PhysiCell does *not* support the ful + If a PhysiCell model uses an intracellular model, the PhysiCell Makefile will run a Python script (in the /beta directory) that checks to see if you have already downloaded the software (library) for the intracellular solver and, if not, downloads it and puts it in a directory within your PhysiCell project where it can be found and linked. The Python script will download the appropriate library for your operating system. ### Minor new features and changes: +#### Version 1.9.1: ++ Implemented basic_volume_model (see standard models), where nuclear volumes are set to zero, and cytoplasmic volumes are updated as normal. +#### Version 1.9.0: + Added `intracellular` XML element (inside `phenotype`) that specifies the type of intracellular model, its model definition file, its PhysiCell dt value to be evaluated, and relevant mappings between it and PhysiCell data. + Added Python scripts in /beta to download intracellular solver libraries: setup_libroadrunner.py, setup_libmaboss.py, setup_fba.py @@ -1508,7 +716,10 @@ However, it is up to each intracellular model as to how, or if, it will be used. + Bug fix and improvements to /beta/params_run.py to perform parameter explorations of models. ### Beta features (not fully supported): - +#### Version 1.9.1: ++ No new beta features this release. + +#### Version 1.9.0: + Started writing a standardized set of functions for Hill functions and promoter/inhibitor signaling. + [Model Builder Tool](https://github.com/PhysiCell-Tools/PhysiCell-model-builder/releases) @@ -1520,7 +731,18 @@ However, it is up to each intracellular model as to how, or if, it will be used. + Added simple contour plotting of a substrate (anim_substrate2D.py in /beta; copy to /output) ### Bugfixes: +#### Version 1.9.1: ++ Fixed bug in legend function where on some rare occasions, the temporary cell could adversely interact with other cells prior to deletion. + ++ Remove an old error printout from standard_elastic_contact_function that causes problem with the ANCIENT version of gcc (4.8.x) that nanoHUB refuses to upgrade. ++ Fixed Libroadrunner memory leak issue. + ++ Made minor bugfixes to parsing cell definitions in the XML configuration files: + + verify motility enabled flag is present before parsing its value + + fix bug when parsing multiple death models + +#### Version 1.9.0: + In core/PhysiCell_cell.cpp, replace `switch` statement with `if`/`else if` to prevent compiler errors related to `static const int` from PhysiCell_constants. + core/PhysiCell_cell.cpp: assign_position(double x, double y, double z): make sure the current mechanics voxel is initialized. @@ -1540,6 +762,8 @@ However, it is up to each intracellular model as to how, or if, it will be used. + We will change the timing of when entry_functions are executed within cycle models. Right now, they are evaluated immediately after the exit from the preceding phase (and prior to any cell division events), which means that only the parent cell executes it, rather htan both daughter cells. Instead, we'll add an internal Boolean for "just exited a phase", and use this to exucte the entry function at the next cycle call. This should make daughter cells independently execute the entry function. + We might make "trigger_death" clear out all the cell's functions, or at least add an option to do this. + ++ We will most probably merge all of "core" and "modules" into "core." ### Planned future improvements: diff --git a/config/PhysiCell_settings.xml b/config/PhysiCell_settings.xml index 5164a3782..88367683e 100644 --- a/config/PhysiCell_settings.xml +++ b/config/PhysiCell_settings.xml @@ -1,83 +1,9 @@ - - - - - - -500 - 500 - -500 - 500 + -1000 + 1000 + -1000 + 1000 -10 10 20 @@ -87,7 +13,7 @@ - 7200 + 64800 min micron @@ -97,11 +23,11 @@ - 4 + 6 - output + output 60 @@ -109,7 +35,7 @@ - 15 + 60 true @@ -120,78 +46,35 @@ false + true - - - 100.0 - 0 - - 1 - 0 - - - - - - - 1000.0 - .1 - - 0 - 0 - - - - - - - 1000.0 - .1 - - 0 - 0 - - - - - - + + + 100000.0 + 0.1 + + 38 + 38 + + 38 + 38 + 38 + 38 + 38 + 38 + + + + true true - + ./config/initial.mat - + ./config/dirichlet.mat @@ -199,251 +82,153 @@ - - - - - - - - - 0.0 - - - - - - - - - 0 - - - - 516 - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 - 0 - 2.0 - - - - - 0.0 - - - - - 0 - 86400 - - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 - 0 - 2.0 - - - - - - 2494 - 0.75 - 540 - - 0.05 - 0.0045 - 0.0055 - - 0 - 0 - - 2.0 - - - - 0 - 10.0 - 1.25 - - - 1.8 - 15.12 - - - - - 0.25 - 5 - 0.5 - - - true - true - - false - food - -1 - - - - - - - 100 - 1 - 0 - 0 - - - - 0 - 1 - 0 - 0 - - - - 0 - 1 - 0 - 0 - - - - - - - 1.0 - 1.0 - 1.0 - - -1 - -1 - -10 - - - - - - - - - - - - 0.003 - - - - - 0 - 1 - - - - 10 - - - - 0.5 - 5 - 0.5 - - true - true - - false - food - 1 - - - - - - 1.0 - 1.0 - 1.0 - - -100 - 10 - 1 - - - - - - - - 0 - 0 - - - - 10 - - - - 0.5 - 2.5 - 0.7 - - - true - true - - false - prey signal - 1 - - - - - - 1.0 - 1.0 - 1.0 - - -2 - 100 - 1 - - - - + + + + + 0.00072 + + + + + + 5.31667e-05 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + + 1 + 1 + .5 + + false + true + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + + 0 + 1 + 10 + 0 + + + + + 0 + + 0 + + + + 0 + + + 1 + + 0 + + + + + + + 0 + + + + + + 1.0 + + + + + + + + ./config + cells.csv + + - 0 - - - - - 15 - + 0 + 5 + 250 + 1 + 0.25 + 0.0 + 2 + - + \ No newline at end of file diff --git a/core/PhysiCell.h b/core/PhysiCell.h index b2724e32f..2f8e4f760 100644 --- a/core/PhysiCell.h +++ b/core/PhysiCell.h @@ -72,7 +72,7 @@ #include #include -static std::string PhysiCell_Version = "1.10.4"; +static std::string PhysiCell_Version = "1.11.0"; static std::string PhysiCell_URL = "http://PhysiCell.MathCancer.org"; static std::string PhysiCell_DOI = "10.1371/journal.pcbi.1005991"; diff --git a/core/PhysiCell_basic_signaling.cpp b/core/PhysiCell_basic_signaling.cpp index e60a1c9a7..798100e97 100644 --- a/core/PhysiCell_basic_signaling.cpp +++ b/core/PhysiCell_basic_signaling.cpp @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # @@ -201,5 +201,16 @@ double decreasing_linear_response_function( double s, double s_min , double s_ma return s; } +double interpolate_behavior( double base_value , double max_changed_value, double response ) +{ + double output = max_changed_value; // bM + output -= base_value; // (bM-b0); + output *= response; // R*(bM-b0); + output += base_value; // b0 + (bM-b0)*R; + return output; +} + + + }; diff --git a/core/PhysiCell_basic_signaling.h b/core/PhysiCell_basic_signaling.h index 5eb51a3f2..dfd1f044e 100644 --- a/core/PhysiCell_basic_signaling.h +++ b/core/PhysiCell_basic_signaling.h @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # @@ -85,6 +85,8 @@ double linear_response_function( double s, double s_min , double s_max ); // don // decreases from 1 (at s_min) to 0 (at s_max) double decreasing_linear_response_function( double s, double s_min , double s_max ); // done +double interpolate_behavior( double base_value , double max_changed_value, double response ); + // signal increases/decreases parameter // options: hill power // options: half max diff --git a/core/PhysiCell_cell.cpp b/core/PhysiCell_cell.cpp index ac3fa52a4..9e6fb01fb 100644 --- a/core/PhysiCell_cell.cpp +++ b/core/PhysiCell_cell.cpp @@ -226,11 +226,14 @@ Cell_Definition cell_defaults; Cell_State::Cell_State() { neighbors.resize(0); + spring_attachments.resize(0); + orientation.resize( 3 , 0.0 ); simple_pressure = 0.0; attached_cells.clear(); + spring_attachments.clear(); number_of_nuclei = 1; @@ -420,6 +423,8 @@ Cell::~Cell() { // release any attached cells (as of 1.7.2 release) this->remove_all_attached_cells(); + // 1.11.0 + this->remove_all_spring_attachments(); // released internalized substrates (as of 1.5.x releases) this->release_internalized_substrates(); @@ -509,6 +514,7 @@ Cell* Cell::divide( ) // make sure ot remove adhesions remove_all_attached_cells(); + remove_all_spring_attachments(); // version 1.10.3: // conserved quantitites in custom data aer divided in half @@ -598,9 +604,10 @@ Cell* Cell::divide( ) // child->set_phenotype( phenotype ); child->phenotype = phenotype; - if (child->phenotype.intracellular) + if (child->phenotype.intracellular){ child->phenotype.intracellular->start(); - + child->phenotype.intracellular->inherit(this); + } // #ifdef ADDON_PHYSIDFBA // child->fba_model = this->fba_model; // #endif @@ -1057,6 +1064,9 @@ Cell* create_cell( Cell_Definition& cd ) pNew->functions = cd.functions; pNew->phenotype = cd.phenotype; + if (pNew->phenotype.intracellular) + pNew->phenotype.intracellular->start(); + pNew->is_movable = cd.is_movable; // true; pNew->is_out_of_domain = false; pNew->displacement.resize(3,0.0); // state? @@ -1101,6 +1111,8 @@ void delete_cell( int index ) // release any attached cells (as of 1.7.2 release) pDeleteMe->remove_all_attached_cells(); + // 1.11.0 + pDeleteMe->remove_all_spring_attachments(); // released internalized substrates (as of 1.5.x releases) pDeleteMe->release_internalized_substrates(); @@ -1130,6 +1142,8 @@ void delete_cell_original( int index ) // before June 11, 2020 // release any attached cells (as of 1.7.2 release) (*all_cells)[index]->remove_all_attached_cells(); + // 1.11.0 + (*all_cells)[index]->remove_all_spring_attachments(); // released internalized substrates (as of 1.5.x releases) (*all_cells)[index]->release_internalized_substrates(); @@ -1335,6 +1349,7 @@ void Cell::ingest_cell( Cell* pCell_to_eat ) // things that have their own thread safety pCell_to_eat->flag_for_removal(); pCell_to_eat->remove_all_attached_cells(); + pCell_to_eat->remove_all_spring_attachments(); return; } @@ -1495,6 +1510,7 @@ void Cell::fuse_cell( Cell* pCell_to_fuse ) // things that have their own thread safety pCell_to_fuse->flag_for_removal(); pCell_to_fuse->remove_all_attached_cells(); + pCell_to_fuse->remove_all_spring_attachments(); return; } @@ -3040,6 +3056,7 @@ void initialize_cell_definitions_from_pugixml( pugi::xml_node root ) std::cout << "virtual_wall_at_domain_edge: enabled" << std::endl; cell_defaults.functions.add_cell_basement_membrane_interactions = standard_domain_edge_avoidance_interactions; } + } // first, let's pre-build the map. @@ -3098,6 +3115,23 @@ void Cell::attach_cell( Cell* pAddMe ) return; } +void Cell::attach_cell_as_spring( Cell* pAddMe ) +{ + #pragma omp critical + { + bool already_attached = false; + for( int i=0 ; i < state.spring_attachments.size() ; i++ ) + { + if( state.spring_attachments[i] == pAddMe ) + { already_attached = true; } + } + if( already_attached == false ) + { state.spring_attachments.push_back( pAddMe ); } + } + // pAddMe->attach_cell( this ); + return; +} + void Cell::detach_cell( Cell* pRemoveMe ) { #pragma omp critical @@ -3122,6 +3156,30 @@ void Cell::detach_cell( Cell* pRemoveMe ) return; } +void Cell::detach_cell_as_spring( Cell* pRemoveMe ) +{ + #pragma omp critical + { + bool found = false; + int i = 0; + while( !found && i < state.spring_attachments.size() ) + { + // if pRemoveMe is in the cell's list, remove it + if( state.spring_attachments[i] == pRemoveMe ) + { + int n = state.spring_attachments.size(); + // copy last entry to current position + state.spring_attachments[i] = state.spring_attachments[n-1]; + // shrink by one + state.spring_attachments.pop_back(); + found = true; + } + i++; + } + } + return; +} + void Cell::remove_all_attached_cells( void ) { { @@ -3136,6 +3194,21 @@ void Cell::remove_all_attached_cells( void ) return; } +void Cell::remove_all_spring_attachments( void ) +{ + { + // remove self from any attached cell's list. + for( int i = 0; i < state.spring_attachments.size() ; i++ ) + { + state.spring_attachments[i]->detach_cell_as_spring( this ); + } + // clear my list + state.spring_attachments.clear(); + } + return; +} + + void attach_cells( Cell* pCell_1, Cell* pCell_2 ) { pCell_1->attach_cell( pCell_2 ); @@ -3143,6 +3216,13 @@ void attach_cells( Cell* pCell_1, Cell* pCell_2 ) return; } +void attach_cells_as_spring( Cell* pCell_1, Cell* pCell_2 ) +{ + pCell_1->attach_cell_as_spring( pCell_2 ); + pCell_2->attach_cell_as_spring( pCell_1 ); + return; +} + void detach_cells( Cell* pCell_1 , Cell* pCell_2 ) { pCell_1->detach_cell( pCell_2 ); @@ -3150,6 +3230,13 @@ void detach_cells( Cell* pCell_1 , Cell* pCell_2 ) return; } +void detach_cells_as_spring( Cell* pCell_1 , Cell* pCell_2 ) +{ + pCell_1->detach_cell_as_spring( pCell_2 ); + pCell_2->detach_cell_as_spring( pCell_1 ); + return; +} + std::vector find_nearby_cells( Cell* pCell ) { std::vector neighbors = {}; diff --git a/core/PhysiCell_cell.h b/core/PhysiCell_cell.h index 657a9b550..c30f90442 100644 --- a/core/PhysiCell_cell.h +++ b/core/PhysiCell_cell.h @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # @@ -142,6 +142,7 @@ class Cell_State private: public: std::vector attached_cells; + std::vector spring_attachments; std::vector neighbors; std::vector orientation; @@ -231,6 +232,10 @@ class Cell : public Basic_Agent void detach_cell( Cell* pRemoveMe ); // done void remove_all_attached_cells( void ); // done + void attach_cell_as_spring( Cell* pAddMe ); // done + void detach_cell_as_spring( Cell* pRemoveMe ); // done + void remove_all_spring_attachments( void ); // done + // I want to eventually deprecate this, by ensuring that // critical BioFVM and PhysiCell data elements are synced when they are needed @@ -286,6 +291,10 @@ extern std::vector (*cell_division_orientation)(void); void attach_cells( Cell* pCell_1, Cell* pCell_2 ); void detach_cells( Cell* pCell_1 , Cell* pCell_2 ); +void attach_cells_as_spring( Cell* pCell_1, Cell* pCell_2 ); +void detach_cells_as_spring( Cell* pCell_1 , Cell* pCell_2 ); + + std::vector find_nearby_cells( Cell* pCell ); // new in 1.8.0 std::vector find_nearby_interacting_cells( Cell* pCell ); // new in 1.8.0 diff --git a/core/PhysiCell_cell_container.cpp b/core/PhysiCell_cell_container.cpp index 13fe12008..7108f2250 100644 --- a/core/PhysiCell_cell_container.cpp +++ b/core/PhysiCell_cell_container.cpp @@ -138,21 +138,24 @@ void Cell_Container::update_all_cells(double t, double phenotype_dt_ , double me static double phenotype_dt_tolerance = 0.001 * phenotype_dt_; static double mechanics_dt_tolerance = 0.001 * mechanics_dt_; - + // intracellular update. called for every diffusion_dt, but actually depends on the intracellular_dt of each cell (as it can be noisy) #pragma omp parallel for for( int i=0; i < (*all_cells).size(); i++ ) { - if( (*all_cells)[i]->phenotype.intracellular != NULL && (*all_cells)[i]->phenotype.intracellular->need_update()) - { - if ((*all_cells)[i]->functions.pre_update_intracellular != NULL) - (*all_cells)[i]->functions.pre_update_intracellular( (*all_cells)[i], (*all_cells)[i]->phenotype , diffusion_dt_ ); + if( (*all_cells)[i]->is_out_of_domain == false && initialzed ) { - (*all_cells)[i]->phenotype.intracellular->update( (*all_cells)[i], (*all_cells)[i]->phenotype , diffusion_dt_ ); + if( (*all_cells)[i]->phenotype.intracellular != NULL && (*all_cells)[i]->phenotype.intracellular->need_update()) + { + if ((*all_cells)[i]->functions.pre_update_intracellular != NULL) + (*all_cells)[i]->functions.pre_update_intracellular( (*all_cells)[i], (*all_cells)[i]->phenotype , diffusion_dt_ ); - if ((*all_cells)[i]->functions.post_update_intracellular != NULL) - (*all_cells)[i]->functions.post_update_intracellular( (*all_cells)[i], (*all_cells)[i]->phenotype , diffusion_dt_ ); + (*all_cells)[i]->phenotype.intracellular->update( (*all_cells)[i], (*all_cells)[i]->phenotype , diffusion_dt_ ); + + if ((*all_cells)[i]->functions.post_update_intracellular != NULL) + (*all_cells)[i]->functions.post_update_intracellular( (*all_cells)[i], (*all_cells)[i]->phenotype , diffusion_dt_ ); + } } } @@ -241,6 +244,33 @@ void Cell_Container::update_all_cells(double t, double phenotype_dt_ , double me { pC->functions.update_velocity( pC,pC->phenotype,time_since_last_mechanics ); } } + // new March 2023: + // dynamic spring attachments, followed by built-in springs + + if( PhysiCell_settings.disable_automated_spring_adhesions == false ) + { + #pragma omp parallel for + for( int i=0; i < (*all_cells).size(); i++ ) + { + Cell* pC = (*all_cells)[i]; + dynamic_spring_attachments(pC,pC->phenotype,time_since_last_mechanics); + } + #pragma omp parallel for + for( int i=0; i < (*all_cells).size(); i++ ) + { + Cell* pC = (*all_cells)[i]; + if( pC->is_movable ) + { + for( int j=0; j < pC->state.spring_attachments.size(); j++ ) + { + Cell* pC1 = pC->state.spring_attachments[j]; + // standard_elastic_contact_function_confluent_rest_length(pC,pC->phenotype,pC1,pC1->phenotype,time_since_last_mechanics); + standard_elastic_contact_function(pC,pC->phenotype,pC1,pC1->phenotype,time_since_last_mechanics); + } + } + } + } + // new March 2022: // run standard interactions (phagocytosis, attack, fusion) here #pragma omp parallel for @@ -310,6 +340,10 @@ void Cell_Container::add_agent_to_outer_voxel(Cell* agent) void Cell_Container::remove_agent_from_voxel(Cell* agent, int voxel_index) { + if (voxel_index < 0) + { + return; + } int delete_index = 0; while( agent_grid[voxel_index][ delete_index ] != agent ) { diff --git a/core/PhysiCell_custom.cpp b/core/PhysiCell_custom.cpp index 505d42fc4..8885084cb 100644 --- a/core/PhysiCell_custom.cpp +++ b/core/PhysiCell_custom.cpp @@ -101,7 +101,13 @@ Vector_Variable::Vector_Variable() std::ostream& operator<<(std::ostream& os, const Vector_Variable& v) { - os << v.name << ": "; + os << v.name << ": "; + if( v.value.size() == 0 ) + { os << "[empty]"; return os; } +/* + if( v.value.size() == 1 ) + { os << v.value[0] << " (" << v.units << ")"; return os; } +*/ for( int i=0; i < v.value.size()-1 ; i++ ) { os << v.value[i] << ","; } os << v.value[v.value.size()-1] << " (" << v.units << ")"; diff --git a/core/PhysiCell_phenotype.cpp b/core/PhysiCell_phenotype.cpp index 4af347e4d..d6ae129a0 100644 --- a/core/PhysiCell_phenotype.cpp +++ b/core/PhysiCell_phenotype.cpp @@ -690,7 +690,7 @@ Mechanics::Mechanics() maximum_number_of_attachments = 12; attachment_elastic_constant = 0.01; - attachment_rate = 10; + attachment_rate = 0; // 10.0 prior ot March 2023 detachment_rate = 0; /* to be deprecated */ @@ -698,9 +698,7 @@ Mechanics::Mechanics() relative_detachment_distance = relative_maximum_adhesion_distance; maximum_attachment_rate = 1.0; - - maximum_attachment_rate = 1.0; - + return; } @@ -1266,6 +1264,7 @@ Cell_Interactions::Cell_Interactions() live_phagocytosis_rates = {0.0}; damage_rate = 1.0; attack_rates = {0.0}; + immunogenicities = {1}; fusion_rates = {0.0}; return; @@ -1281,6 +1280,7 @@ void Cell_Interactions::sync_to_cell_definitions() live_phagocytosis_rates.resize( number_of_cell_defs, 0.0); attack_rates.resize( number_of_cell_defs, 0.0); fusion_rates.resize( number_of_cell_defs, 0.0); + immunogenicities.resize( number_of_cell_defs , 1.0 ); } return; @@ -1309,6 +1309,13 @@ double& Cell_Interactions::fusion_rate( std::string type_name ) return fusion_rates[n]; } +double& Cell_Interactions::immunogenicity( std::string type_name ) +{ + extern std::unordered_map cell_definition_indices_by_name; + int n = cell_definition_indices_by_name[type_name]; + return immunogenicities[n]; +} + Cell_Transformations::Cell_Transformations() { transformation_rates = {0.0}; diff --git a/core/PhysiCell_phenotype.h b/core/PhysiCell_phenotype.h index bc80948c2..d7134ec41 100644 --- a/core/PhysiCell_phenotype.h +++ b/core/PhysiCell_phenotype.h @@ -611,6 +611,9 @@ class Intracellular virtual void update() = 0; virtual void update(Cell* cell, Phenotype& phenotype, double dt) = 0; + // This function deals with inheritance from mother to daughter cells + virtual void inherit(Cell* cell) = 0; + // Get value for model parameter virtual double get_parameter_value(std::string name) = 0; @@ -650,7 +653,13 @@ class Cell_Interactions double dead_phagocytosis_rate; std::vector live_phagocytosis_rates; // attack parameters (e.g., T cells) + std::vector attack_rates; + // do I attack cell type j? + + std::vector immunogenicities; // new! + // how immnogenic am I to cell type j? + double damage_rate; // cell fusion parameters std::vector fusion_rates; @@ -663,6 +672,7 @@ class Cell_Interactions double& live_phagocytosis_rate( std::string type_name ); // done double& attack_rate( std::string type_name ); // done double& fusion_rate( std::string type_name ); // done + double& immunogenicity( std::string type_name ); // done // automated cell phagocytosis, attack, and fusion // void perform_interactions( Cell* pCell, Phenotype& phenotype, double dt ); diff --git a/core/PhysiCell_signal_behavior.cpp b/core/PhysiCell_signal_behavior.cpp index 97b65c72c..3b37168da 100644 --- a/core/PhysiCell_signal_behavior.cpp +++ b/core/PhysiCell_signal_behavior.cpp @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # @@ -232,6 +232,37 @@ void setup_signal_behavior_dictionaries( void ) signal_to_int[custom_signal_name] = map_index; } + map_index++; + signal_to_int["apoptotic"] = map_index; + int_to_signal[map_index] = "apoptotic"; + // synonyms + signal_to_int["is_apoptotic"] = map_index; + + map_index++; + signal_to_int["necrotic"] = map_index; + int_to_signal[map_index] = "necrotic"; + // synonyms + signal_to_int["is_necrotic"] = map_index; + +/* + // immunogenicity to each cell type + for( int i=0; i < n ; i++ ) + { + map_index++; + Cell_Definition* pCD = cell_definitions_by_type[i]; + std::string temp = "immunogenicity to " + pCD->name; + signal_to_int[temp] = map_index; + int_to_signal[map_index] = temp; + // synonyms + std::string temp1 = "immunogenicity to cell type " + std::to_string( pCD->type ); + signal_to_int[temp1] = map_index; + } +*/ + + + + /* add new signals above this line */ + behavior_to_int.clear(); int_to_behavior.clear(); @@ -463,6 +494,45 @@ void setup_signal_behavior_dictionaries( void ) behavior_to_int[custom_behavior_name] = map_index; } + map_index++; + map_name = "is_movable"; + behavior_to_int[map_name ] = map_index; + int_to_behavior[map_index] = map_name; + // synonyms + behavior_to_int["movable"] = map_index; + behavior_to_int["is movable"] = map_index; + + // immunogenicity to each cell type + for( int i=0; i < n ; i++ ) + { + map_index++; + Cell_Definition* pCD = cell_definitions_by_type[i]; + std::string map_name = "immunogenicity to " + pCD->name; + behavior_to_int[map_name ] = map_index; + int_to_behavior[map_index] = map_name; + + // synonyms + std::string temp1 = "immunogenicity to cell type " + std::to_string( pCD->type ); + behavior_to_int[temp1] = map_index; + } + + map_index++; + map_name = "cell attachment rate"; + behavior_to_int[map_name ] = map_index; + int_to_behavior[map_index] = map_name; + + map_index++; + map_name = "cell detachment rate"; + behavior_to_int[map_name ] = map_index; + int_to_behavior[map_index] = map_name; + + map_index++; + map_name = "maximum number of cell attachments"; + behavior_to_int[map_name ] = map_index; + int_to_behavior[map_index] = map_name; + + /* add new behaviors above this line */ + // resize scales; signal_scales.resize( int_to_signal.size() , 1.0 ); @@ -541,6 +611,9 @@ int find_signal_index( std::string signal_name ) // safety first! if( search != signal_to_int.end() ) { return search->second; } + + std::cout << "having trouble finding " << signal_name << std::endl; + return -1; } @@ -667,6 +740,28 @@ std::vector get_signals( Cell* pCell ) { signals[first_custom_ind+nc] = pCell->custom_data.variables[nc].value; } } + static int apoptotic_ind = find_signal_index( "apoptotic" ); + if(pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::apoptotic ) + { signals[apoptotic_ind] = 1; } + else + { signals[apoptotic_ind] = 0; } + + static int necrotic_ind = find_signal_index( "necrotic" ); + if( pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_swelling || + pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_lysed || + pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic ) + { signals[necrotic_ind] = 1; } + else + { signals[necrotic_ind] = 0; } + +/* + // vector of immunogenicity signals + static int start_immunogenicity_ind = find_signal_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + std::copy( pCell->phenotype.cell_interactions.immunogenicities.begin() , + pCell->phenotype.cell_interactions.immunogenicities.end(), + signals.begin()+start_immunogenicity_ind); +*/ + // rescale signals /= signal_scales; @@ -894,6 +989,39 @@ double get_single_signal( Cell* pCell, int index ) return out; } + static int apoptotic_ind = find_signal_index( "apoptotic" ); + if( index == apoptotic_ind ) + { + if(pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::apoptotic ) + { return 1; } + else + { return 0; } + } + + static int necrotic_ind = find_signal_index( "necrotic" ); + if( index == necrotic_ind ) + { + if( pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_swelling || + pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_lysed || + pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic ) + { return 1; } + else + { return 0; } + } + +/* + static int start_immunogenicity_ind = find_signal_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + static int max_immunogenicity_ind = start_immunogenicity_ind+n; + if( start_immunogenicity_ind > -1 && index >= start_immunogenicity_ind && index < max_immunogenicity_ind ) + { + int j = index - start_immunogenicity_ind; + out = pCell->phenotype.cell_interactions.immunogenicities[j]; + out /= signal_scales[index]; + return out; + } +*/ + + // unknown after here ! std::cout << "Warning: Requested unknown signal number " << index << "!" << std::endl @@ -1058,6 +1186,31 @@ void set_behaviors( Cell* pCell , std::vector parameters ) { pCell->custom_data.variables[nc].value = parameters[first_custom_ind+nc]; } } + // set cell to movable / not movable + static int movable_ind = find_behavior_index( "is_movable"); + if( parameters[movable_ind] > 0.5 ) + { pCell->is_movable = true; } + else + { pCell->is_movable = false; } + + // vector of immunogenicity signals + static int start_immunogenicity_ind = find_behavior_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + std::copy( parameters.begin()+start_immunogenicity_ind , + parameters.begin()+start_immunogenicity_ind+n , + pCell->phenotype.cell_interactions.immunogenicities.begin() ); + + // set cell attachment rate + static int attachment_rate_ind = find_behavior_index( "cell attachment rate"); + pCell->phenotype.mechanics.attachment_rate = parameters[attachment_rate_ind]; + + // set cell detachment rate + static int detachment_rate_ind = find_behavior_index( "cell detachment rate"); + pCell->phenotype.mechanics.detachment_rate = parameters[detachment_rate_ind]; + + // maximum number of cell attachments + static int max_attachments_ind = find_behavior_index( "maximum number of cell attachments"); + pCell->phenotype.mechanics.maximum_number_of_attachments = (int) parameters[max_attachments_ind]; + return; } @@ -1207,6 +1360,37 @@ void set_single_behavior( Cell* pCell, int index , double parameter ) if( first_custom_ind >= 0 && index >= first_custom_ind && index < max_custom_ind ) { pCell->custom_data.variables[index-first_custom_ind].value = parameter; } + // set cell to movable / not movable + static int movable_ind = find_behavior_index( "is_movable"); + if( index == movable_ind ) + { + if( parameter > 0.5 ) + { pCell->is_movable = true; } + else + { pCell->is_movable = false; } + } + + // immunogenicity to each cell type + static int first_immunogenicity_index = find_behavior_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + if( index >= first_immunogenicity_index && index < first_immunogenicity_index + n ) + { pCell->phenotype.cell_interactions.immunogenicities[index-first_immunogenicity_index] = parameter ; return; } + + + // set cell attachment rate + static int attachment_rate_ind = find_behavior_index( "cell attachment rate"); + if( index == attachment_rate_ind ) + { pCell->phenotype.mechanics.attachment_rate = parameter; } + + // set cell detachment rate + static int detachment_rate_ind = find_behavior_index( "cell detachment rate"); + if( index == detachment_rate_ind ) + { pCell->phenotype.mechanics.detachment_rate = parameter; } + + // maximum number of cell attachments + static int max_attachments_ind = find_behavior_index( "maximum number of cell attachments"); + if( index == max_attachments_ind ) + { pCell->phenotype.mechanics.maximum_number_of_attachments = (int) parameter; } + return; } @@ -1358,6 +1542,31 @@ std::vector get_behaviors( Cell* pCell ) { parameters[first_custom_ind+nc] = pCell->custom_data.variables[nc].value; } } + // is the cell movable / not movable + static int movable_ind = find_behavior_index( "is_movable"); + if( pCell->is_movable == true ) + { parameters[movable_ind] = 1; } + else + { parameters[movable_ind] = 0; } + + // vector of immunogenicity behaviors + static int start_immunogenicity_ind = find_behavior_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + std::copy( pCell->phenotype.cell_interactions.immunogenicities.begin(), + pCell->phenotype.cell_interactions.immunogenicities.end(), + parameters.begin()+start_immunogenicity_ind ); + + // get cell attachment rate + static int attachment_rate_ind = find_behavior_index( "cell attachment rate"); + parameters[attachment_rate_ind] = pCell->phenotype.mechanics.attachment_rate; + + // get cell detachment rate + static int detachment_rate_ind = find_behavior_index( "cell detachment rate"); + parameters[detachment_rate_ind] = pCell->phenotype.mechanics.detachment_rate; + + // maximum number of cell attachments + static int max_attachments_ind = find_behavior_index( "maximum number of cell attachments"); + parameters[max_attachments_ind] = pCell->phenotype.mechanics.maximum_number_of_attachments; + return parameters; } @@ -1482,7 +1691,7 @@ double get_single_behavior( Cell* pCell , int index ) { return pCell->phenotype.mechanics.cell_BM_repulsion_strength; } // dead cell phagocytosis - static int dead_phag_index = find_behavior_index("phagocytose dead dell" ); + static int dead_phag_index = find_behavior_index("phagocytose dead cell" ); if( index == dead_phag_index ) { return pCell->phenotype.cell_interactions.dead_phagocytosis_rate; } @@ -1512,6 +1721,38 @@ double get_single_behavior( Cell* pCell , int index ) if( first_custom_ind >= 0 && index >= first_custom_ind && index < max_custom_ind ) { return pCell->custom_data.variables[index-first_custom_ind].value; } + // is the cell movable / not movable + static int movable_ind = find_behavior_index( "is_movable"); + if( index == movable_ind ) + { + if( pCell->is_movable == true ) + { return 1.0; } + else + { return 0.0; } + } + + // vector of immunogenicity behaviors + static int start_immunogenicity_ind = find_behavior_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + static int max_immunogenicity_ind = start_immunogenicity_ind + n; + if( start_immunogenicity_ind > -1 && index >= start_immunogenicity_ind && index < max_immunogenicity_ind ) + { return pCell->phenotype.cell_interactions.immunogenicities[index-start_immunogenicity_ind]; } + + + // set cell attachment rate + static int attachment_rate_ind = find_behavior_index( "cell attachment rate"); + if( index == attachment_rate_ind ) + return pCell->phenotype.mechanics.attachment_rate; + + // set cell detachment rate + static int detachment_rate_ind = find_behavior_index( "cell detachment rate"); + if( index == detachment_rate_ind ) + { return pCell->phenotype.mechanics.detachment_rate; } + + // maximum number of cell attachments + static int max_attachments_ind = find_behavior_index( "maximum number of cell attachments"); + if( index == max_attachments_ind ) + { return pCell->phenotype.mechanics.maximum_number_of_attachments; } + return -1; } @@ -1693,6 +1934,32 @@ std::vector get_base_behaviors( Cell* pCell ) { parameters[first_custom_ind+nc] = pCD->custom_data.variables[nc].value; } } + // is the cell movable / not movable + static int movable_ind = find_behavior_index( "is_movable"); + if( pCD->is_movable == true ) + { parameters[movable_ind] = 1; } + else + { parameters[movable_ind] = 0; } + + // vector of immunogenicity behaviors + static int start_immunogenicity_ind = find_behavior_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + std::copy( pCD->phenotype.cell_interactions.immunogenicities.begin(), + pCD->phenotype.cell_interactions.immunogenicities.end(), + parameters.begin()+start_immunogenicity_ind ); + + + // set cell attachment rate + static int attachment_rate_ind = find_behavior_index( "cell attachment rate"); + parameters[attachment_rate_ind] = pCD->phenotype.mechanics.attachment_rate; + + // set cell detachment rate + static int detachment_rate_ind = find_behavior_index( "cell detachment rate"); + parameters[detachment_rate_ind] = pCD->phenotype.mechanics.detachment_rate; + + // maximum number of cell attachments + static int max_attachments_ind = find_behavior_index( "maximum number of cell attachments"); + parameters[max_attachments_ind] = pCD->phenotype.mechanics.maximum_number_of_attachments; + return parameters; } @@ -1819,7 +2086,7 @@ double get_single_base_behavior( Cell* pCell , int index ) { return pCD->phenotype.mechanics.cell_BM_repulsion_strength; } // dead cell phagocytosis - static int dead_phag_index = find_behavior_index("phagocytose dead dell" ); + static int dead_phag_index = find_behavior_index("phagocytose dead cell" ); if( index == dead_phag_index ) { return pCD->phenotype.cell_interactions.dead_phagocytosis_rate; } @@ -1849,6 +2116,38 @@ double get_single_base_behavior( Cell* pCell , int index ) if( first_custom_ind >= 0 && index >= first_custom_ind && index < max_custom_ind ) { return pCD->custom_data.variables[index-first_custom_ind].value; } + // is the cell movable / not movable + static int movable_ind = find_behavior_index( "is_movable"); + if( index == movable_ind ) + { + if( pCD->is_movable == true ) + { return 1.0; } + else + { return 0.0; } + } + + // vector of immunogenicity behaviors + static int start_immunogenicity_ind = find_behavior_index( "immunogenicity to " + cell_definitions_by_type[0]->name ); + static int max_immunogenicity_ind = start_immunogenicity_ind + n; + if( start_immunogenicity_ind > -1 && index >= start_immunogenicity_ind && index < max_immunogenicity_ind ) + { return pCD->phenotype.cell_interactions.immunogenicities[index-start_immunogenicity_ind]; } + + + // set cell attachment rate + static int attachment_rate_ind = find_behavior_index( "cell attachment rate"); + if( index == attachment_rate_ind ) + { return pCD->phenotype.mechanics.attachment_rate; } + + // set cell detachment rate + static int detachment_rate_ind = find_behavior_index( "cell detachment rate"); + if( index == detachment_rate_ind ) + { return pCD->phenotype.mechanics.detachment_rate; } + + // maximum number of cell attachments + static int max_attachments_ind = find_behavior_index( "maximum number of cell attachments"); + if( index == max_attachments_ind ) + { return pCD->phenotype.mechanics.maximum_number_of_attachments; } + return -1; } diff --git a/core/PhysiCell_signal_behavior.h b/core/PhysiCell_signal_behavior.h index b7fcc77c9..78483224c 100644 --- a/core/PhysiCell_signal_behavior.h +++ b/core/PhysiCell_signal_behavior.h @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # diff --git a/core/PhysiCell_standard_models.cpp b/core/PhysiCell_standard_models.cpp index 818654a67..b0d99669c 100644 --- a/core/PhysiCell_standard_models.cpp +++ b/core/PhysiCell_standard_models.cpp @@ -545,12 +545,11 @@ void standard_volume_update_function( Cell* pCell, Phenotype& phenotype, double phenotype.volume.nuclear = phenotype.volume.nuclear_solid + phenotype.volume.nuclear_fluid; phenotype.volume.cytoplasmic = phenotype.volume.cytoplasmic_solid + phenotype.volume.cytoplasmic_fluid; - phenotype.volume.calcified_fraction = dt * phenotype.volume.calcification_rate + phenotype.volume.calcified_fraction += dt * phenotype.volume.calcification_rate * (1- phenotype.volume.calcified_fraction); phenotype.volume.total = phenotype.volume.cytoplasmic + phenotype.volume.nuclear; - - + phenotype.volume.fluid_fraction = phenotype.volume.fluid / ( 1e-16 + phenotype.volume.total ); @@ -995,6 +994,37 @@ void standard_elastic_contact_function( Cell* pC1, Phenotype& p1, Cell* pC2, Phe return; } +void standard_elastic_contact_function_confluent_rest_length( Cell* pC1, Phenotype& p1, Cell* pC2, Phenotype& p2 , double dt ) +{ + if( pC1->position.size() != 3 || pC2->position.size() != 3 ) + { return; } + + std::vector displacement = pC2->position; + displacement -= pC1->position; + + // update May 2022 - effective adhesion + int ii = find_cell_definition_index( pC1->type ); + int jj = find_cell_definition_index( pC2->type ); + + double adhesion_ii = pC1->phenotype.mechanics.attachment_elastic_constant * pC1->phenotype.mechanics.cell_adhesion_affinities[jj]; + double adhesion_jj = pC2->phenotype.mechanics.attachment_elastic_constant * pC2->phenotype.mechanics.cell_adhesion_affinities[ii]; + + double effective_attachment_elastic_constant = sqrt( adhesion_ii*adhesion_jj ); + // axpy( &(pC1->velocity) , effective_attachment_elastic_constant , displacement ); + + // have the adhesion strength taper away at this rest lenght + // set the rest length = confluent cell-cell spacing + // + double rest_length = ( p1.geometry.radius + p2.geometry.radius ) * 0.9523809523809523; + + double strength = ( norm(displacement) - rest_length )*effective_attachment_elastic_constant; + normalize( &displacement ); + axpy( &(pC1->velocity) , strength , displacement ); + + return; +} + + void evaluate_interactions( Cell* pCell, Phenotype& phenotype, double dt ) { if( pCell->functions.contact_function == NULL ) @@ -1192,7 +1222,14 @@ void standard_cell_cell_interactions( Cell* pCell, Phenotype& phenotype, double // attack // assume you can only attack one cell at a time - probability = phenotype.cell_interactions.attack_rate(type_name)*dt; // s[type] * dt; + // probability = phenotype.cell_interactions.attack_rate(type_name)*dt; // s[type] * dt; + + double attack_ij = phenotype.cell_interactions.attack_rate(type_name); + double immunogenicity_ji = pTarget->phenotype.cell_interactions.immunogenicity(pCell->type_name); + + probability = attack_ij * immunogenicity_ji * dt; + + dt; // s[type] * dt; if( UniformRandom() < probability && attacked == false ) { pCell->attack_cell(pTarget,dt); @@ -1229,5 +1266,90 @@ void standard_cell_transformations( Cell* pCell, Phenotype& phenotype, double dt } } + +void dynamic_attachments( Cell* pCell , Phenotype& phenotype, double dt ) +{ + // check for detachments + double detachment_probability = phenotype.mechanics.detachment_rate * dt; + for( int j=0; j < pCell->state.attached_cells.size(); j++ ) + { + Cell* pTest = pCell->state.attached_cells[j]; + if( UniformRandom() <= detachment_probability ) + { detach_cells( pCell , pTest ); } + } + + // check if I have max number of attachments + if( pCell->state.attached_cells.size() >= phenotype.mechanics.maximum_number_of_attachments ) + { return; } + + // check for new attachments; + double attachment_probability = phenotype.mechanics.attachment_rate * dt; + bool done = false; + int j = 0; + while( done == false && j < pCell->state.neighbors.size() ) + { + Cell* pTest = pCell->state.neighbors[j]; + if( pTest->state.number_of_attached_cells() < pTest->phenotype.mechanics.maximum_number_of_attachments ) + { + // std::string search_string = "adhesive affinity to " + pTest->type_name; + // double affinity = get_single_behavior( pCell , search_string ); + double affinity = phenotype.mechanics.cell_adhesion_affinity(pTest->type_name); + + double prob = attachment_probability * affinity; + if( UniformRandom() <= prob ) + { + // attempt the attachment. testing for prior connection is already automated + attach_cells( pCell, pTest ); + if( pCell->state.attached_cells.size() >= phenotype.mechanics.maximum_number_of_attachments ) + { done = true; } + } + } + j++; + } + return; +} + +void dynamic_spring_attachments( Cell* pCell , Phenotype& phenotype, double dt ) +{ + // check for detachments + double detachment_probability = phenotype.mechanics.detachment_rate * dt; + for( int j=0; j < pCell->state.spring_attachments.size(); j++ ) + { + Cell* pTest = pCell->state.spring_attachments[j]; + if( UniformRandom() <= detachment_probability ) + { detach_cells_as_spring( pCell , pTest ); } + } + + // check if I have max number of attachments + if( pCell->state.spring_attachments.size() >= phenotype.mechanics.maximum_number_of_attachments ) + { return; } + + // check for new attachments; + double attachment_probability = phenotype.mechanics.attachment_rate * dt; + bool done = false; + int j = 0; + while( done == false && j < pCell->state.neighbors.size() ) + { + Cell* pTest = pCell->state.neighbors[j]; + if( pTest->state.spring_attachments.size() < pTest->phenotype.mechanics.maximum_number_of_attachments ) + { + // std::string search_string = "adhesive affinity to " + pTest->type_name; + // double affinity = get_single_behavior( pCell , search_string ); + double affinity = phenotype.mechanics.cell_adhesion_affinity(pTest->type_name); + + double prob = attachment_probability * affinity; + if( UniformRandom() <= prob ) + { + // attempt the attachment. testing for prior connection is already automated + attach_cells_as_spring( pCell, pTest ); + if( pCell->state.spring_attachments.size() >= phenotype.mechanics.maximum_number_of_attachments ) + { done = true; } + } + } + j++; + } + return; +} + }; diff --git a/core/PhysiCell_standard_models.h b/core/PhysiCell_standard_models.h index 5e2daf207..b7187c520 100644 --- a/core/PhysiCell_standard_models.h +++ b/core/PhysiCell_standard_models.h @@ -135,6 +135,7 @@ void initialize_default_cell_definition( void ); // done void chemotaxis_function( Cell* pCell, Phenotype& phenotype , double dt ); void standard_elastic_contact_function( Cell* pC1, Phenotype& p1, Cell* pC2, Phenotype& p2 , double dt ); +void standard_elastic_contact_function_confluent_rest_length( Cell* pC1, Phenotype& p1, Cell* pC2, Phenotype& p2 , double dt ); void evaluate_interactions( Cell* pCell, Phenotype& phenotype, double dt ); // new in 1.10.0 @@ -146,6 +147,8 @@ void standard_cell_transformations( Cell* pCell, Phenotype& phenotype, double dt void advanced_chemotaxis_function_normalized( Cell* pCell, Phenotype& phenotype , double dt ); void advanced_chemotaxis_function( Cell* pCell, Phenotype& phenotype , double dt ); +void dynamic_attachments( Cell* pCell , Phenotype& phenotype, double dt ); +void dynamic_spring_attachments( Cell* pCell , Phenotype& phenotype, double dt ); }; diff --git a/documentation/.DS_Store b/documentation/.DS_Store deleted file mode 100644 index fe6625595..000000000 Binary files a/documentation/.DS_Store and /dev/null differ diff --git a/modules/PhysiCell_MultiCellDS.cpp b/modules/PhysiCell_MultiCellDS.cpp index 6c8c6d483..f9843b81e 100644 --- a/modules/PhysiCell_MultiCellDS.cpp +++ b/modules/PhysiCell_MultiCellDS.cpp @@ -1776,7 +1776,7 @@ void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std:: // name = "calcified_fraction"; std::fwrite( &( pCell->phenotype.volume.calcified_fraction ) , sizeof(double) , 1 , fp ); // name = "orientation"; - std::fwrite( &( pCell->state.orientation ) , sizeof(double) , 3 , fp ); + std::fwrite( pCell->state.orientation.data() , sizeof(double) , 3 , fp ); // name = "polarity"; std::fwrite( &( pCell->phenotype.geometry.polarity ) , sizeof(double) , 1 , fp ); @@ -2040,12 +2040,13 @@ void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std:: return; } -void write_neighbor_graph( std::string filename_base ) +void write_neighbor_graph( std::string filename ) { + /* char filename [1024]; sprintf( filename , "%s_cell_neighbor_graph.txt" , filename_base.c_str() ); - /* store filename without the relative pathing (if any) */ + // store filename without the relative pathing (if any) char filename_without_pathing [1024]; char* filename_start = strrchr( filename , '/' ); if( filename_start == NULL ) @@ -2053,6 +2054,7 @@ void write_neighbor_graph( std::string filename_base ) else { filename_start++; } strcpy( filename_without_pathing , filename_start ); + */ std::ofstream of( filename , std::ios::out ); std::stringstream buffer; @@ -2077,12 +2079,13 @@ void write_neighbor_graph( std::string filename_base ) } -void write_attached_cells_graph( std::string filename_base ) +void write_attached_cells_graph( std::string filename ) { + /* char filename [1024]; sprintf( filename , "%s_cell_attached_graph.txt" , filename_base.c_str() ); - /* store filename without the relative pathing (if any) */ + // store filename without the relative pathing (if any) char filename_without_pathing [1024]; char* filename_start = strrchr( filename , '/' ); if( filename_start == NULL ) @@ -2090,6 +2093,7 @@ void write_attached_cells_graph( std::string filename_base ) else { filename_start++; } strcpy( filename_without_pathing , filename_start ); + */ std::ofstream of( filename , std::ios::out ); std::stringstream buffer; diff --git a/modules/PhysiCell_MultiCellDS.h b/modules/PhysiCell_MultiCellDS.h index 68d611a1a..523c2e446 100644 --- a/modules/PhysiCell_MultiCellDS.h +++ b/modules/PhysiCell_MultiCellDS.h @@ -102,8 +102,8 @@ void save_PhysiCell_to_MultiCellDS_xml_pugi_v2( std::string filename_base , Micr void add_PhysiCell_cells_to_open_xml_pugi_v2( pugi::xml_document& xml_dom, std::string filename_base, Microenvironment& M ); void save_PhysiCell_to_MultiCellDS_v2( std::string filename_base , Microenvironment& M , double current_simulation_time); -void write_neighbor_graph( std::string filename_base ); -void write_attached_cells_graph( std::string filename_base ); +void write_neighbor_graph( std::string filename ); +void write_attached_cells_graph( std::string filename ); }; diff --git a/modules/PhysiCell_geometry.cpp b/modules/PhysiCell_geometry.cpp index 044f8bd94..eaeddbcf8 100644 --- a/modules/PhysiCell_geometry.cpp +++ b/modules/PhysiCell_geometry.cpp @@ -225,7 +225,7 @@ void draw_line( std::vector start , std::vector end , Cell_Defin void draw_line( std::vector start , std::vector end , int cell_type , double compression ) { return draw_line(start,end,find_cell_definition(cell_type),compression); } -void load_cells_csv( std::string filename ) +void load_cells_csv_v1( std::string filename ) { std::ifstream file( filename, std::ios::in ); if( !file ) @@ -233,6 +233,10 @@ void load_cells_csv( std::string filename ) std::cout << "Error: " << filename << " not found during cell loading. Quitting." << std::endl; exit(-1); } + else + { + std::cout << "Loading cells from simple (v1) CSV file " << filename << " ... " << std::endl; + } std::string line; while (std::getline(file, line)) @@ -332,4 +336,177 @@ bool load_cells_from_pugixml( pugi::xml_node root ) bool load_cells_from_pugixml( void ) { return load_cells_from_pugixml( physicell_config_root ); } +std::vector split_csv_labels( std::string labels_line ) +{ + std::vector< std::string > label_tokens; + std::string s; + + std::stringstream stream(labels_line); + while( std::getline( stream , s , ',' ) ) + { label_tokens.push_back(s); } + + return label_tokens; +} + +Cell* process_csv_v2_line( std::string line , std::vector labels ) +{ + // split the line into tokens + std::vector< std::string > tokens; + + std::stringstream stream(line); + std::string s; + while( std::getline( stream , s , ',' ) ) + { tokens.push_back(s); } + + // get the cell position + std::vector position; + char* pTemp; + for( int i=0; i < 3 ; i++ ) + { position.push_back( strtod( tokens[i].c_str() , &pTemp ) ); } + + // the cell type + std::string celltype = tokens[3]; + Cell_Definition* pCD = find_cell_definition( celltype ); + if( pCD == NULL ) + { + std::cout << "Warning! CSV file requests creating cell type " << celltype << std::endl + << "\tat " << position << "but I don't recognize that type. Skipping cell!" << std::endl << std::endl; + return NULL; + } + + // create the cell IF the definition was found + std::cout << "Creating " << pCD->name << " (type=" << pCD->type << ") at " + << position << std::endl; + + Cell* pCell = create_cell( *pCD ); + pCell->assign_position( position ); + + // now write any extra data + + for( int k=4 ; k < tokens.size(); k++ ) + { + double dval = strtod(tokens[k].c_str() , &pTemp ); + bool processed = false; + bool skip = false; + + + // if the string is empty, skip + if( tokens[k].size() == 0 ) + { skip = true; } + else + { + char c = tokens[k].c_str()[0]; + // use 's' or 'S' to skip the entry + if( c == 's' || c == 'S' ) + { skip = true; } + } + + // special cases: + + // volume + if( labels[k] == "volume" && skip == false ) + { + pCell->set_total_volume( dval ); + processed = true; + } + + // check behavior dictionary + + if( processed == false && skip == false ) + { + // if the behavior is found in the dictionary, process it + if( find_behavior_index( labels[k] ) > -1 ) + { + set_single_behavior( pCell , labels[k] , dval ); + processed = true; + } + } + + // warning message for any unprocessed variables + if( processed == false && skip == false ) + { + std::cout << "\tWarning: I don't know how to process " << labels[k] + << " so I skipped it." << std::endl; + } + // give a notation for any intentinoally skipped variables + if( skip == true ) + { + std::cout << "\tNote: Skipping " << labels[k] + << " for this cell." << std::endl; + } + + + } + + return pCell; +} + +void load_cells_csv_v2( std::string filename ) +{ + // open file + std::ifstream file( filename, std::ios::in ); + if( !file ) + { + std::cout << "Error: " << filename << " not found during cell loading. Quitting." << std::endl; + exit(-1); + } + else + { + std::cout << "Loading cells from detailed (v2) CSV file " << filename << " ... " << std::endl; + } + + // get the first line (labels) + + std::string line; + std::getline( file , line ); + + // tokenize the labels + + std::vector labels = split_csv_labels( line ); + + // process all remaining lines + + while (std::getline(file, line)) + { process_csv_v2_line(line,labels); } + + // close the file + + file.close(); + std::cout << "Done! " << std::endl << std::endl; + + return; +} + +void load_cells_csv( std::string filename ) +{ + // open file + std::ifstream file( filename, std::ios::in ); + if( !file ) + { + std::cout << "Error: " << filename << " not found during cell loading. Quitting." << std::endl; + exit(-1); + } + + // determine version + std::string line; + std::getline( file , line ); + char c = line.c_str()[0]; + + file.close(); + + if( c == 'X' || c == 'x' ) + { + // v2 + return load_cells_csv_v2( filename ); + } + else + { + // v1 + return load_cells_csv_v1( filename ); + } + + return; +} + + }; diff --git a/modules/PhysiCell_geometry.h b/modules/PhysiCell_geometry.h index a9b750b7a..91e6365fe 100644 --- a/modules/PhysiCell_geometry.h +++ b/modules/PhysiCell_geometry.h @@ -70,6 +70,7 @@ #include #include +#include #include "../core/PhysiCell.h" #include "./PhysiCell_settings.h" @@ -79,14 +80,24 @@ namespace PhysiCell { // loaders -void load_cells_csv( std::string filename ); // done +void load_cells_csv_v1( std::string filename ); // done + + +std::vector split_csv_labels( std::string labels_line ); // done +Cell* process_csv_v2_line( std::string line , std::vector labels ); // done +void load_cells_csv_v2( std::string filename ); // done + + +void load_cells_csv( std::string filename ); + + + void load_cells_mat( std::string filename ); void load_cells_physicell( std::string filename ); bool load_cells_from_pugixml( pugi::xml_node root ); bool load_cells_from_pugixml( void ); // load cells based on default config XML root - // // 2D functions // diff --git a/modules/PhysiCell_pathology.cpp b/modules/PhysiCell_pathology.cpp index 8dba27d41..b42d440a1 100644 --- a/modules/PhysiCell_pathology.cpp +++ b/modules/PhysiCell_pathology.cpp @@ -402,7 +402,7 @@ std::string formatted_minutes_to_DDHHMM( double minutes ) return output ; } -void SVG_plot( std::string filename , Microenvironment& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*) ) +void SVG_plot( std::string filename , Microenvironment& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*), std::vector (*substrate_coloring_function)(double, double, double) ) { double X_lower = M.mesh.bounding_box[0]; double X_upper = M.mesh.bounding_box[3]; @@ -429,11 +429,24 @@ void SVG_plot( std::string filename , Microenvironment& M, double z_slice , doub exit(-1); } - Write_SVG_start( os, plot_width , plot_height + top_margin ); + if(PhysiCell_settings.enable_substrate_plot == true && (*substrate_coloring_function) != NULL){ - // draw the background - Write_SVG_rect( os , 0 , 0 , plot_width, plot_height + top_margin , 0.002 * plot_height , "white", "white" ); + double legend_padding = 200.0; // I have to add a margin on the left to visualize the bar plot and the values + Write_SVG_start( os, plot_width + legend_padding, plot_height + top_margin ); + + // draw the background + Write_SVG_rect( os , 0 , 0 , plot_width + legend_padding, plot_height + top_margin , 0.002 * plot_height , "white", "white" ); + + } + else{ + + Write_SVG_start( os, plot_width , plot_height + top_margin ); + + // draw the background + Write_SVG_rect( os , 0 , 0 , plot_width, plot_height + top_margin , 0.002 * plot_height , "white", "white" ); + + } // write the simulation time to the top of the plot char* szString; @@ -475,6 +488,115 @@ void SVG_plot( std::string filename , Microenvironment& M, double z_slice , doub double normalizer = 78.539816339744831 / (voxel_size*voxel_size*voxel_size); // color in the background ECM + if(PhysiCell_settings.enable_substrate_plot == true && (*substrate_coloring_function) != NULL) + { + double dz_stroma = M.mesh.dz; + double max_conc; + double min_conc; + + std::string sub = PhysiCell_settings.substrate_to_monitor; + int sub_index = M.find_density_index(sub); // check the substrate does actually exist + if(sub_index == -1){ + std::cout << "ERROR SAMPLING THE SUBSTRATE: COULD NOT FIND THE SUBSTRATE " << sub << std::endl; //if not print error message + } + else + { + if(PhysiCell_settings.limits_substrate_plot){ + max_conc = PhysiCell_settings.max_concentration; + min_conc = PhysiCell_settings.min_concentration; + } + else{ + max_conc = M.density_vector(5)[sub_index]; + min_conc = M.density_vector(5)[sub_index]; // so here I am sampling the concentration to set a min and a mx + //look for the max and min concentration among all the substrates + for (int n = 0; n < M.number_of_voxels(); n++) + { + double concentration = M.density_vector(n)[sub_index]; + if (concentration > max_conc) + max_conc = concentration; + if (concentration < min_conc) + min_conc = concentration; + } + }; + + //check that max conc is not zero otherwise it is a big problem! + if(max_conc == 0){ + + max_conc = 1.0; + + }; + + for (int n = 0; n < M.number_of_voxels(); n++) + { + auto current_voxel = M.voxels(n); + int z_center = current_voxel.center[2]; + double z_displ = z_center - dz_stroma/2; + + double z_compare = z_displ; + + if (default_microenvironment_options.simulate_2D == true){ + z_compare = z_center; + }; + + if (z_slice == z_compare){ //this is to make sure the substrate is sampled in the voxel visualized (so basically the slice) + int x_center = current_voxel.center[0]; + int y_center = current_voxel.center[1]; + + double x_displ = x_center - dx_stroma/2; + double y_displ = (y_center - dy_stroma) + dy_stroma/2; + + double concentration = M.density_vector(n)[sub_index]; + + std::vector< std::string > output = substrate_coloring_function(concentration, max_conc, min_conc ); + + Write_SVG_rect( os , x_displ - X_lower , y_displ - Y_lower, dx_stroma, dy_stroma , 0 , "none", output[0] ); + } + + } + + // add legend for the substrate + + os << " " << std::endl; //for some misterious reasons, the tissue part in the SVG is rotated so I have to re-rotate to draw + // the legend, otherwise it will be printed upside down + int padding = 0; + + double conc_interval = (max_conc - min_conc) / 13; // setting the interval for the values in the legend. I will divide the legend in 13 parts (as in the jupyter notebook) + + for(int i = 0; i <= 12; i++){ //creating 13 rectangoles for the bar, each one with a different shade of color. + + double concentration_sample = min_conc + (conc_interval * i); // the color depends on the concentration, starting from the min concentration to the max (which was sampled before) + + std::vector< std::string > output = substrate_coloring_function(concentration_sample, max_conc, min_conc ); + + padding = 25 * i; + + double upper_left_x = plot_width + 25.0; + double upper_left_y = ((plot_height - 25) / 13.0) * i; // here I set the position of each rectangole + + Write_SVG_rect(os, upper_left_x, plot_height - upper_left_y - 60, 25.0, ((plot_height - 25.0) / 13.0), 0 , "none", output[0]); //drawing each piece of the barplot + + if(i%2 == 0){ // of course I am not printing each value of the barplot, otherwise is too crowded, so just one each 2 + + char* szString; + szString = new char [1024]; + + sprintf( szString , "- %e", concentration_sample); + + Write_SVG_text( os , szString, upper_left_x + 24, plot_height - upper_left_y + 5.31, font_size , + PhysiCell_SVG_options.font_color.c_str() , PhysiCell_SVG_options.font.c_str() ); // misterious values set with a trial and error approach due to OCD. But now the legend is coherent at pixel level + + delete [] szString; + + } + + } + + Write_SVG_rect(os, 25.0 + plot_width, 25.0, 25.0, plot_height - 25.0, 0.002 * plot_height , "black", "none"); // nice black contour around the legend + + os << " " << std::endl; // no more rotation, restoring the tissue object in the SVG + } + } /* if( ECM.TellRows() > 0 ) { @@ -649,6 +771,21 @@ void SVG_plot( std::string filename , Microenvironment& M, double z_slice , doub return; } +std::vector paint_by_density_percentage( double concentration, double max_conc, double min_conc ){ + + std::vector< std::string > output( 4 , "black" ); + int color = (int) round( ((concentration - min_conc) / (max_conc - min_conc)) * 255 ); + if(color > 255){ + color = 255; + } + char szTempString [128]; + sprintf( szTempString , "rgb(%u,234,197)", 255 - color); + output[0].assign( szTempString ); + + return output; + +} + std::vector paint_by_number_cell_coloring( Cell* pCell ) { static std::vector< std::string > colors(0); @@ -704,6 +841,25 @@ std::vector paint_by_number_cell_coloring( Cell* pCell ) output[3] = "rgb(139,69,19)"; } } + + // new March 2023 (for better compatibility with studio) + + // if dead, use live color for the outline + if( pCell->phenotype.death.dead == true ) + { output[1] = interior_color; } + + // necrotic cells are brown + if( pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_swelling || + pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_lysed || + pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic ) + { interior_color = "saddlebrown"; } + // apoptotic cells are white + if( pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::apoptotic ) + { interior_color = "white"; } + + output[0] = interior_color; // set cytoplasm color + output[2] = interior_color; // set cytoplasm color + output[3] = interior_color; // set cytoplasm color return output; } @@ -745,7 +901,7 @@ void create_plot_legend( std::string filename , std::vector (*cell_ // place a big circle with cytoplasm colors Write_SVG_circle(os,cursor_x, cursor_y , temp_cell_radius , 1.0 , colors[1] , colors[0] ); // place a small circle with nuclear colors - Write_SVG_circle(os,cursor_x, cursor_y , 0.5*temp_cell_radius , 1.0 , colors[2] , colors[3] ); + Write_SVG_circle(os,cursor_x, cursor_y , 0.5*temp_cell_radius , 1.0 , colors[3] , colors[2] ); // place the label diff --git a/modules/PhysiCell_pathology.h b/modules/PhysiCell_pathology.h index 7bb5eac5c..8ee623dd2 100644 --- a/modules/PhysiCell_pathology.h +++ b/modules/PhysiCell_pathology.h @@ -103,6 +103,9 @@ std::vector transmission( std::vector& incoming_light, std::vect // each string is either rgb(R,G,B) or none std::vector simple_cell_coloring( Cell* pCell ); // done + +std::vector paint_by_density_percentage( double concentration, double max_conc, double min_conc ); //done + std::vector false_cell_coloring_Ki67( Cell* pCell ); // done std::vector false_cell_coloring_live_dead( Cell* pCell ); // done @@ -117,7 +120,7 @@ std::vector paint_by_number_cell_coloring( Cell* pCell ); // done std::string formatted_minutes_to_DDHHMM( double minutes ); -void SVG_plot( std::string filename , Microenvironment& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*) ); // done +void SVG_plot( std::string filename , Microenvironment& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*), std::vector (*substrate_coloring_function)(double, double, double) = NULL ); // done void SVG_plot_with_stroma( std::string filename , Microenvironment& M, double z_slice , double time, std::vector (*cell_coloring_function)(Cell*) , int ECM_index, std::vector (*ECM_coloring_function)(double) ); // planned diff --git a/modules/PhysiCell_settings.cpp b/modules/PhysiCell_settings.cpp index d57b7e050..51ab04ffd 100644 --- a/modules/PhysiCell_settings.cpp +++ b/modules/PhysiCell_settings.cpp @@ -127,6 +127,11 @@ PhysiCell_Settings::PhysiCell_Settings() SVG_save_interval = 60; enable_SVG_saves = true; + enable_substrate_plot = false; + substrate_to_monitor = "oxygen"; + limits_substrate_plot = false; + min_concentration = -1.0; + max_concentration = -1.0; intracellular_save_interval = 60; enable_intracellular_saves = false; @@ -186,6 +191,19 @@ void PhysiCell_Settings::read_from_pugixml( void ) node = xml_find_node( node , "SVG" ); SVG_save_interval = xml_get_double_value( node , "interval" ); enable_SVG_saves = xml_get_bool_value( node , "enable" ); + + pugi::xml_node node_plot_substrate; + node_plot_substrate = xml_find_node( node , "plot_substrate" ); + enable_substrate_plot = node_plot_substrate.attribute("enabled").as_bool(); + limits_substrate_plot = node_plot_substrate.attribute("limits").as_bool(); + + if(enable_substrate_plot){ + substrate_to_monitor = xml_get_string_value(node_plot_substrate, "substrate"); + if (limits_substrate_plot) { + min_concentration = xml_get_double_value(node_plot_substrate, "min_conc"); + max_concentration = xml_get_double_value(node_plot_substrate, "max_conc"); + } + }; node = node.parent(); node = xml_find_node( node , "intracellular_data" ); @@ -223,7 +241,15 @@ void PhysiCell_Settings::read_from_pugixml( void ) cell_division_orientation = LegacyRandomOnUnitSphere; } + settings = xml_get_bool_value( node_options, "disable_automated_spring_adhesions" ); + if( settings ) + { + std::cout << "Disabling automated spring adhesions and detachments!" << std::endl; + PhysiCell_settings.disable_automated_spring_adhesions = true; + } + // other options can go here, eventually + } // domain options @@ -354,6 +380,11 @@ T& Parameters::operator()( int i ) template T& Parameters::operator()( std::string str ) { + if (name_to_index_map.find(str) == name_to_index_map.end()) + { + std::cerr << "ERROR : Unknown parameter " << str << " ! Quitting." << std::endl; + exit(-1); + } return parameters[ name_to_index_map[str] ].value; } @@ -366,6 +397,11 @@ Parameter& Parameters::operator[]( int i ) template Parameter& Parameters::operator[]( std::string str ) { + if (name_to_index_map.find(str) == name_to_index_map.end()) + { + std::cerr << "ERROR : Unknown parameter " << str << " ! Quitting." << std::endl; + exit(-1); + } return parameters[ name_to_index_map[str] ]; } @@ -373,7 +409,11 @@ Parameter& Parameters::operator[]( std::string str ) template int Parameters::find_index( std::string search_name ) { - return name_to_index_map[ search_name ]; + auto out = name_to_index_map.find( search_name ); + if( out != name_to_index_map.end() ) + { return out->second; } + return -1; + // return name_to_index_map[ search_name ]; } diff --git a/modules/PhysiCell_settings.h b/modules/PhysiCell_settings.h index 4b9e3739e..ffeae81d4 100644 --- a/modules/PhysiCell_settings.h +++ b/modules/PhysiCell_settings.h @@ -111,10 +111,18 @@ class PhysiCell_Settings double full_save_interval = 60; bool enable_full_saves = true; bool enable_legacy_saves = false; + + bool disable_automated_spring_adhesions = false; double SVG_save_interval = 60; bool enable_SVG_saves = true; + bool enable_substrate_plot = false; + std::string substrate_to_monitor = "oxygen"; + bool limits_substrate_plot = false; + double min_concentration = -1.0; + double max_concentration = -1.0; + double intracellular_save_interval = 60; bool enable_intracellular_saves = false; diff --git a/protocols/adding new signals or behaviors.md b/protocols/adding new signals or behaviors.md index 66d601bf6..9fea0e6ad 100644 --- a/protocols/adding new signals or behaviors.md +++ b/protocols/adding new signals or behaviors.md @@ -20,8 +20,7 @@ Suppose you want to add a new signal "my signal name" to the dictionary, and tha 1. Go to the end of the "signal" section. Just before these lines: ``` - behavior_to_int.clear(); - int_to_behavior.clear(); + /* add new signals above this line */ ``` 1. Add the signal like this: @@ -105,6 +104,8 @@ Suppose you want to add a new behavior "my behavior name" to the dictionary, and 1. Go to the end of the "behavior" section. Just before these lines: ``` + /* add new behaviors above this line */ + // resize scales; signal_scales.resize( int_to_signal.size() , 1.0 ); ``` diff --git a/sample_projects/Makefile-default b/sample_projects/Makefile-default index 595ea5cd2..0cee2c68a 100644 --- a/sample_projects/Makefile-default +++ b/sample_projects/Makefile-default @@ -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" + @echo " worm-sample interaction-sample mechano-sample" @echo "" @echo "Sample intracellular projects: ode-energy-sample physiboss-cell-lines-sample cancer-metabolism-sample" @echo "" @@ -93,7 +93,7 @@ template: biorobots-sample: cp ./sample_projects/biorobots/custom_modules/* ./custom_modules/ touch main.cpp && cp main.cpp main-backup.cpp - cp ./sample_projects/biorobots/main-biorobots.cpp ./main.cpp + cp ./sample_projects/biorobots/main.cpp ./main.cpp cp Makefile Makefile-backup cp ./sample_projects/biorobots/Makefile . cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml @@ -102,7 +102,7 @@ biorobots-sample: cancer-biorobots-sample: cp ./sample_projects/cancer_biorobots/custom_modules/* ./custom_modules/ touch main.cpp && cp main.cpp main-backup.cpp - cp ./sample_projects/cancer_biorobots/main-cancer_biorobots.cpp ./main.cpp + cp ./sample_projects/cancer_biorobots/main.cpp ./main.cpp cp Makefile Makefile-backup cp ./sample_projects/cancer_biorobots/Makefile . cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml @@ -129,7 +129,7 @@ celltypes3-sample: heterogeneity-sample: cp ./sample_projects/heterogeneity/custom_modules/* ./custom_modules/ touch main.cpp && cp main.cpp main-backup.cpp - cp ./sample_projects/heterogeneity/main-heterogeneity.cpp ./main.cpp + cp ./sample_projects/heterogeneity/main.cpp ./main.cpp cp Makefile Makefile-backup cp ./sample_projects/heterogeneity/Makefile . cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml @@ -208,6 +208,13 @@ cancer-metabolism-sample: cp ./config/PhysiCell_settings.xml ./config/PhysiCell_settings-backup.xml cp ./sample_projects_intracellular/fba/cancer_metabolism/config/* ./config/ +mechano-sample: + cp ./sample_projects/mechano/custom_modules/* ./custom_modules/ + touch main.cpp && cp main.cpp main-backup.cpp + cp ./sample_projects/mechano/main.cpp ./main.cpp + cp Makefile Makefile-backup + cp ./sample_projects/mechano/Makefile . + cp ./sample_projects/mechano/config/* ./config/ # early examples for convergence testing @@ -422,3 +429,25 @@ upgrade: $(SOURCE) mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/biorobots/Makefile b/sample_projects/biorobots/Makefile index 47ec7a2d3..4a91072ec 100644 --- a/sample_projects/biorobots/Makefile +++ b/sample_projects/biorobots/Makefile @@ -53,28 +53,29 @@ PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o Physi PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ PhysiCell_signal_behavior.o -PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o +PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o \ +PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o # put your custom objects here (they should be in the custom_modules directory) -PhysiCell_custom_module_OBJECTS := biorobots.o +PhysiCell_custom_module_OBJECTS := custom.o pugixml_OBJECTS := pugixml.o PhysiCell_OBJECTS := $(BioFVM_OBJECTS) $(pugixml_OBJECTS) $(PhysiCell_core_OBJECTS) $(PhysiCell_module_OBJECTS) ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiCell_custom_module_OBJECTS) -#compile the project +# compile the project all: main.cpp $(ALL_OBJECTS) $(COMPILE_COMMAND) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp - make name + make name name: @echo "" @echo "Executable name is" $(PROGRAM_NAME) @echo "" - + # PhysiCell core components PhysiCell_phenotype.o: ./core/PhysiCell_phenotype.cpp @@ -149,23 +150,23 @@ PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp - + PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp - $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp - $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp # user-defined PhysiCell modules -biorobots.o: ./custom_modules/biorobots.cpp - $(COMPILE_COMMAND) -c ./custom_modules/biorobots.cpp +custom.o: ./custom_modules/custom.cpp + $(COMPILE_COMMAND) -c ./custom_modules/custom.cpp # cleanup @@ -179,16 +180,13 @@ reset: rm ALL_CITATIONS.txt cp ./config/PhysiCell_settings-backup.xml ./config/PhysiCell_settings.xml touch ./config/empty.csv - rm -f ./config/*.csv + rm -f ./config/*.csv clean: rm -f *.o rm -f $(PROGRAM_NAME)* data-cleanup: - rm -f *.mat - rm -f *.xml - rm -f *.svg rm -rf ./output mkdir ./output touch ./output/empty.txt @@ -237,7 +235,7 @@ gif: movie: ffmpeg -r $(FRAMERATE) -f image2 -i $(OUTPUT)/snapshot%08d.jpg -vcodec libx264 -pix_fmt yuv420p -strict -2 -tune animation -crf 15 -acodec none $(OUTPUT)/out.mp4 - + # upgrade rules SOURCE := PhysiCell_upgrade.zip @@ -265,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/biorobots/VERSION.txt b/sample_projects/biorobots/VERSION.txt new file mode 100644 index 000000000..5a68790ef --- /dev/null +++ b/sample_projects/biorobots/VERSION.txt @@ -0,0 +1 @@ +1.10.4 \ No newline at end of file diff --git a/sample_projects/biorobots/config/PhysiCell_settings.xml b/sample_projects/biorobots/config/PhysiCell_settings.xml index 4895e4800..2d5f7e46b 100644 --- a/sample_projects/biorobots/config/PhysiCell_settings.xml +++ b/sample_projects/biorobots/config/PhysiCell_settings.xml @@ -1,77 +1,3 @@ - - - - - -1000 @@ -87,7 +13,7 @@ - 2880 + 2880 min micron @@ -97,11 +23,11 @@ - 4 + 6 - output + output 2 @@ -120,261 +46,523 @@ false - true + true + true - - 1000 - .1 - - 0 - 1 - - - - - 1000 - .4 - - 0 - 1 - - - + + 1000 + 0.1 + + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 1000 + 0.4 + + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + true - false - + true + ./config/initial.mat - + ./config/dirichlet.mat - + - - - - - - - - - 0.0 - - - - - - - - - 0 - - - - 516 - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 - 0 - 2.0 - - - - - 0.0 - - - - - 0 - 86400 - - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 - 0 - 2.0 - - - - - - 2494 - 0.75 - 540 - - 0.05 - 0.0045 - 0.0055 - - 0 - 0 - - 2.0 - - - - 0.4 - 10.0 - 1.25 - - - 1.8 - 15.12 - - - - - 1 - 1 - .5 - - - false - true - - false - director signal - 1 - - - - - - - 0 - 1 - 0 - 0 - - - - 0 - 1 - 0 - 0 - - - - - - - 0.0 - - - - - - - - 9.9 - - - - - - - - - - 9.9 - - - - - 1.0 - - - - - - - 5.0 - 5.0 - 0.5 - - - true - true - - false - director signal - 1 - - - - - - 1.0 - - - - + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.5 + 10.0 + 0.0 + + + + 1 + 1 + .5 + + false + true + + false + director signal + 1 + + + false + false + + 0.0 + 0.0 + + + + + + + + 9.9 + 1 + 0 + 0 + + + 0.0 + 1 + 0.0 + 0.0 + + + + + 0 + + 0.0 + 0.0 + 0.0 + + + + 0.0 + 0.0 + 0.0 + + + 1 + + 0.0 + 0.0 + 0.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + + 0 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.5 + 10.0 + 0.0 + + + + 1 + 1 + .5 + + false + true + + false + director signal + 1 + + + false + false + + 0.0 + 0.0 + + + + + + + + 0 + 1 + 0 + 0 + + + 9.9 + 1 + 0.0 + 0.0 + + + + + 0 + + 0.0 + 0.0 + 0.0 + + + + 0.0 + 0.0 + 0.0 + + + 1 + + 0.0 + 0.0 + 0.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + + 1 + + + + + + + + 0.0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.5 + 10.0 + 0.0 + + + + 5 + 5 + .5 + + true + true + + false + director signal + 1 + + + true + false + + 0.0 + 1 + + + + + + + + 0 + 1 + 0 + 0 + + + 0.0 + 1 + 0.0 + 0.0 + + + + + 0 + + 0.0 + 0.0 + 0.0 + + + + 0.0 + 0.0 + 0.0 + + + 1 + + 0.0 + 0.0 + 0.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + + 1 + + + + ./config cells.csv - + - 0 - - - 1e3 - .4 - 1e3 - .1 - - - 0.05 - - - 1.0 - 0.5 - - - 15 - 100 - 50 - - - 0.4 - - - red - blue - limegreen - - + 0 + 0 + red + blue + limegreen + 0.4 + 15 + 100 + 50 + 0.5 + 1 + 0.5 + - + \ No newline at end of file diff --git a/sample_projects/biorobots/custom_modules/biorobots.cpp b/sample_projects/biorobots/custom_modules/custom.cpp similarity index 60% rename from sample_projects/biorobots/custom_modules/biorobots.cpp rename to sample_projects/biorobots/custom_modules/custom.cpp index ca7eb910e..1407d289b 100644 --- a/sample_projects/biorobots/custom_modules/biorobots.cpp +++ b/sample_projects/biorobots/custom_modules/custom.cpp @@ -1,581 +1,491 @@ -/* -############################################################################### -# If you use PhysiCell in your project, please cite PhysiCell and the version # -# number, such as below: # -# # -# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # -# # -# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # -# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # -# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # -# DOI: 10.1371/journal.pcbi.1005991 # -# # -# See VERSION.txt or call get_PhysiCell_version() to get the current version # -# x.y.z. Call display_citations() to get detailed information on all cite-# -# able software used in your PhysiCell application. # -# # -# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # -# as below: # -# # -# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # -# with BioFVM [2] to solve the transport equations. # -# # -# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # -# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # -# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # -# DOI: 10.1371/journal.pcbi.1005991 # -# # -# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # -# llelized diffusive transport solver for 3-D biological simulations, # -# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # -# # -############################################################################### -# # -# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # -# # -# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # -# All rights reserved. # -# # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions are met: # -# # -# 1. Redistributions of source code must retain the above copyright notice, # -# this list of conditions and the following disclaimer. # -# # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in the # -# documentation and/or other materials provided with the distribution. # -# # -# 3. Neither the name of the copyright holder nor the names of its # -# contributors may be used to endorse or promote products derived from this # -# software without specific prior written permission. # -# # -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # -# POSSIBILITY OF SUCH DAMAGE. # -# # -############################################################################### -*/ - -#include "./biorobots.h" - -void setup_microenvironment( void ) -{ - // set domain parameters - - initialize_microenvironment(); - - // these will ***overwrite*** values specified in the - // microenvironment_setup part of the XML, - // based on what's in the user_parameters section - - microenvironment.name = "synthetic tissue"; - - int cargo_index = microenvironment.find_density_index( "cargo signal" ); - int director_index = microenvironment.find_density_index( "director signal" ); - - microenvironment.diffusion_coefficients[cargo_index] = - parameters.doubles("cargo_signal_D"); - microenvironment.decay_rates[cargo_index] = - parameters.doubles("cargo_signal_decay"); - - microenvironment.diffusion_coefficients[director_index] = - parameters.doubles("director_signal_D"); - microenvironment.decay_rates[director_index] = - parameters.doubles("director_signal_decay"); - - // display the microenvironment again - - microenvironment.display_information( std::cout ); - - return; -} - -void create_cell_types( void ) -{ - SeedRandom( parameters.ints("random_seed") ); - // housekeeping - - /* - Put any modifications to default cell definition here if you - want to have "inherited" by other cell types. - - This is a good place to set default functions. - */ - - cell_defaults.functions.volume_update_function = standard_volume_update_function; - cell_defaults.functions.update_velocity = standard_update_cell_velocity; - - cell_defaults.functions.update_migration_bias = NULL; - cell_defaults.functions.update_phenotype = NULL; - cell_defaults.functions.custom_cell_rule = NULL; - - cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; - cell_defaults.functions.calculate_distance_to_membrane = NULL; - - /* - This parses the cell definitions in the XML config file. - */ - - initialize_cell_definitions_from_pugixml(); - - /* - Put any modifications to individual cell definitions here. - - This is a good place to set custom functions. - */ - - cell_defaults.phenotype.mechanics.attachment_elastic_constant = parameters.doubles( "elastic_coefficient" ); - - static int worker_ID = find_cell_definition( "worker cell" )->type; - static int cargo_ID = find_cell_definition( "cargo cell" )->type; - static int director_ID = find_cell_definition( "director cell" )->type; - - Cell_Definition* pCD = find_cell_definition( "director cell" ); - pCD->functions.update_phenotype = director_cell_rule; - pCD->phenotype.mechanics.attachment_elastic_constant = parameters.doubles( "elastic_coefficient" ); - - pCD = find_cell_definition( "cargo cell" ); - pCD->functions.update_phenotype = cargo_cell_rule; - pCD->functions.custom_cell_rule = NULL; // extra_elastic_attachment_mechanics; // pre-1.8.0 - pCD->functions.contact_function = standard_elastic_contact_function; - pCD->phenotype.mechanics.attachment_elastic_constant = parameters.doubles( "elastic_coefficient" ); - - pCD = find_cell_definition( "worker cell" ); - pCD->phenotype.mechanics.cell_cell_adhesion_strength = 0.0; - - pCD->functions.update_phenotype = worker_cell_rule; - pCD->functions.custom_cell_rule = NULL; // extra_elastic_attachment_mechanics; // pre 1.8.0 - pCD->functions.contact_function = standard_elastic_contact_function; - pCD->functions.update_migration_bias = worker_cell_motility; - pCD->phenotype.mechanics.attachment_elastic_constant = parameters.doubles( "elastic_coefficient" ); - - /* - This builds the map of cell definitions and summarizes the setup. - */ - - build_cell_definitions_maps(); - display_cell_definitions( std::cout ); - - return; -} - -void director_cell_rule( Cell* pCell , Phenotype& phenotype , double dt ) -{ - return; - std::vector nearby = pCell->cells_in_my_container(); - - // if at least 2 neighbors, turn off secretion - // if size >= 3, then we have "self" and at least two more - if( nearby.size() > 2 ) - { - pCell->phenotype.secretion.set_all_secretion_to_zero(); - pCell->custom_data[ "secreting" ] = 0.0; - - pCell->functions.update_phenotype = NULL; - } - - return; -} - -std::vector robot_coloring_function( Cell* pCell ) -{ - std::string color = "black"; - std::vector< std::string > output( 4 , color ); - - // black cells if necrotic - if( pCell->phenotype.death.dead == true ) - { return output; } - - output[3] = "none"; // no nuclear outline color - - static std::string worker_color = parameters.strings( "worker_color" ); - static std::string cargo_color = parameters.strings( "cargo_color" ); - static std::string director_color = parameters.strings( "director_color" ); - - static int worker_ID = find_cell_definition( "worker cell" )->type; - static int cargo_ID = find_cell_definition( "cargo cell" )->type; - static int director_ID = find_cell_definition( "director cell" )->type; - - if( pCell->type == worker_ID ) - { color = worker_color; } - else if( pCell->type == cargo_ID ) - { color = cargo_color; } - else if( pCell->type == director_ID ) - { color = director_color; } - else - { color = "white"; } - - output[0] = color; - output[2] = color; - - return output; -} - -void create_cargo_cluster_6( std::vector& center ) -{ - // create a hollow cluster at position, with random orientation - - static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); - - static double spacing = 0.95 * pCargoDef->phenotype.geometry.radius * 2.0; - static double d_Theta = 1.047197551196598 ; // 2*pi / 6.0 - - double theta = 6.283185307179586 * UniformRandom(); - - static std::vector position(3,0.0); - - Cell* pC; - for( int i=0; i < 6; i++ ) - { - pC = create_cell( *pCargoDef ); - - position[0] = center[0] + spacing*cos( theta ); - position[1] = center[1] + spacing*sin( theta ); - - pC->assign_position( position ); - - theta += d_Theta; - } - - return; -} - -void create_cargo_cluster_7( std::vector& center ) -{ - static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); - - // create a filled cluster at position, with random orientation - - create_cargo_cluster_6( center ); - Cell* pC = create_cell( *pCargoDef ); - pC->assign_position( center ); - - return; -} - - -void create_cargo_cluster_3( std::vector& center ) -{ - static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); - - // create a small cluster at position, with random orientation - - static double spacing = 0.95 * pCargoDef->phenotype.geometry.radius * 1.0; - static double d_Theta = 2.094395102393195 ; // 2*pi / 3.0 - - double theta = 6.283185307179586 * UniformRandom(); - - static std::vector position(3,0.0); - - Cell* pC; - for( int i=0; i < 3; i++ ) - { - pC = create_cell( *pCargoDef ); - - position[0] = center[0] + spacing*cos( theta ); - position[1] = center[1] + spacing*sin( theta ); - - pC->assign_position( position ); - - theta += d_Theta; - } - - return; -} - - -void setup_tissue( void ) -{ - int number_of_directors = parameters.ints("number_of_directors"); // 15; - int number_of_cargo_clusters = parameters.ints("number_of_cargo_clusters"); // 100; - int number_of_workers = parameters.ints("number_of_workers"); // 50; - - static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); - static Cell_Definition* pDirectorDef = find_cell_definition("director cell"); - static Cell_Definition* pWorkerDef = find_cell_definition("worker cell"); - - - std::cout << "Placing cells ... " << std::endl; - - // randomly place seed cells - - std::vector position(3,0.0); - - double x_range = default_microenvironment_options.X_range[1] - default_microenvironment_options.X_range[0]; - double y_range = default_microenvironment_options.Y_range[1] - default_microenvironment_options.Y_range[0]; - - double relative_margin = 0.2; - double relative_outer_margin = 0.02; - - std::cout << "\tPlacing " << number_of_directors << " director cells ... " << std::endl; - for( int i=0; i < number_of_directors ; i++ ) - { - // pick a random location - position[0] = default_microenvironment_options.X_range[0] + x_range*( relative_margin + (1.0-2*relative_margin)*UniformRandom() ); - - position[1] = default_microenvironment_options.Y_range[0] + y_range*( relative_outer_margin + (1.0-2*relative_outer_margin)*UniformRandom() ); - - // place the cell - Cell* pC; - pC = create_cell( *pDirectorDef ); - pC->assign_position( position ); - pC->is_movable = false; - } - - // place cargo clusters on the fringes - - std::cout << "\tPlacing cargo cells ... " << std::endl; - for( int i=0; i < number_of_cargo_clusters ; i++ ) - { - // pick a random location - - position[0] = default_microenvironment_options.X_range[0] + - x_range*( relative_outer_margin + (1-2.0*relative_outer_margin)*UniformRandom() ); - - position[1] = default_microenvironment_options.Y_range[0] + - y_range*( relative_outer_margin + (1-2.0*relative_outer_margin)*UniformRandom() ); - - if( UniformRandom() < 0.5 ) - { - Cell* pCell = create_cell( *pCargoDef ); - pCell->assign_position( position ); - } - else - { - create_cargo_cluster_7( position ); - } - } - - // place "workersworkers" - - std::cout << "\tPlacing worker cells ... " << std::endl; - for( int i=0; i < number_of_workers ; i++ ) - { - // pick a random location - - position[0] = default_microenvironment_options.X_range[0] + x_range*( relative_margin + (1.0-2*relative_margin)*UniformRandom() ); - - position[1] = default_microenvironment_options.Y_range[0] + y_range*( relative_outer_margin + (1.0-2*relative_outer_margin)*UniformRandom() ); - - // place the cell - Cell* pC; - - pC = create_cell( *pWorkerDef ); - pC->assign_position( position ); - } - - - std::cout << "done!" << std::endl; - // make a plot - - // load cells from your CSV file (if enabled) - load_cells_from_pugixml(); - - PhysiCell_SVG_options.length_bar = 200; - SVG_plot( "initial.svg" , microenvironment, 0.0 , 0.0 , robot_coloring_function ); - - return; -} - - -void cargo_cell_rule( Cell* pCell , Phenotype& phenotype , double dt ) -{ - - return; -} - -/* -void attach_cells( Cell* pCell_1, Cell* pCell_2 ) -{ - #pragma omp critical - { - - bool already_attached = false; - for( int i=0 ; i < pCell_1->state.neighbors.size() ; i++ ) - { - if( pCell_1->state.neighbors[i] == pCell_2 ) - { already_attached = true; } - } - if( already_attached == false ) - { pCell_1->state.neighbors.push_back( pCell_2 ); } - - already_attached = false; - for( int i=0 ; i < pCell_2->state.neighbors.size() ; i++ ) - { - if( pCell_2->state.neighbors[i] == pCell_1 ) - { already_attached = true; } - } - if( already_attached == false ) - { pCell_2->state.neighbors.push_back( pCell_1 ); } - - } - - return; -} -*/ - -/* -void dettach_cells( Cell* pCell_1 , Cell* pCell_2 ) -{ - #pragma omp critical - { - bool found = false; - int i = 0; - while( !found && i < pCell_1->state.neighbors.size() ) - { - // if cell 2 is in cell 1's list, remove it - if( pCell_1->state.neighbors[i] == pCell_2 ) - { - int n = pCell_1->state.neighbors.size(); - // copy last entry to current position - pCell_1->state.neighbors[i] = pCell_1->state.neighbors[n-1]; - // shrink by one - pCell_1->state.neighbors.pop_back(); - found = true; - } - i++; - } - - found = false; - i = 0; - while( !found && i < pCell_2->state.neighbors.size() ) - { - // if cell 1 is in cell 2's list, remove it - if( pCell_2->state.neighbors[i] == pCell_1 ) - { - int n = pCell_2->state.neighbors.size(); - // copy last entry to current position - pCell_2->state.neighbors[i] = pCell_2->state.neighbors[n-1]; - // shrink by one - pCell_2->state.neighbors.pop_back(); - found = true; - } - i++; - } - - } - - return; -} -*/ - -/* -void add_elastic_velocity( Cell* pActingOn, Cell* pAttachedTo , double elastic_constant ) -{ - std::vector displacement = pAttachedTo->position - pActingOn->position; - axpy( &(pActingOn->velocity) , elastic_constant , displacement ); - - return; -} -*/ - -/* -void extra_elastic_attachment_mechanics( Cell* pCell, Phenotype& phenotype, double dt ) -{ - // if I am - std::vector velocity(3,0.0); - - for( int i=0; i < pCell->state.neighbors.size() ; i++ ) - { - add_elastic_velocity( pCell, pCell->state.neighbors[i], pCell->custom_data["elastic coefficient"] ); - } - - return; -} -*/ - -void worker_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ) -{ - static double threshold = parameters.doubles("drop_threshold"); // 0.4; - - static int cargo_index = microenvironment.find_density_index( "cargo signal" ); // 1 - static int director_index = microenvironment.find_density_index( "director signal" ); // 0 - - // have I arrived? If so, release my cargo - if( pCell->nearest_density_vector()[director_index] > threshold ) - { - // set receptor = 0 for cells we're detaching from - // and set their cycle rate to zero - for( int k=0; k < pCell->state.attached_cells.size() ; k++ ) - { - Cell* pTemp = pCell->state.attached_cells[k]; - - pTemp->custom_data[ "receptor" ] = 0.0; - pTemp->phenotype.cycle.data.transition_rate( 0,0 ) = 0; - } - - pCell->remove_all_attached_cells(); - /* // prior to 1.8.0 - for( int i=0; i < pCell->state.neighbors.size(); i++ ) - { - Cell* pTemp = pCell->state.neighbors[i]; - dettach_cells( pCell, pTemp ); - - pTemp->custom_data[ "receptor" ] = 0.0; - pTemp->phenotype.cycle.data.transition_rate( 0,0 ) = 0; - } - */ - } - - // am I searching for cargo? if so, see if I've found it - // if( pCell->state.neighbors.size() == 0 ) // pre 1.8.0 - if( pCell->state.number_of_attached_cells() == 0 ) - { - std::vector nearby = pCell->cells_in_my_container(); - for( int i=0; i < nearby.size(); i++ ) - { - // if it is expressing the receptor, dock with it - if( nearby[i]->custom_data["receptor"] > 0.5 ) - { - attach_cells( pCell, nearby[i] ); - nearby[i]->custom_data["receptor"] = 0.0; - nearby[i]->phenotype.secretion.set_all_secretion_to_zero(); - } - } - - } - - return; -} - -void worker_cell_motility( Cell* pCell, Phenotype& phenotype, double dt ) -{ - // if attached, biased motility towards director chemoattractant - // otherwise, biased motility towards cargo chemoattractant - - static double attached_worker_migration_bias = - parameters.doubles("attached_worker_migration_bias"); - static double unattached_worker_migration_bias = - parameters.doubles("unattached_worker_migration_bias"); - - static int cargo_index = microenvironment.find_density_index( "cargo signal" ); // 1 - static int director_index = microenvironment.find_density_index( "director signal" ); // 0 - - // if( pCell->state.neighbors.size() > 0 ) // pre-1.8.0 - if( pCell->state.number_of_attached_cells() > 0 ) - { - phenotype.motility.migration_bias = attached_worker_migration_bias; - - phenotype.motility.migration_bias_direction = pCell->nearest_gradient(director_index); - normalize( &( phenotype.motility.migration_bias_direction ) ); - } - else - { - phenotype.motility.migration_bias = unattached_worker_migration_bias; - - phenotype.motility.migration_bias_direction = pCell->nearest_gradient(cargo_index); - normalize( &( phenotype.motility.migration_bias_direction ) ); - } - - return; -} - +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include "./custom.h" + +void create_cell_types( void ) +{ + // set the random seed + SeedRandom( parameters.ints("random_seed") ); + + /* + Put any modifications to default cell definition here if you + want to have "inherited" by other cell types. + + This is a good place to set default functions. + */ + + initialize_default_cell_definition(); + cell_defaults.phenotype.secretion.sync_to_microenvironment( µenvironment ); + + cell_defaults.functions.volume_update_function = standard_volume_update_function; + cell_defaults.functions.update_velocity = standard_update_cell_velocity; + + cell_defaults.functions.update_migration_bias = NULL; + cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based; + cell_defaults.functions.custom_cell_rule = NULL; + cell_defaults.functions.contact_function = NULL; + + cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; + cell_defaults.functions.calculate_distance_to_membrane = NULL; + + /* + This parses the cell definitions in the XML config file. + */ + + initialize_cell_definitions_from_pugixml(); + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + build_cell_definitions_maps(); + + /* + This intializes cell signal and response dictionaries + */ + + setup_signal_behavior_dictionaries(); + + /* + Put any modifications to individual cell definitions here. + + This is a good place to set custom functions. + */ + + cell_defaults.functions.update_phenotype = phenotype_function; + cell_defaults.functions.custom_cell_rule = custom_function; + cell_defaults.functions.contact_function = contact_function; + + Cell_Definition* pCD = find_cell_definition( "director cell"); + pCD->functions.update_phenotype = director_cell_rule; + + pCD = find_cell_definition( "cargo cell"); + pCD->functions.update_phenotype = cargo_cell_rule; + pCD->functions.contact_function = standard_elastic_contact_function; + + pCD = find_cell_definition( "worker cell"); + pCD->functions.update_phenotype = worker_cell_rule; + pCD->functions.contact_function = standard_elastic_contact_function; + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + display_cell_definitions( std::cout ); + + return; +} + +void setup_microenvironment( void ) +{ + // set domain parameters + + // put any custom code to set non-homogeneous initial conditions or + // extra Dirichlet nodes here. + + // initialize BioFVM + + initialize_microenvironment(); + + return; +} + +void setup_tissue( void ) +{ + double Xmin = microenvironment.mesh.bounding_box[0]; + double Ymin = microenvironment.mesh.bounding_box[1]; + double Zmin = microenvironment.mesh.bounding_box[2]; + + double Xmax = microenvironment.mesh.bounding_box[3]; + double Ymax = microenvironment.mesh.bounding_box[4]; + double Zmax = microenvironment.mesh.bounding_box[5]; + + if( default_microenvironment_options.simulate_2D == true ) + { + Zmin = 0.0; + Zmax = 0.0; + } + + double Xrange = Xmax - Xmin; + double Yrange = Ymax - Ymin; + double Zrange = Zmax - Zmin; + + // create some of each type of cell + + Cell* pC; + + for( int k=0; k < cell_definitions_by_index.size() ; k++ ) + { + Cell_Definition* pCD = cell_definitions_by_index[k]; + std::cout << "Placing cells of type " << pCD->name << " ... " << std::endl; + for( int n = 0 ; n < parameters.ints("number_of_cells") ; n++ ) + { + std::vector position = {0,0,0}; + position[0] = Xmin + UniformRandom()*Xrange; + position[1] = Ymin + UniformRandom()*Yrange; + position[2] = Zmin + UniformRandom()*Zrange; + + pC = create_cell( *pCD ); + pC->assign_position( position ); + } + } + std::cout << std::endl; + + // load cells from your CSV file (if enabled) + load_cells_from_pugixml(); + + /* custom loading here */ + + int number_of_directors = parameters.ints("number_of_directors"); // 15; + int number_of_cargo_clusters = parameters.ints("number_of_cargo_clusters"); // 100; + int number_of_workers = parameters.ints("number_of_workers"); // 50; + + static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); + static Cell_Definition* pDirectorDef = find_cell_definition("director cell"); + static Cell_Definition* pWorkerDef = find_cell_definition("worker cell"); + + + std::cout << "Placing cells ... " << std::endl; + + // randomly place seed cells + + std::vector position(3,0.0); + + double relative_margin = 0.2; + double relative_outer_margin = 0.02; + + std::cout << "\tPlacing " << number_of_directors << " director cells ... " << std::endl; + for( int i=0; i < number_of_directors ; i++ ) + { + // pick a random location + position[0] = default_microenvironment_options.X_range[0] + Xrange*( relative_margin + (1.0-2*relative_margin)*UniformRandom() ); + + position[1] = default_microenvironment_options.Y_range[0] + Yrange*( relative_outer_margin + (1.0-2*relative_outer_margin)*UniformRandom() ); + + // place the cell + Cell* pC; + pC = create_cell( *pDirectorDef ); + pC->assign_position( position ); + set_single_behavior( pC, "movable" , false); + } + + // place cargo clusters on the fringes + + std::cout << "\tPlacing cargo cells ... " << std::endl; + for( int i=0; i < number_of_cargo_clusters ; i++ ) + { + // pick a random location + + position[0] = default_microenvironment_options.X_range[0] + + Xrange*( relative_outer_margin + (1-2.0*relative_outer_margin)*UniformRandom() ); + + position[1] = default_microenvironment_options.Y_range[0] + + Yrange*( relative_outer_margin + (1-2.0*relative_outer_margin)*UniformRandom() ); + + if( UniformRandom() < 0.5 ) + { + Cell* pCell = create_cell( *pCargoDef ); + pCell->assign_position( position ); + } + else + { + create_cargo_cluster_7( position ); + } + } + + // place "workersworkers" + + std::cout << "\tPlacing worker cells ... " << std::endl; + for( int i=0; i < number_of_workers ; i++ ) + { + // pick a random location + + position[0] = default_microenvironment_options.X_range[0] + Xrange*( relative_margin + (1.0-2*relative_margin)*UniformRandom() ); + + position[1] = default_microenvironment_options.Y_range[0] + Yrange*( relative_outer_margin + (1.0-2*relative_outer_margin)*UniformRandom() ); + + // place the cell + Cell* pC; + + pC = create_cell( *pWorkerDef ); + pC->assign_position( position ); + } + + + std::cout << "done!" << std::endl; + // make a plot + + // load cells from your CSV file (if enabled) + load_cells_from_pugixml(); + + PhysiCell_SVG_options.length_bar = 200; + SVG_plot( "initial.svg" , microenvironment, 0.0 , 0.0 , robot_coloring_function ); + + + + return; +} + +std::vector my_coloring_function( Cell* pCell ) +{ return paint_by_number_cell_coloring(pCell); } + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ return; } + +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) +{ return; } + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) +{ return; } + +std::vector robot_coloring_function( Cell* pCell ) +{ + std::string color = "black"; + std::vector< std::string > output( 4 , color ); + + // black cells if necrotic + if( pCell->phenotype.death.dead == true ) + { return output; } + + output[3] = "none"; // no nuclear outline color + + static std::string worker_color = parameters.strings( "worker_color" ); + static std::string cargo_color = parameters.strings( "cargo_color" ); + static std::string director_color = parameters.strings( "director_color" ); + + static int worker_ID = find_cell_definition( "worker cell" )->type; + static int cargo_ID = find_cell_definition( "cargo cell" )->type; + static int director_ID = find_cell_definition( "director cell" )->type; + + if( pCell->type == worker_ID ) + { color = worker_color; } + else if( pCell->type == cargo_ID ) + { color = cargo_color; } + else if( pCell->type == director_ID ) + { color = director_color; } + else + { color = "white"; } + + output[0] = color; + output[2] = color; + + return output; +} + +void director_cell_rule( Cell* pCell , Phenotype& phenotype , double dt ) +{ return; } + +void cargo_cell_rule( Cell* pCell , Phenotype& phenotype , double dt ) +{ + static double elastic_coefficient = parameters.doubles( "elastic_coefficient" ); + + set_single_behavior( pCell ,"cell-cell adhesion elastic constant" , elastic_coefficient ); + return; +} + +void worker_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ) +{ + static double threshold = parameters.doubles("drop_threshold"); // 0.4; + + static double attached_worker_migration_bias = + parameters.doubles("attached_worker_migration_bias"); + static double unattached_worker_migration_bias = + parameters.doubles("unattached_worker_migration_bias"); + + static double elastic_coefficient = parameters.doubles( "elastic_coefficient" ); + + double director_signal = get_single_signal( pCell, "director signal" ); + double cargo_signal = get_single_signal( pCell, "cargo signal"); + + set_single_behavior( pCell ,"cell-cell adhesion elastic constant" , elastic_coefficient ); + + // have I arrived? If so, release my cargo + // set chemotaxis weights to seek cargo + // set migration bias + if( director_signal > threshold ) + { + // set receptor = 0 for cells we're detaching from + // and set their cycle rate to zero + for( int k=0; k < pCell->state.attached_cells.size() ; k++ ) + { + Cell* pTemp = pCell->state.attached_cells[k]; + + set_single_behavior( pTemp, "custom:receptor" , 0.0 ); + set_single_behavior( pTemp, "cycle entry" , 0.0 ); + } + + pCell->remove_all_attached_cells(); + + set_single_behavior( pCell , "chemotactic response to director signal" , 0.0 ); + set_single_behavior( pCell , "chemotactic response to cargo signal" , 1.0 ); + set_single_behavior( pCell , "migration bias" , unattached_worker_migration_bias ); + } + + // am I searching for cargo? if so, see if I've found it + // if( pCell->state.neighbors.size() == 0 ) // pre 1.8.0 + if( pCell->state.number_of_attached_cells() == 0 ) + { + std::vector nearby = pCell->cells_in_my_container(); + for( int i=0; i < nearby.size(); i++ ) + { + // if it is expressing the receptor, dock with it + // set chemotaxis weights + // set migration bias + + double receptor = get_single_signal( nearby[i] , "custom:receptor" ); + if( receptor > 0.5 ) + { + attach_cells( pCell, nearby[i] ); + set_single_behavior( nearby[i] , "custom:receptor" , 0.0 ); + + set_single_behavior( nearby[i] , "director signal secretion" , 0.0 ); + set_single_behavior( nearby[i] , "cargo signal secretion" , 0.0 ); + + set_single_behavior( pCell , "chemotactic response to director signal" , 1.0 ); + set_single_behavior( pCell , "chemotactic response to cargo signal" , 0.0 ); + set_single_behavior( pCell , "migration bias" , attached_worker_migration_bias ); + + } + } + + } + + return; +} + +void create_cargo_cluster_6( std::vector& center ) +{ + // create a hollow cluster at position, with random orientation + + static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); + + static double spacing = 0.95 * pCargoDef->phenotype.geometry.radius * 2.0; + static double d_Theta = 1.047197551196598 ; // 2*pi / 6.0 + + double theta = 6.283185307179586 * UniformRandom(); + + static std::vector position(3,0.0); + + Cell* pC; + for( int i=0; i < 6; i++ ) + { + pC = create_cell( *pCargoDef ); + + position[0] = center[0] + spacing*cos( theta ); + position[1] = center[1] + spacing*sin( theta ); + + pC->assign_position( position ); + + theta += d_Theta; + } + + return; +} + +void create_cargo_cluster_7( std::vector& center ) +{ + static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); + + // create a filled cluster at position, with random orientation + + create_cargo_cluster_6( center ); + Cell* pC = create_cell( *pCargoDef ); + pC->assign_position( center ); + + return; +} + +void create_cargo_cluster_3( std::vector& center ) +{ + static Cell_Definition* pCargoDef = find_cell_definition("cargo cell"); + + // create a small cluster at position, with random orientation + + static double spacing = 0.95 * pCargoDef->phenotype.geometry.radius * 1.0; + static double d_Theta = 2.094395102393195 ; // 2*pi / 3.0 + + double theta = 6.283185307179586 * UniformRandom(); + + static std::vector position(3,0.0); + + Cell* pC; + for( int i=0; i < 3; i++ ) + { + pC = create_cell( *pCargoDef ); + + position[0] = center[0] + spacing*cos( theta ); + position[1] = center[1] + spacing*sin( theta ); + + pC->assign_position( position ); + + theta += d_Theta; + } + + return; +} + diff --git a/sample_projects/biorobots/custom_modules/biorobots.h b/sample_projects/biorobots/custom_modules/custom.h similarity index 87% rename from sample_projects/biorobots/custom_modules/biorobots.h rename to sample_projects/biorobots/custom_modules/custom.h index 1df3ffae4..13c67b857 100644 --- a/sample_projects/biorobots/custom_modules/biorobots.h +++ b/sample_projects/biorobots/custom_modules/custom.h @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # @@ -68,49 +68,37 @@ #include "../core/PhysiCell.h" #include "../modules/PhysiCell_standard_modules.h" -using namespace BioFVM; +using namespace BioFVM; using namespace PhysiCell; -/* -// declare the cell types - -static Cell_Definition worker_cell; -static Cell_Definition cargo_cell; -static Cell_Definition director_cell; -static Cell_Definition linker_cell; - -static int worker_ID = 0; -static int cargo_ID = 1; -static int linker_ID = 2; -static int director_ID = 3; -*/ +// setup functions to help us along -// set up the microenvironment +void create_cell_types( void ); +void setup_tissue( void ); -void setup_microenvironment( void ); // done +// set up the BioFVM microenvironment +void setup_microenvironment( void ); -// set up the cell types +// custom pathology coloring function -void create_cell_types( void ); +std::vector my_coloring_function( Cell* ); -// set up the problem geometry +// custom functions can go here -void setup_tissue( void ); +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ); -// coloring functions +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ); std::vector robot_coloring_function( Cell* pCell ); -// these are the custom functions for these cells - -// void extra_elastic_attachment_mechanics( Cell* pCell, Phenotype& phenotype, double dt ); - void worker_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ); -void worker_cell_motility( Cell* pCell, Phenotype& phenotype, double dt ); - void cargo_cell_rule( Cell* pCell , Phenotype& phenotype , double dt ); +void director_cell_rule( Cell* pCell , Phenotype& phenotype , double dt ); -void director_cell_rule( Cell* pCell , Phenotype& phenotype , double dt ); // done - +void worker_cell_motility( Cell* pCell, Phenotype& phenotype, double dt ); +void create_cargo_cluster_6( std::vector& center ); +void create_cargo_cluster_7( std::vector& center ); +void create_cargo_cluster_3( std::vector& center ); diff --git a/sample_projects/biorobots/main.cpp b/sample_projects/biorobots/main.cpp new file mode 100644 index 000000000..214399ebb --- /dev/null +++ b/sample_projects/biorobots/main.cpp @@ -0,0 +1,253 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2023, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "./core/PhysiCell.h" +#include "./modules/PhysiCell_standard_modules.h" + +// put custom code modules here! + +#include "./custom_modules/custom.h" + +using namespace BioFVM; +using namespace PhysiCell; + +int main( int argc, char* argv[] ) +{ + // load and parse settings file(s) + + bool XML_status = false; + char copy_command [1024]; + if( argc > 1 ) + { + XML_status = load_PhysiCell_config_file( argv[1] ); + sprintf( copy_command , "cp %s %s" , argv[1] , PhysiCell_settings.folder.c_str() ); + } + else + { + XML_status = load_PhysiCell_config_file( "./config/PhysiCell_settings.xml" ); + sprintf( copy_command , "cp ./config/PhysiCell_settings.xml %s" , PhysiCell_settings.folder.c_str() ); + } + if( !XML_status ) + { exit(-1); } + + // copy config file to output directry + system( copy_command ); + + // OpenMP setup + omp_set_num_threads(PhysiCell_settings.omp_num_threads); + + // time setup + std::string time_units = "min"; + + /* Microenvironment setup */ + + setup_microenvironment(); // modify this in the custom code + + /* PhysiCell setup */ + + // set mechanics voxel size, and match the data structure to BioFVM + double mechanics_voxel_size = 30; + Cell_Container* cell_container = create_cell_container_for_microenvironment( microenvironment, mechanics_voxel_size ); + + /* Users typically start modifying here. START USERMODS */ + + create_cell_types(); + + setup_tissue(); + + /* Users typically stop modifying here. END USERMODS */ + + // set MultiCellDS save options + + set_save_biofvm_mesh_as_matlab( true ); + set_save_biofvm_data_as_matlab( true ); + set_save_biofvm_cell_data( true ); + set_save_biofvm_cell_data_as_custom_matlab( true ); + + // save a simulation snapshot + + char filename[1024]; + sprintf( filename , "%s/initial" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + // save a quick SVG cross section through z = 0, after setting its + // length bar to 200 microns + + PhysiCell_SVG_options.length_bar = 200; + + // for simplicity, set a pathology coloring function + + std::vector (*cell_coloring_function)(Cell*) = robot_coloring_function; + + sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + + sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); + create_plot_legend( filename , cell_coloring_function ); + + display_citations(); + + // set the performance timers + + BioFVM::RUNTIME_TIC(); + BioFVM::TIC(); + + std::ofstream report_file; + if( PhysiCell_settings.enable_legacy_saves == true ) + { + sprintf( filename , "%s/simulation_report.txt" , PhysiCell_settings.folder.c_str() ); + + report_file.open(filename); // create the data log file + report_file<<"simulated time\tnum cells\tnum division\tnum death\twall time"<update_all_cells( PhysiCell_globals.current_time ); + + /* + Custom add-ons could potentially go here. + */ + + PhysiCell_globals.current_time += diffusion_dt; + } + + if( PhysiCell_settings.enable_legacy_saves == true ) + { + log_output(PhysiCell_globals.current_time, PhysiCell_globals.full_output_index, microenvironment, report_file); + report_file.close(); + } + } + catch( const std::exception& e ) + { // reference to the base of a polymorphic object + std::cout << e.what(); // information from length_error printed + } + + // save a final simulation snapshot + + sprintf( filename , "%s/final" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + sprintf( filename , "%s/final.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + + // timer + + std::cout << std::endl << "Total simulation runtime: " << std::endl; + BioFVM::display_stopwatch_value( std::cout , BioFVM::runtime_stopwatch_value() ); + + return 0; +} diff --git a/sample_projects/cancer_biorobots/Makefile b/sample_projects/cancer_biorobots/Makefile index facc95370..1381dd805 100644 --- a/sample_projects/cancer_biorobots/Makefile +++ b/sample_projects/cancer_biorobots/Makefile @@ -1,5 +1,5 @@ VERSION := $(shell grep . VERSION.txt | cut -f1 -d:) -PROGRAM_NAME := cancer_biorobots +PROGRAM_NAME := project CC := g++ # CC := g++-mp-7 # typical macports compiler name @@ -30,7 +30,6 @@ ARCH := native # best auto-tuning # ARCH := nocona #64-bit pentium 4 or later # CFLAGS := -march=$(ARCH) -Ofast -s -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 - CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 ifeq ($(OS),Windows_NT) @@ -54,12 +53,12 @@ PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o Physi PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ PhysiCell_signal_behavior.o -PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o \ -PhysiCell_various_outputs.o PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o +PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o \ +PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o # put your custom objects here (they should be in the custom_modules directory) -PhysiCell_custom_module_OBJECTS := cancer_biorobots.o +PhysiCell_custom_module_OBJECTS := custom.o pugixml_OBJECTS := pugixml.o @@ -70,8 +69,8 @@ ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiCell_custom_module_OBJECTS) all: main.cpp $(ALL_OBJECTS) $(COMPILE_COMMAND) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp - make name - + make name + name: @echo "" @echo "Executable name is" $(PROGRAM_NAME) @@ -151,23 +150,23 @@ PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp - + PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp - $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp - $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp - $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp # user-defined PhysiCell modules -cancer_biorobots.o: ./custom_modules/cancer_biorobots.cpp - $(COMPILE_COMMAND) -c ./custom_modules/cancer_biorobots.cpp +custom.o: ./custom_modules/custom.cpp + $(COMPILE_COMMAND) -c ./custom_modules/custom.cpp # cleanup @@ -180,17 +179,14 @@ reset: touch ./core/PhysiCell_cell.cpp rm ALL_CITATIONS.txt cp ./config/PhysiCell_settings-backup.xml ./config/PhysiCell_settings.xml - touch ./config/empty.csv - rm -f ./config/*.csv + touch ./config/empty.csv + rm -f ./config/*.csv clean: rm -f *.o rm -f $(PROGRAM_NAME)* data-cleanup: - rm -f *.mat - rm -f *.xml - rm -f *.svg rm -rf ./output mkdir ./output touch ./output/empty.txt @@ -239,7 +235,7 @@ gif: movie: ffmpeg -r $(FRAMERATE) -f image2 -i $(OUTPUT)/snapshot%08d.jpg -vcodec libx264 -pix_fmt yuv420p -strict -2 -tune animation -crf 15 -acodec none $(OUTPUT)/out.mp4 - + # upgrade rules SOURCE := PhysiCell_upgrade.zip @@ -267,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/cancer_biorobots/VERSION.txt b/sample_projects/cancer_biorobots/VERSION.txt new file mode 100644 index 000000000..1cac385c6 --- /dev/null +++ b/sample_projects/cancer_biorobots/VERSION.txt @@ -0,0 +1 @@ +1.11.0 diff --git a/sample_projects/cancer_biorobots/config/PhysiCell_settings.xml b/sample_projects/cancer_biorobots/config/PhysiCell_settings.xml index 2001e6349..5263677a6 100644 --- a/sample_projects/cancer_biorobots/config/PhysiCell_settings.xml +++ b/sample_projects/cancer_biorobots/config/PhysiCell_settings.xml @@ -1,435 +1,592 @@ - - + - + + -750 + 750 + -750 + 750 + -10 + 10 + 20 + 20 + 20 + true + - - - -750 - 750 - -750 - 750 - -10 - 10 - 20 - 20 - 20 - true - - - - 14400 - min - micron - - 0.01 - 0.1 - 6 - - - - 8 - - - - output + + 14400 + min + micron + 0.01 + 0.1 + 6 + + + + 8 + - - 60 - true - - - - 60 - true - - - - false - - - - - false - true - + + output + + 60 + true + + + 60 + true + + + false + + - - - - 100000.000000 - .1 - - 38.0 - 38.0 - - - - - 1000 - .1 - - 0 - 0 - - - - - 1000 - .15625 - - 0 - 0 - - - - true - false - - - ./config/initial.mat - - - - ./config/dirichlet.mat - - - - - - - - - + + false + true + true + - - - - 0.000072 - - - - - - - - - 5.31667e-05 - - - - 516 - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + + + + 100000.0 + 0.1 + + 38 + 38 + + 38 + 38 + 38 + 38 + 38 + 38 + + + + + 1000 + 0.1 + + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 1000 + .15625 + + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + true + true + + ./config/initial.mat + + + ./config/dirichlet.mat + + + + + + + + + + 0.00072 + + + + + 5.31667e-05 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 - - - - - 0.0 - - - - - 0 - 86400 - - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + 0.4 + 10.0 + 1.25 + + 1 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 1 + 1 + .5 + + false + true + + false + oxygen + 1 + + + false + false + + 0.0 + 0.0 + 0.0 + + + + + + + 0 + 1 + 10 + 0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0 + + 0 + 0.0 + 0.0 + + + 0 + 0.0 + 0.0 + + 1 + + 0 + 0.0 + 0.0 + + + + + 0 + 0.0 + 0.0 + + + + + 0 + 10 + 0.03333 + 0.004167 + 0.004167 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + 0.0 + + + + + 4.065e-5 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 - - - - - - 2494 - 0.75 - 540 - - 0.05 - 0.0045 - 0.0055 - - 0 - 0 - - 2.0 - - - - 0.4 - 10.0 - 1.25 - - - 1.8 - 15.12 - - - - - 1 - 1 - .5 - - - false - true - - false - oxygen - 1 - - - - - - - 0 - 38 - 10 - 0 - - - - 0 - 1 - 0 - 0 - - - - 0 - 1 - 0 - 0 - - - - - - - 0.0 - 10 - 0.03333 - 0.004167 - 0.004167 - 0.0 - - - - - - - - 0.0 - - - - - 4.065e-5 - - - - - 0 - - - 10 - - - - - false - - - - - 1.0 - - - - - - - - 0.0 - - - - - 0 - - - - - 0 - - - - 2 - 5 - 0.5 - - - true - true - - - - - + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + 0 + 50 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 1 + 1 + .5 + + false + true + + false + oxygen + 1 + + + false + false + + 0.0 + 0.0 + 0.0 + + + + + + + 0 + 1 + 1 + 0 + + + 10 + 1 + 0.0 + 0.0 + + + 0.0 + 1 + 0.0 + 0.0 + + + + 0 + + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + + 1 + + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + + + + + 1 + 10 + 0.03333 + 0.004167 + 0.004167 + 0.5 + 50 + 0.1 + 18 + 14 + 0.001 + 0.0 + 0.0 + + + + + + + 0.0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + 0 + 50 + 1.25 + + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 2 + 5 + .5 + + true + true + + false + oxygen + 1 + + + true + false + + 0.0 + 1 + 0.0 + + + + + + + 0 + 1 + 1 + 0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0 + + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + + 1 + + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + + + + + 0 + 10 + 0.03333 + 0.004167 + 0.004167 + 0.5 + 50 + 0.1 + 18 + 14 + 0.001 + 0.5 + 0.5 + + + - - - - - ./config - cells.csv - - - - - 0 - - - 10080 - - 3 - - - 0.1 - 0 - 5 - - - 0.1 - 0 - 5 + + + ./config + cells.csv + + - - 0.05 - - 1.25 - - - - 0.10 - 500 - - - 200 - - - 50.0 - - - 0.1 - 18.0 - 14.0 - - - 0.001 - - 0.5 - 0.5 - - - + + 0 + 0 + 10080 + 3 + 0.1 + 500 + 200 + + \ No newline at end of file diff --git a/sample_projects/cancer_biorobots/config/cells.csv b/sample_projects/cancer_biorobots/config/cells.csv index acdc5b6bf..734bdc767 100644 --- a/sample_projects/cancer_biorobots/config/cells.csv +++ b/sample_projects/cancer_biorobots/config/cells.csv @@ -1 +1 @@ -0,0,0,0 +0,0,0,0 \ No newline at end of file diff --git a/sample_projects/cancer_biorobots/custom_modules/cancer_biorobots.cpp b/sample_projects/cancer_biorobots/custom_modules/custom.cpp similarity index 52% rename from sample_projects/cancer_biorobots/custom_modules/cancer_biorobots.cpp rename to sample_projects/cancer_biorobots/custom_modules/custom.cpp index 8b2196495..9c43db830 100644 --- a/sample_projects/cancer_biorobots/custom_modules/cancer_biorobots.cpp +++ b/sample_projects/cancer_biorobots/custom_modules/custom.cpp @@ -65,136 +65,114 @@ ############################################################################### */ -#include "./cancer_biorobots.h" +#include "./custom.h" -Cell_Definition* cargo_cell; -Cell_Definition* worker_cell; - -void create_cargo_cell_type( void ) +void create_cell_types( void ) { - cargo_cell = find_cell_definition( "cargo cell" ); - - int apoptosis_index = cell_defaults.phenotype.death.find_death_model_index( PhysiCell_constants::apoptosis_death_model ); - - int oxygen_ID = microenvironment.find_density_index( "oxygen" ); // 0 - int attract_ID = microenvironment.find_density_index( "chemoattractant" ); // 1 - int therapy_ID = microenvironment.find_density_index( "therapeutic" ); // 2 - - // reduce o2 uptake + // set the random seed + SeedRandom( parameters.ints("random_seed") ); - cargo_cell->phenotype.secretion.uptake_rates[oxygen_ID] *= - parameters.doubles("cargo_o2_relative_uptake"); + /* + Put any modifications to default cell definition here if you + want to have "inherited" by other cell types. + + This is a good place to set default functions. + */ - cargo_cell->phenotype.mechanics.cell_cell_adhesion_strength *= - parameters.doubles("cargo_relative_adhesion"); // 0.0; - cargo_cell->phenotype.mechanics.cell_cell_repulsion_strength *= - parameters.doubles("cargo_relative_repulsion"); // 5.0; - - // figure out mechanics parameters + initialize_default_cell_definition(); + cell_defaults.phenotype.secretion.sync_to_microenvironment( µenvironment ); - cargo_cell->phenotype.mechanics.relative_maximum_attachment_distance - = parameters.doubles( "max_attachment_distance" ) / cargo_cell->phenotype.geometry.radius ; + cell_defaults.functions.volume_update_function = standard_volume_update_function; + cell_defaults.functions.update_velocity = standard_update_cell_velocity; - cargo_cell->phenotype.mechanics.relative_detachment_distance - = parameters.doubles( "max_elastic_displacement" ) / cargo_cell->phenotype.geometry.radius ; - - cargo_cell->phenotype.mechanics.attachment_elastic_constant - = parameters.doubles("elastic_coefficient"); - - // set functions + cell_defaults.functions.update_migration_bias = NULL; + cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based; + cell_defaults.functions.custom_cell_rule = NULL; + cell_defaults.functions.contact_function = NULL; - cargo_cell->functions.update_phenotype = cargo_cell_phenotype_rule; - cargo_cell->functions.custom_cell_rule = cargo_cell_rule; - cargo_cell->functions.contact_function = biorobots_contact_function; - cargo_cell->functions.update_migration_bias = NULL; + cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; + cell_defaults.functions.calculate_distance_to_membrane = NULL; - // set custom data values + /* + This parses the cell definitions in the XML config file. + */ - return; -} - -void create_worker_cell_type( void ) -{ - worker_cell = find_cell_definition( "worker cell" ); + initialize_cell_definitions_from_pugixml(); - int oxygen_ID = microenvironment.find_density_index( "oxygen" ); // 0 - int attract_ID = microenvironment.find_density_index( "chemoattractant" ); // 1 - int therapy_ID = microenvironment.find_density_index( "therapeutic" ); // 2 - - // reduce o2 uptake - - worker_cell->phenotype.secretion.uptake_rates[oxygen_ID] *= - parameters.doubles("worker_o2_relative_uptake"); // 0.1; - - worker_cell->phenotype.mechanics.cell_cell_adhesion_strength *= - parameters.doubles("worker_relative_adhesion"); // 0.0; - worker_cell->phenotype.mechanics.cell_cell_repulsion_strength *= - parameters.doubles("worker_relative_repulsion"); // 5.0; - - // figure out mechanics parameters - - worker_cell->phenotype.mechanics.relative_maximum_attachment_distance - = parameters.doubles( "max_attachment_distance" ) / worker_cell->phenotype.geometry.radius ; + /* + This builds the map of cell definitions and summarizes the setup. + */ - worker_cell->phenotype.mechanics.attachment_elastic_constant - = parameters.doubles("elastic_coefficient"); - - worker_cell->phenotype.mechanics.relative_detachment_distance - = parameters.doubles( "max_elastic_displacement" ) / worker_cell->phenotype.geometry.radius ; + build_cell_definitions_maps(); - // set functions - - worker_cell->functions.update_phenotype = NULL; // worker_cell_rule; - worker_cell->functions.custom_cell_rule = worker_cell_rule; - worker_cell->functions.contact_function = biorobots_contact_function; - worker_cell->functions.update_migration_bias = worker_cell_motility; - - // set custom data values - - return; -} + /* + This intializes cell signal and response dictionaries + */ -void create_cell_types( void ) -{ - // use the same random seed so that future experiments have the - // same initial histogram of oncoprotein, even if threading means - // that future division and other events are still not identical - // for all runs - SeedRandom( parameters.ints("random_seed") ); - - // housekeeping - - initialize_default_cell_definition(); + setup_signal_behavior_dictionaries(); + + /* + Put any modifications to individual cell definitions here. + + This is a good place to set custom functions. + */ + cell_defaults.functions.update_phenotype = phenotype_function; + cell_defaults.functions.custom_cell_rule = custom_function; + cell_defaults.functions.contact_function = contact_function; + + // ?? // cell_defaults.parameters.o2_proliferation_saturation = 38.0; cell_defaults.parameters.o2_reference = 38.0; + + // cancer cells + Cell_Definition* pCD = find_cell_definition( "cancer cell"); + pCD->functions.update_phenotype = tumor_cell_phenotype_with_therapy; + + pCD->parameters.o2_proliferation_saturation = 38.0; + pCD->parameters.o2_reference = 38.0; + + // cargo cells + pCD = find_cell_definition( "cargo cell"); + + // figure out mechanics parameters - int oxygen_ID = microenvironment.find_density_index( "oxygen" ); // 0 - int attract_ID = microenvironment.find_density_index( "chemoattractant" ); // 1 - int therapy_ID = microenvironment.find_density_index( "therapeutic" ); // 2 - - // set the default cell type to o2-based proliferation with the effect of the - // on oncoprotein, and secretion of the immunostimulatory factor - - cell_defaults.functions.update_phenotype = tumor_cell_phenotype_with_therapy; - cell_defaults.functions.custom_cell_rule = NULL; - - // change the max cell-cell adhesion distance - cell_defaults.phenotype.mechanics.set_relative_maximum_adhesion_distance(parameters.doubles("max_relative_cell_adhesion_distance") ); - - cell_defaults.phenotype.mechanics.attachment_elastic_constant = parameters.doubles( "elastic_coefficient" ); + pCD->phenotype.mechanics.relative_maximum_attachment_distance + = pCD->custom_data["max_attachment_distance"] / pCD->phenotype.geometry.radius ; - /* - This parses the cell definitions in the XML config file. - */ + pCD->phenotype.mechanics.relative_detachment_distance + = pCD->custom_data["max_elastic_displacement"] / pCD->phenotype.geometry.radius ; + + pCD->phenotype.mechanics.attachment_elastic_constant + = pCD->custom_data["elastic_coefficient"]; - initialize_cell_definitions_from_pugixml(); + // set functions + pCD->functions.update_phenotype = cargo_cell_phenotype_rule; + pCD->functions.custom_cell_rule = cargo_cell_rule; + pCD->functions.contact_function = biorobots_contact_function; + pCD->functions.update_migration_bias = NULL; + + // worker cells + + pCD = find_cell_definition( "worker cell"); + + pCD->phenotype.mechanics.relative_maximum_attachment_distance + = pCD->custom_data["max_attachment_distance"] / pCD->phenotype.geometry.radius ; - // create the biorobot types - create_cargo_cell_type(); - create_worker_cell_type(); + pCD->phenotype.mechanics.relative_detachment_distance + = pCD->custom_data["max_elastic_displacement"] / pCD->phenotype.geometry.radius ; + + pCD->phenotype.mechanics.attachment_elastic_constant + = pCD->custom_data["elastic_coefficient"]; + + pCD->functions.update_phenotype = NULL; // worker_cell_rule; + pCD->functions.custom_cell_rule = worker_cell_rule; + pCD->functions.contact_function = biorobots_contact_function; - build_cell_definitions_maps(); + /* + This builds the map of cell definitions and summarizes the setup. + */ + display_cell_definitions( std::cout ); return; @@ -202,55 +180,60 @@ void create_cell_types( void ) void setup_microenvironment( void ) { - // set domain parameters + // set domain parameters + + // put any custom code to set non-homogeneous initial conditions or + // extra Dirichlet nodes here. + + // initialize BioFVM - if( default_microenvironment_options.simulate_2D == false ) - { - std::cout << "WARNING: overriding from 3-D to 2-D" << std::endl; - default_microenvironment_options.simulate_2D = true; - } - initialize_microenvironment(); - + return; -} +} -//keep -void introduce_biorobots( void ) +void setup_tissue( void ) { - // idea: we'll "inject" them in a little column - - static double worker_fraction = - parameters.doubles("worker_fraction"); // 0.10; /* param */ - static int number_of_injected_cells = - parameters.ints("number_of_injected_cells"); // 500; /* param */ - - // make these vary with domain size - double left_coordinate = default_microenvironment_options.X_range[1] - 150.0; // 600.0; - double right_cooridnate = default_microenvironment_options.X_range[1] - 50.0; // 700.0; + double Xmin = microenvironment.mesh.bounding_box[0]; + double Ymin = microenvironment.mesh.bounding_box[1]; + double Zmin = microenvironment.mesh.bounding_box[2]; - double bottom_coordinate = default_microenvironment_options.Y_range[0] + 50.0; // -700; - double top_coordinate = default_microenvironment_options.Y_range[1] - 50.0; // 700; - - for( int i=0 ;i < number_of_injected_cells ; i++ ) + double Xmax = microenvironment.mesh.bounding_box[3]; + double Ymax = microenvironment.mesh.bounding_box[4]; + double Zmax = microenvironment.mesh.bounding_box[5]; + + if( default_microenvironment_options.simulate_2D == true ) { - std::vector position = {0,0,0}; - position[0] = left_coordinate + (right_cooridnate-left_coordinate)*UniformRandom(); - position[1] = bottom_coordinate + (top_coordinate-bottom_coordinate)*UniformRandom(); - - Cell* pCell; - if( UniformRandom() <= worker_fraction ) - { pCell = create_cell( *worker_cell ); } - else - { pCell = create_cell( *cargo_cell ); } - pCell->assign_position( position ); + Zmin = 0.0; + Zmax = 0.0; } - return; -} + double Xrange = Xmax - Xmin; + double Yrange = Ymax - Ymin; + double Zrange = Zmax - Zmin; + + // create some of each type of cell + + Cell* pC; + + for( int k=0; k < cell_definitions_by_index.size() ; k++ ) + { + Cell_Definition* pCD = cell_definitions_by_index[k]; + std::cout << "Placing cells of type " << pCD->name << " ... " << std::endl; + for( int n = 0 ; n < parameters.ints("number_of_cells") ; n++ ) + { + std::vector position = {0,0,0}; + position[0] = Xmin + UniformRandom()*Xrange; + position[1] = Ymin + UniformRandom()*Yrange; + position[2] = Zmin + UniformRandom()*Zrange; + + pC = create_cell( *pCD ); + pC->assign_position( position ); + } + } + std::cout << std::endl; -void setup_tissue( void ) -{ + // custom placement // place a cluster of tumor cells at the center double cell_radius = cell_defaults.phenotype.geometry.radius; @@ -259,6 +242,7 @@ void setup_tissue( void ) double tumor_radius = parameters.doubles("tumor_radius"); // 200.0; Cell* pCell = NULL; + Cell_Definition* pCD_cancer = find_cell_definition( "cancer cell"); double x = 0.0; double x_outer = tumor_radius; @@ -279,45 +263,62 @@ void setup_tissue( void ) if( fabs( y ) > 0.01 ) { - pCell = create_cell(); // tumor cell + pCell = create_cell(*pCD_cancer); // tumor cell pCell->assign_position( x , -y , 0.0 ); } if( fabs( x ) > 0.01 ) { - pCell = create_cell(); // tumor cell + pCell = create_cell(*pCD_cancer); // tumor cell pCell->assign_position( -x , y , 0.0 ); if( fabs( y ) > 0.01 ) { - pCell = create_cell(); // tumor cell + pCell = create_cell(*pCD_cancer); // tumor cell pCell->assign_position( -x , -y , 0.0 ); } } x += cell_spacing; - } y += cell_spacing * sqrt(3.0)/2.0; n++; } + // load cells from your CSV file (if enabled) - load_cells_from_pugixml(); + load_cells_from_pugixml(); return; } -// done +std::vector my_coloring_function( Cell* pCell ) +{ return paint_by_number_cell_coloring(pCell); } + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ return; } + +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) +{ return; } + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) +{ return; } + std::vector cancer_biorobots_coloring_function( Cell* pCell ) { std::vector< std::string > output( 4, "black" ); - static int damage_i = pCell->custom_data.find_variable_index( "damage" ); - static double max_damage = 1.0 * cell_defaults.custom_data["damage_rate"] / (1e-16 + cell_defaults.custom_data[ "repair_rate" ] ); + double damage = get_single_signal( pCell, "damage"); + + static double max_damage = 1.0 * get_single_signal(pCell,"custom:damage_rate") + / (1e-16 + get_single_signal(pCell,"custom:repair_rate" ) ); + + static Cell_Definition* pCD_cargo = find_cell_definition( "cargo cell"); + static Cell_Definition* pCD_cancer = find_cell_definition( "cancer cell"); + static Cell_Definition* pCD_worker = find_cell_definition( "worker cell"); // cargo cell - if( pCell->type == cargo_cell->type ) + if( pCell->type == pCD_cargo->type ) { output[0] = "blue"; output[1] = "blue"; @@ -327,7 +328,7 @@ std::vector cancer_biorobots_coloring_function( Cell* pCell ) } // worker cell - if( pCell->type == worker_cell->type ) + if( pCell->type == pCD_worker->type ) { output[0] = "red"; output[1] = "red"; @@ -337,7 +338,7 @@ std::vector cancer_biorobots_coloring_function( Cell* pCell ) } // apoptotic tumor - cyan - if (pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::apoptotic ) // Apoptotic - cyan + if( get_single_signal( pCell, "apoptotic" ) > 0.5 ) // Apoptotic - cyan { output[0] = "cyan"; output[2] = "darkcyan"; @@ -345,9 +346,7 @@ std::vector cancer_biorobots_coloring_function( Cell* pCell ) } // Necrotic tumor - Brown - if( pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_swelling || - pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_lysed || - pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic ) + if( get_single_signal( pCell, "necrotic") > 0.5 ) { output[0] = "rgb(250,138,38)"; output[2] = "rgb(139,69,19)"; @@ -358,157 +357,59 @@ std::vector cancer_biorobots_coloring_function( Cell* pCell ) // if live: color by damage - if( pCell->phenotype.death.dead == false ) + if( get_single_signal( pCell, "dead") < 0.5 ) { - int damage = (int) round( pCell->custom_data[damage_i] * 255.0 / max_damage ); + int damage_int = (int) round( damage * 255.0 / max_damage ); char szTempString [128]; - sprintf( szTempString , "rgb(%u,%u,%u)" , damage , 255-damage , damage ); + sprintf( szTempString , "rgb(%u,%u,%u)" , damage_int , 255-damage_int , damage_int ); output[0].assign( szTempString ); output[1].assign( szTempString ); - sprintf( szTempString , "rgb(%u,%u,%u)" , damage/4 , (255-damage)/4 , damage/4 ); + sprintf( szTempString , "rgb(%u,%u,%u)" , damage_int/4 , (255-damage_int)/4 , damage_int/4 ); output[2].assign( szTempString ); } return output; } -// keep! -Cell* worker_cell_check_neighbors_for_attachment( Cell* pWorker , double dt ) -{ - std::vector nearby = pWorker->cells_in_my_container(); - int i = 0; - while( i < nearby.size() ) - { - // don't try to attach to yourself - if( nearby[i] != pWorker ) - { - if( worker_cell_attempt_attachment( pWorker, nearby[i] , dt ) ) - { return nearby[i]; } - } - i++; - } - - return NULL; -} - -// keep! -bool worker_cell_attempt_attachment( Cell* pWorker, Cell* pCargo , double dt ) +void introduce_biorobots( void ) { - static int receptor_i = pCargo->custom_data.find_variable_index( "receptor" ); - - static double receptor_threshold = - parameters.doubles("attachment_receptor_threshold"); // 0.1; - - static double max_attachment_distance = - parameters.doubles("max_attachment_distance"); // 18.0; - static double min_attachment_distance = - parameters.doubles("min_attachment_distance"); // 14.0; - static double attachment_difference = max_attachment_distance - min_attachment_distance; - - if( pCargo->custom_data[receptor_i] > receptor_threshold ) - { - std::vector displacement = pCargo->position - pWorker->position; - double distance = norm( displacement ); - if( distance > max_attachment_distance ) - { return false; } - - if( distance < min_attachment_distance ) - { - attach_cells( pWorker, pCargo ); - return true; - } + // idea: we'll "inject" them in a little column - return true; - } + static double worker_fraction = + parameters.doubles("worker_fraction"); // 0.10; /* param */ + static int number_of_injected_cells = + parameters.ints("number_of_injected_cells"); // 500; /* param */ - return false; -} + // make these vary with domain size + double left_coordinate = default_microenvironment_options.X_range[1] - 150.0; // 600.0; + double right_cooridnate = default_microenvironment_options.X_range[1] - 50.0; // 700.0; -void worker_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ) -{ - // if I am dead, don't bother + double bottom_coordinate = default_microenvironment_options.Y_range[0] + 50.0; // -700; + double top_coordinate = default_microenvironment_options.Y_range[1] - 50.0; // 700; - if( phenotype.death.dead == true ) - { - // the cell death functions don't automatically turn off custom functions, - // since those are part of mechanics. + Cell_Definition* pCD_worker = find_cell_definition( "worker cell"); + Cell_Definition* pCD_cargo = find_cell_definition( "cargo cell"); - // Let's just fully disable now. - pCell->functions.custom_cell_rule = NULL; - return; - } - - // am I searching for cargo? if so, see if I've found it - if( pCell->state.number_of_attached_cells() == 0 ) - { - std::vector nearby = pCell->cells_in_my_container(); - bool attached = false; // want to limit to one attachment - int i =0; - while( i < nearby.size() && attached == false ) - { - // if it is expressing the receptor, dock with it - if( nearby[i]->custom_data["receptor"] > 0.5 && attached == false ) - { - attach_cells( pCell, nearby[i] ); - // nearby[i]->custom_data["receptor"] = 0.0; // put into cargo cell rule instead? - // nearby[i]->phenotype.secretion.set_all_secretion_to_zero(); // put into cargo rule instead? - attached = true; - } - i++; - } - - } - - return; -} - -void worker_cell_motility( Cell* pCell, Phenotype& phenotype, double dt ) -{ - static int o2_index = microenvironment.find_density_index( "oxygen" ); - static int signal_index = microenvironment.find_density_index( "chemoattractant" ); - - static double detection_threshold = - parameters.doubles("motility_shutdown_detection_threshold"); // 0.001; - - // if attached, biased motility towards director chemoattractant - // otherwise, biased motility towards cargo chemoattractant - - static double attached_worker_migration_bias = - parameters.doubles("attached_worker_migration_bias"); - static double unattached_worker_migration_bias = - parameters.doubles("unattached_worker_migration_bias"); - - if( pCell->state.number_of_attached_cells() > 0 ) - { - phenotype.motility.migration_bias = attached_worker_migration_bias; - - phenotype.motility.migration_bias_direction = pCell->nearest_gradient(o2_index); - phenotype.motility.migration_bias_direction *= -1.0; - normalize( &( phenotype.motility.migration_bias_direction ) ); - } - else + for( int i=0 ;i < number_of_injected_cells ; i++ ) { - // if there is no detectable signal, shut down motility (permanently) - if( pCell->nearest_density_vector()[signal_index] < detection_threshold ) - { - phenotype.motility.is_motile = false; - pCell->functions.update_migration_bias = NULL; - } - - phenotype.motility.migration_bias = unattached_worker_migration_bias; + std::vector position = {0,0,0}; + position[0] = left_coordinate + (right_cooridnate-left_coordinate)*UniformRandom(); + position[1] = bottom_coordinate + (top_coordinate-bottom_coordinate)*UniformRandom(); - phenotype.motility.migration_bias_direction = pCell->nearest_gradient(signal_index); - normalize( &( phenotype.motility.migration_bias_direction ) ); + Cell* pCell; + if( UniformRandom() <= worker_fraction ) + { pCell = create_cell( *pCD_worker ); } + else + { pCell = create_cell( *pCD_cargo ); } + pCell->assign_position( position ); } return; } -/* CARGO CELL RULES */ - void cargo_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ) { - if( phenotype.death.dead == true ) + if( get_single_signal( pCell, "dead" ) > 0.5 ) { // the cell death functions don't automatically turn off custom functions, // since those are part of mechanics. @@ -521,40 +422,32 @@ void cargo_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ) // if I'm docked if( pCell->state.number_of_attached_cells() > 0 ) { - phenotype.motility.is_motile = false; + set_single_behavior( pCell, "migration speed" , 0.0 ); return; } return; } -// phenotype rule void cargo_cell_phenotype_rule( Cell* pCell, Phenotype& phenotype, double dt ) { - static int o2_index = microenvironment.find_density_index( "oxygen" ); - static int signal_index = microenvironment.find_density_index( "chemoattractant" ); - static int drug_index = microenvironment.find_density_index( "therapeutic" ); - - static int drop_index = pCell->custom_data.find_variable_index( "cargo_release_o2_threshold" ); - static int receptor_index = pCell->custom_data.find_variable_index( "receptor" ); - - static int apoptosis_model_index = phenotype.death.find_death_model_index( "apoptosis" ); - // if dettached and receptor on, secrete signal // if dettached and receptor off, secrete chemo + + double receptor = get_single_signal( pCell , "custom:receptor" ); if( pCell->state.number_of_attached_cells() == 0 ) { - if( pCell->custom_data[receptor_index] > 0.1 ) + if( receptor > 0.1 ) { - phenotype.secretion.secretion_rates[signal_index] = 10.0; - phenotype.secretion.secretion_rates[drug_index] = 0.0; + set_single_behavior( pCell , "chemoattractant secretion" , 10); + set_single_behavior( pCell , "therapeutic secretion" , 0); } else { - phenotype.secretion.secretion_rates[signal_index] = 0.0; - phenotype.secretion.secretion_rates[drug_index] = 10.0; + set_single_behavior( pCell , "chemoattractant secretion" , 0); + set_single_behavior( pCell , "therapeutic secretion" , 10); } return; } @@ -565,18 +458,21 @@ void cargo_cell_phenotype_rule( Cell* pCell, Phenotype& phenotype, double dt ) // if attached and oxygen high, secrete nothing, receptor off // if attached and oxygen low, dettach, start secreting chemo, receptor off + + double o2 = get_single_signal( pCell, "oxygen"); + double o2_drop = get_single_signal( pCell , "custom:cargo_release_o2_threshold"); - if( pCell->nearest_density_vector()[o2_index] > pCell->custom_data[drop_index] ) + if( o2 > o2_drop ) { - phenotype.secretion.secretion_rates[signal_index] = 0.0; - phenotype.secretion.secretion_rates[drug_index] = 0.0; - pCell->custom_data[receptor_index] = 0.0; + set_single_behavior( pCell , "chemoattractant secretion" , 0); + set_single_behavior( pCell , "therapeutic secretion" , 0); + set_single_behavior( pCell , "custom:receptor" , 0 ); } else { - phenotype.secretion.secretion_rates[signal_index] = 0.0; - phenotype.secretion.secretion_rates[drug_index] = 10.0; - pCell->custom_data[receptor_index] = 0.0; + set_single_behavior( pCell , "chemoattractant secretion" , 0); + set_single_behavior( pCell , "therapeutic secretion" , 10); + set_single_behavior( pCell , "custom:receptor" , 0 ); pCell->remove_all_attached_cells(); } @@ -584,26 +480,40 @@ void cargo_cell_phenotype_rule( Cell* pCell, Phenotype& phenotype, double dt ) return; } -/* TUMOR CELL RULES */ +void biorobots_contact_function( Cell* pActingOn, Phenotype& pao, Cell* pAttachedTo, Phenotype& pat , double dt ) +{ + std::vector displacement = pAttachedTo->position - pActingOn->position; + + static double max_elastic_displacement = pao.geometry.radius * pao.mechanics.relative_detachment_distance; + static double max_displacement_squared = max_elastic_displacement*max_elastic_displacement; + + // detach cells if too far apart + + if( norm_squared( displacement ) > max_displacement_squared ) + { + detach_cells( pActingOn , pAttachedTo ); + return; + } + + axpy( &(pActingOn->velocity) , pao.mechanics.attachment_elastic_constant , displacement ); + + return; +} void tumor_cell_phenotype_with_therapy( Cell* pCell, Phenotype& phenotype, double dt ) { - static int cycle_start_index = live.find_phase_index( PhysiCell_constants::live ); - static int cycle_end_index = live.find_phase_index( PhysiCell_constants::live ); - static int damage_i = pCell->custom_data.find_variable_index( "damage" ); + double damage = get_single_signal( pCell, "damage"); - static int damage_rate_i = pCell->custom_data.find_variable_index( "damage_rate" ); - static int repair_rate_i = pCell->custom_data.find_variable_index( "repair_rate" ); - static int death_rate_i = pCell->custom_data.find_variable_index( "drug_death_rate" ); - - static int chemo_i = microenvironment.find_density_index( "therapeutic" ); - - static int apoptosis_model_index = phenotype.death.find_death_model_index( "apoptosis" ); + double damage_rate = get_single_signal( pCell , "custom:damage_rate"); + double repair_rate = get_single_signal( pCell , "custom:repair_rate"); + double drug_death_rate = get_single_signal( pCell , "custom:drug_death_rate" ); + + double drug = get_single_signal( pCell , "therapeutic"); - static double max_damage = 1.0 * cell_defaults.custom_data["damage_rate"] / (1e-16 + cell_defaults.custom_data[ "repair_rate" ] ); + static double max_damage = 1.0 * damage_rate / (1e-16 + repair_rate ); // if I'm dead, don't bother. disable my phenotype rule - if( phenotype.death.dead == true ) + if( get_single_signal( pCell, "dead") > 0.5 ) { pCell->functions.update_phenotype = NULL; return; @@ -611,35 +521,41 @@ void tumor_cell_phenotype_with_therapy( Cell* pCell, Phenotype& phenotype, doubl // first, vary the cell birth and death rates with oxygenation + // std::cout << get_single_behavior( pCell , "cycle entry") << " vs "; update_cell_and_death_parameters_O2_based(pCell,phenotype,dt); - + // std::cout << get_single_behavior( pCell , "cycle entry") << std::endl; + // the update the cell damage // dD/dt = alpha*c - beta-D by implicit scheme - double temp = pCell->nearest_density_vector()[chemo_i]; + double temp = drug; // reuse temp as much as possible to reduce memory allocations etc. temp *= dt; - temp *= pCell->custom_data[damage_rate_i]; + temp *= damage_rate; - pCell->custom_data[damage_i] += temp; // d_prev + dt*chemo*damage_rate + damage += temp; // d_prev + dt*chemo*damage_rate - temp = pCell->custom_data[repair_rate_i]; + temp = repair_rate; temp *= dt; temp += 1.0; - pCell->custom_data[damage_i] /= temp; // (d_prev + dt*chemo*damage_rate)/(1 + dt*repair_rate) + damage /= temp; // (d_prev + dt*chemo*damage_rate)/(1 + dt*repair_rate) // then, see if the cell undergoes death from the therapy temp = dt; - temp *= pCell->custom_data[damage_i]; - temp *= pCell->custom_data[death_rate_i]; + temp *= damage; + temp *= drug_death_rate; temp /= max_damage; // dt*(damage/max_damage)*death_rate + // make sure we write the damage (not current a behavior) + pCell->state.damage = damage; + if( UniformRandom() <= temp ) { - pCell->start_death( apoptosis_model_index ); + // pCell->start_death( apoptosis_model_index ); + set_single_behavior( pCell, "apoptosis" , 9e99 ); pCell->functions.update_phenotype = NULL; pCell->functions.custom_cell_rule = NULL; } @@ -647,23 +563,75 @@ void tumor_cell_phenotype_with_therapy( Cell* pCell, Phenotype& phenotype, doubl return; } -void biorobots_contact_function( Cell* pActingOn, Phenotype& pao, Cell* pAttachedTo, Phenotype& pat , double dt ) +void worker_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ) { - std::vector displacement = pAttachedTo->position - pActingOn->position; + // if I am dead, don't bother + + if( get_single_signal( pCell , "dead") > 0.5 ) + { + // the cell death functions don't automatically turn off custom functions, + // since those are part of mechanics. + + // Let's just fully disable now. + pCell->functions.custom_cell_rule = NULL; + return; + } - static double max_elastic_displacement = pao.geometry.radius * pao.mechanics.relative_detachment_distance; - static double max_displacement_squared = max_elastic_displacement*max_elastic_displacement; + // am I searching for cargo? if so, see if I've found it + if( pCell->state.number_of_attached_cells() == 0 ) + { + std::vector nearby = pCell->cells_in_my_container(); + bool attached = false; // want to limit to one attachment + int i =0; + while( i < nearby.size() && attached == false ) + { + // if it is expressing the receptor, dock with it + if( get_single_signal(nearby[i],"custom:receptor") > 0.5 && attached == false ) + { + attach_cells( pCell, nearby[i] ); + // nearby[i]->custom_data["receptor"] = 0.0; // put into cargo cell rule instead? + // nearby[i]->phenotype.secretion.set_all_secretion_to_zero(); // put into cargo rule instead? + attached = true; + } + i++; + } + } + + // from prior motility function + + double o2 = get_single_signal( pCell, "oxygen"); + double chemoattractant = get_single_signal( pCell , "chemoattractant"); + + static double detection_threshold = get_single_signal( pCell, "custom:motility_shutdown_detection_threshold"); - // detach cells if too far apart + // if attached, biased motility towards director chemoattractant + // otherwise, biased motility towards cargo chemoattractant - if( norm_squared( displacement ) > max_displacement_squared ) + static double attached_worker_migration_bias = get_single_signal( pCell, "custom:attached_worker_migration_bias"); + static double unattached_worker_migration_bias = get_single_signal( pCell , "custom:unattached_worker_migration_bias"); + + if( pCell->state.number_of_attached_cells() > 0 ) { - detach_cells( pActingOn , pAttachedTo ); - return; + set_single_behavior( pCell , "migration bias" , attached_worker_migration_bias ); + + set_single_behavior( pCell , "chemotactic response to oxygen" , -1 ); + set_single_behavior( pCell , "chemotactic response to chemoattractant" , 0 ); + } + else + { + // if there is no detectable signal, shut down motility (permanently) + if( chemoattractant < detection_threshold ) + { + set_single_behavior( pCell, "migration speed" , 0 ); + } + + set_single_behavior( pCell , "migration bias" , unattached_worker_migration_bias ); + + set_single_behavior( pCell , "chemotactic response to oxygen" , 0 ); + set_single_behavior( pCell , "chemotactic response to chemoattractant" , 1 ); } - - axpy( &(pActingOn->velocity) , pao.mechanics.attachment_elastic_constant , displacement ); return; } + diff --git a/sample_projects/cancer_biorobots/custom_modules/cancer_biorobots.h b/sample_projects/cancer_biorobots/custom_modules/custom.h similarity index 85% rename from sample_projects/cancer_biorobots/custom_modules/cancer_biorobots.h rename to sample_projects/cancer_biorobots/custom_modules/custom.h index 15cdad826..ab1adcf04 100644 --- a/sample_projects/cancer_biorobots/custom_modules/cancer_biorobots.h +++ b/sample_projects/cancer_biorobots/custom_modules/custom.h @@ -71,33 +71,39 @@ using namespace BioFVM; using namespace PhysiCell; -// custom cell phenotype function to scale immunostimulatory factor with hypoxia -void tumor_cell_phenotype_with_therapy( Cell* pCell, Phenotype& phenotype, double dt ); // done +// setup functions to help us along -void create_cargo_cell_type( void ); //done -void create_worker_cell_type( void ); // done +void create_cell_types( void ); +void setup_tissue( void ); -// set the tumor cell properties, then call the function -// to set up the tumor cells -void create_cell_types( void ); // done +// set up the BioFVM microenvironment +void setup_microenvironment( void ); -void setup_tissue(); +// custom pathology coloring function -void introduce_biorobots( void ); // done +std::vector my_coloring_function( Cell* ); -// set up the microenvironment to include the immunostimulatory factor -void setup_microenvironment( void ); // done +// custom functions can go here -std::vector cancer_biorobots_coloring_function( Cell* ); // done +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ); -// cell rules for extra elastic adhesion +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ); -bool worker_cell_attempt_attachment( Cell* pWorker, Cell* pCargo , double dt ); // done +std::vector cancer_biorobots_coloring_function( Cell* ); -void worker_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ); // at mechanics time scale -void worker_cell_motility( Cell* pCell, Phenotype& phenotype, double dt ); +void introduce_biorobots( void ); -void cargo_cell_phenotype_rule( Cell* pCell , Phenotype& phenotype , double dt ); // done -void cargo_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ); // done +// cargo cells + +void cargo_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ); +void cargo_cell_phenotype_rule( Cell* pCell, Phenotype& phenotype, double dt ); + +void biorobots_contact_function( Cell* pActingOn, Phenotype& pao, Cell* pAttachedTo, Phenotype& pat , double dt ); + +// cancer cells +void tumor_cell_phenotype_with_therapy( Cell* pCell, Phenotype& phenotype, double dt ); + +// worker cells +void worker_cell_rule( Cell* pCell, Phenotype& phenotype, double dt ); -void biorobots_contact_function( Cell* , Phenotype& , Cell* , Phenotype& , double ); diff --git a/sample_projects/biorobots/scripts/empty.txt b/sample_projects/cancer_biorobots/custom_modules/empty.txt similarity index 100% rename from sample_projects/biorobots/scripts/empty.txt rename to sample_projects/cancer_biorobots/custom_modules/empty.txt diff --git a/sample_projects/cancer_biorobots/main-cancer_biorobots.cpp b/sample_projects/cancer_biorobots/main.cpp similarity index 96% rename from sample_projects/cancer_biorobots/main-cancer_biorobots.cpp rename to sample_projects/cancer_biorobots/main.cpp index b686d11d8..41876503a 100644 --- a/sample_projects/cancer_biorobots/main-cancer_biorobots.cpp +++ b/sample_projects/cancer_biorobots/main.cpp @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # @@ -76,9 +76,9 @@ #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" -// custom user modules +// put custom code modules here! -#include "./custom_modules/cancer_biorobots.h" +#include "./custom_modules/custom.h" using namespace BioFVM; using namespace PhysiCell; @@ -108,28 +108,24 @@ int main( int argc, char* argv[] ) // OpenMP setup omp_set_num_threads(PhysiCell_settings.omp_num_threads); - // PNRG setup - SeedRandom(); - // time setup std::string time_units = "min"; /* Microenvironment setup */ - setup_microenvironment(); - + setup_microenvironment(); // modify this in the custom code + /* PhysiCell setup */ // set mechanics voxel size, and match the data structure to BioFVM double mechanics_voxel_size = 30; Cell_Container* cell_container = create_cell_container_for_microenvironment( microenvironment, mechanics_voxel_size ); + /* Users typically start modifying here. START USERMODS */ + create_cell_types(); - setup_tissue(); - /* Users typically start modifying here. START USERMODS */ - - double therapy_activation_time = parameters.doubles("therapy_activation_time"); // 60 * 24 * 7; // inject therapy at 7 days + setup_tissue(); /* Users typically stop modifying here. END USERMODS */ @@ -141,7 +137,7 @@ int main( int argc, char* argv[] ) set_save_biofvm_cell_data_as_custom_matlab( true ); // save a simulation snapshot - + char filename[1024]; sprintf( filename , "%s/initial" , PhysiCell_settings.folder.c_str() ); save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); @@ -153,14 +149,14 @@ int main( int argc, char* argv[] ) // for simplicity, set a pathology coloring function - std::vector (*cell_coloring_function)(Cell*) = cancer_biorobots_coloring_function; + std::vector (*cell_coloring_function)(Cell*) = cancer_biorobots_coloring_function; sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); - create_plot_legend( filename , cell_coloring_function ); - + create_plot_legend( filename , cell_coloring_function ); + display_citations(); // set the performance timers @@ -175,15 +171,17 @@ int main( int argc, char* argv[] ) report_file.open(filename); // create the data log file report_file<<"simulated time\tnum cells\tnum division\tnum death\twall time"< therapy_activation_time - 0.01*diffusion_dt && therapy_introduced == false ) { std::cout << "Therapy started!" << std::endl; @@ -236,6 +234,10 @@ int main( int argc, char* argv[] ) // run PhysiCell ((Cell_Container *)microenvironment.agent_container)->update_all_cells( PhysiCell_globals.current_time ); + /* + Custom add-ons could potentially go here. + */ + PhysiCell_globals.current_time += diffusion_dt; } diff --git a/sample_projects/cancer_immune/Makefile b/sample_projects/cancer_immune/Makefile index 00e4a29b9..0d65dd05a 100644 --- a/sample_projects/cancer_immune/Makefile +++ b/sample_projects/cancer_immune/Makefile @@ -264,4 +264,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/cancer_immune/config/PhysiCell_settings.xml b/sample_projects/cancer_immune/config/PhysiCell_settings.xml index fe9e748f6..958f1ddfa 100644 --- a/sample_projects/cancer_immune/config/PhysiCell_settings.xml +++ b/sample_projects/cancer_immune/config/PhysiCell_settings.xml @@ -123,6 +123,7 @@ false true + true @@ -211,10 +212,10 @@ - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 diff --git a/sample_projects/celltypes3/Makefile b/sample_projects/celltypes3/Makefile index 2bb4ad783..a15199d9c 100644 --- a/sample_projects/celltypes3/Makefile +++ b/sample_projects/celltypes3/Makefile @@ -263,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/celltypes3/config/PhysiCell_settings.xml b/sample_projects/celltypes3/config/PhysiCell_settings.xml index 1d0e4def9..d33ac8a26 100644 --- a/sample_projects/celltypes3/config/PhysiCell_settings.xml +++ b/sample_projects/celltypes3/config/PhysiCell_settings.xml @@ -120,6 +120,7 @@ false + false @@ -259,10 +260,10 @@ - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 diff --git a/sample_projects/heterogeneity/Makefile b/sample_projects/heterogeneity/Makefile index da709e84a..9b2235264 100644 --- a/sample_projects/heterogeneity/Makefile +++ b/sample_projects/heterogeneity/Makefile @@ -58,18 +58,18 @@ PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o # put your custom objects here (they should be in the custom_modules directory) -PhysiCell_custom_module_OBJECTS := heterogeneity.o +PhysiCell_custom_module_OBJECTS := custom.o pugixml_OBJECTS := pugixml.o PhysiCell_OBJECTS := $(BioFVM_OBJECTS) $(pugixml_OBJECTS) $(PhysiCell_core_OBJECTS) $(PhysiCell_module_OBJECTS) ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiCell_custom_module_OBJECTS) -# compile the project +# compile the project all: main.cpp $(ALL_OBJECTS) $(COMPILE_COMMAND) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp - make name + make name name: @echo "" @@ -150,23 +150,23 @@ PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp - + PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp - $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp - $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp - $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp # user-defined PhysiCell modules -heterogeneity.o: ./custom_modules/heterogeneity.cpp - $(COMPILE_COMMAND) -c ./custom_modules/heterogeneity.cpp +custom.o: ./custom_modules/custom.cpp + $(COMPILE_COMMAND) -c ./custom_modules/custom.cpp # cleanup @@ -187,9 +187,6 @@ clean: rm -f $(PROGRAM_NAME)* data-cleanup: - # rm -f *.mat - # rm -f *.xml - # rm -f *.svg rm -rf ./output mkdir ./output touch ./output/empty.txt @@ -266,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/heterogeneity/VERSION.txt b/sample_projects/heterogeneity/VERSION.txt new file mode 100644 index 000000000..1cac385c6 --- /dev/null +++ b/sample_projects/heterogeneity/VERSION.txt @@ -0,0 +1 @@ +1.11.0 diff --git a/sample_projects/heterogeneity/config/PhysiCell_settings.xml b/sample_projects/heterogeneity/config/PhysiCell_settings.xml index f73707ffc..9bd89bc01 100644 --- a/sample_projects/heterogeneity/config/PhysiCell_settings.xml +++ b/sample_projects/heterogeneity/config/PhysiCell_settings.xml @@ -1,77 +1,3 @@ - - - - - -1000 @@ -87,7 +13,7 @@ - 64800 + 64800 min micron @@ -97,11 +23,11 @@ - 4 + 6 - output + output 60 @@ -120,176 +46,190 @@ false - true + true + false - - - 100000.00 - .1 - - 38.0 - 38.0 - - - - false - false - + + + 100000.0 + 0.1 + + 38 + 38 + + 38 + 38 + 38 + 38 + 38 + 38 + + + + + true + true + ./config/initial.mat - + ./config/dirichlet.mat - + - - - - - - 0.00072 - - - - - - - - - 5.31667e-05 - - - - 516 - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 - 0 - 2.0 - - + + + + 0.00072 + + + + + + 5.31667e-05 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 0.0 + 0.0 + + + + 1 + 1 + .5 + + false + true + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + + 0 + 1 + 10 + 0 + + + + + 0 + + 0 + + + + 0 + + + 1 + + 0 + + + - - 0.0 - - - - - 0 - 86400 - - - - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 - 0 - 2.0 - - - + + + 0 + + - - 2494 - 0.75 - 540 - - 0.05 - 0.0045 - 0.0055 - - 0 - 0 - - 2.0 - - - - - 0.4 - 10.0 - 1.25 - - - 1.8 - 15.12 - - - - - 1 - 1 - .5 - - - false - true - - false - oxygen - -1 - - - - - - - 0 - 38 - 10 - 0 - - + + + 1.0 + + - - - - - 1.0 - - - + ./config cells.csv - + - 250.0 - 1.0 - 0.25 - 0.0 - 2 - 0 - + 0 + 0 + 250 + 1 + 0.25 + 0.0 + 2 + - + \ No newline at end of file diff --git a/sample_projects/heterogeneity/config/cells.csv b/sample_projects/heterogeneity/config/cells.csv index acdc5b6bf..734bdc767 100644 --- a/sample_projects/heterogeneity/config/cells.csv +++ b/sample_projects/heterogeneity/config/cells.csv @@ -1 +1 @@ -0,0,0,0 +0,0,0,0 \ No newline at end of file diff --git a/sample_projects/heterogeneity/custom_modules/heterogeneity.cpp b/sample_projects/heterogeneity/custom_modules/custom.cpp similarity index 67% rename from sample_projects/heterogeneity/custom_modules/heterogeneity.cpp rename to sample_projects/heterogeneity/custom_modules/custom.cpp index ef9ada63f..657592349 100644 --- a/sample_projects/heterogeneity/custom_modules/heterogeneity.cpp +++ b/sample_projects/heterogeneity/custom_modules/custom.cpp @@ -65,8 +65,7 @@ ############################################################################### */ -#include "./heterogeneity.h" -#include "../modules/PhysiCell_settings.h" +#include "./custom.h" void create_cell_types( void ) { @@ -81,31 +80,57 @@ void create_cell_types( void ) */ initialize_default_cell_definition(); - - cell_defaults.parameters.o2_proliferation_saturation = 38.0; - cell_defaults.parameters.o2_reference = 38.0; + cell_defaults.phenotype.secretion.sync_to_microenvironment( µenvironment ); - cell_defaults.functions.update_phenotype = tumor_cell_phenotype_with_oncoprotein; cell_defaults.functions.volume_update_function = standard_volume_update_function; - cell_defaults.functions.update_velocity = standard_update_cell_velocity; + cell_defaults.functions.update_velocity = standard_update_cell_velocity; + + cell_defaults.functions.update_migration_bias = NULL; + cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based; + cell_defaults.functions.custom_cell_rule = NULL; + cell_defaults.functions.contact_function = NULL; + + cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; + cell_defaults.functions.calculate_distance_to_membrane = NULL; - /* + /* This parses the cell definitions in the XML config file. */ initialize_cell_definitions_from_pugixml(); - + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + build_cell_definitions_maps(); + + /* + This intializes cell signal and response dictionaries + */ + + setup_signal_behavior_dictionaries(); + /* Put any modifications to individual cell definitions here. This is a good place to set custom functions. */ + cell_defaults.functions.update_phenotype = phenotype_function; + cell_defaults.functions.custom_cell_rule = custom_function; + cell_defaults.functions.contact_function = contact_function; + + Cell_Definition* pCD = find_cell_definition( "cancer cell"); + pCD->functions.update_phenotype = tumor_cell_phenotype_with_oncoprotein; + + pCD->parameters.o2_proliferation_saturation = 38; + pCD->parameters.o2_reference = 38; + /* This builds the map of cell definitions and summarizes the setup. */ - build_cell_definitions_maps(); display_cell_definitions( std::cout ); return; @@ -113,23 +138,63 @@ void create_cell_types( void ) void setup_microenvironment( void ) { - // make sure ot override and go back to 2D - if( default_microenvironment_options.simulate_2D == false ) - { - std::cout << "Warning: overriding XML config option and setting to 2D!" << std::endl; - default_microenvironment_options.simulate_2D = true; - } - + // set domain parameters + + // put any custom code to set non-homogeneous initial conditions or + // extra Dirichlet nodes here. + + // initialize BioFVM + initialize_microenvironment(); - + return; -} +} void setup_tissue( void ) { - // place a cluster of tumor cells at the center + double Xmin = microenvironment.mesh.bounding_box[0]; + double Ymin = microenvironment.mesh.bounding_box[1]; + double Zmin = microenvironment.mesh.bounding_box[2]; + + double Xmax = microenvironment.mesh.bounding_box[3]; + double Ymax = microenvironment.mesh.bounding_box[4]; + double Zmax = microenvironment.mesh.bounding_box[5]; + + if( default_microenvironment_options.simulate_2D == true ) + { + Zmin = 0.0; + Zmax = 0.0; + } - double cell_radius = cell_defaults.phenotype.geometry.radius; + double Xrange = Xmax - Xmin; + double Yrange = Ymax - Ymin; + double Zrange = Zmax - Zmin; + + // create some of each type of cell + + Cell* pC; + + for( int k=0; k < cell_definitions_by_index.size() ; k++ ) + { + Cell_Definition* pCD = cell_definitions_by_index[k]; + std::cout << "Placing cells of type " << pCD->name << " ... " << std::endl; + for( int n = 0 ; n < parameters.ints("number_of_cells") ; n++ ) + { + std::vector position = {0,0,0}; + position[0] = Xmin + UniformRandom()*Xrange; + position[1] = Ymin + UniformRandom()*Yrange; + position[2] = Zmin + UniformRandom()*Zrange; + + pC = create_cell( *pCD ); + pC->assign_position( position ); + } + } + std::cout << std::endl; + + // custom placement + + Cell_Definition* pCD = find_cell_definition( "cancer cell"); + double cell_radius = pCD->phenotype.geometry.radius; double cell_spacing = 0.95 * 2.0 * cell_radius; double tumor_radius = parameters.doubles( "tumor_radius" ); // 250.0; @@ -159,44 +224,49 @@ void setup_tissue( void ) while( x < x_outer ) { - pCell = create_cell(); // tumor cell + pCell = create_cell( *pCD ); // tumor cell pCell->assign_position( x , y , 0.0 ); - pCell->custom_data[0] = NormalRandom( p_mean, p_sd ); - if( pCell->custom_data[0] < p_min ) - { pCell->custom_data[0] = p_min; } - if( pCell->custom_data[0] > p_max ) - { pCell->custom_data[0] = p_max; } + double p = NormalRandom( p_mean, p_sd ); + if( p < p_min ) + { p = p_min; } + if( p > p_max ) + { p = p_max; } + set_single_behavior( pCell, "custom:oncoprotein" , p ); if( fabs( y ) > 0.01 ) { - pCell = create_cell(); // tumor cell + pCell = create_cell(*pCD); // tumor cell pCell->assign_position( x , -y , 0.0 ); - pCell->custom_data[0] = NormalRandom( p_mean, p_sd ); - if( pCell->custom_data[0] < p_min ) - { pCell->custom_data[0] = p_min; } - if( pCell->custom_data[0] > p_max ) - { pCell->custom_data[0] = p_max; } + double p = NormalRandom( p_mean, p_sd ); + if( p < p_min ) + { p = p_min; } + if( p > p_max ) + { p = p_max; } + set_single_behavior( pCell, "custom:oncoprotein" , p ); } if( fabs( x ) > 0.01 ) { - pCell = create_cell(); // tumor cell + pCell = create_cell(*pCD); // tumor cell pCell->assign_position( -x , y , 0.0 ); - pCell->custom_data[0] = NormalRandom( p_mean, p_sd ); - if( pCell->custom_data[0] < p_min ) - { pCell->custom_data[0] = p_min; } - if( pCell->custom_data[0] > p_max ) - { pCell->custom_data[0] = p_max; } + double p = NormalRandom( p_mean, p_sd ); + if( p < p_min ) + { p = p_min; } + if( p > p_max ) + { p = p_max; } + set_single_behavior( pCell, "custom:oncoprotein" , p ); if( fabs( y ) > 0.01 ) { - pCell = create_cell(); // tumor cell + pCell = create_cell(*pCD); // tumor cell pCell->assign_position( -x , -y , 0.0 ); - pCell->custom_data[0] = NormalRandom( p_mean, p_sd ); - if( pCell->custom_data[0] < p_min ) - { pCell->custom_data[0] = p_min; } - if( pCell->custom_data[0] > p_max ) - { pCell->custom_data[0] = p_max; } + double p = NormalRandom( p_mean, p_sd ); + if( p < p_min ) + { p = p_min; } + if( p > p_max ) + { p = p_max; } + set_single_behavior( pCell, "custom:oncoprotein" , p ); + } } x += cell_spacing; @@ -212,7 +282,7 @@ void setup_tissue( void ) double max = -9e9; for( int i=0; i < all_cells->size() ; i++ ) { - double r = (*all_cells)[i]->custom_data[0]; + double r = get_single_signal( (*all_cells)[i] , "custom:oncoprotein" ); sum += r; if( r < min ) { min = r; } @@ -224,7 +294,8 @@ void setup_tissue( void ) sum = 0.0; for( int i=0; i < all_cells->size(); i++ ) { - sum += ( (*all_cells)[i]->custom_data[0] - mean )*( (*all_cells)[i]->custom_data[0] - mean ); + double r = get_single_signal( (*all_cells)[i] , "custom:oncoprotein" ); + sum += ( r - mean )*( r - mean ); } double standard_deviation = sqrt( sum / ( all_cells->size() - 1.0 + 1e-15 ) ); @@ -232,40 +303,29 @@ void setup_tissue( void ) << "===================" << std::endl; std::cout << "mean: " << mean << std::endl; std::cout << "standard deviation: " << standard_deviation << std::endl; - std::cout << "[min max]: [" << min << " " << max << "]" << std::endl << std::endl; + std::cout << "[min max]: [" << min << " " << max << "]" << std::endl << std::endl; // load cells from your CSV file (if enabled) - load_cells_from_pugixml(); + load_cells_from_pugixml(); return; } -// custom cell phenotype function to scale immunostimulatory factor with hypoxia -void tumor_cell_phenotype_with_oncoprotein( Cell* pCell, Phenotype& phenotype, double dt ) -{ - update_cell_and_death_parameters_O2_based(pCell,phenotype,dt); - - // if cell is dead, don't bother with future phenotype changes. - if( phenotype.death.dead == true ) - { - pCell->functions.update_phenotype = NULL; - return; - } +std::vector my_coloring_function( Cell* pCell ) +{ return paint_by_number_cell_coloring(pCell); } - // multiply proliferation rate by the oncoprotein - - static int cycle_start_index = live.find_phase_index( PhysiCell_constants::live ); - static int cycle_end_index = live.find_phase_index( PhysiCell_constants::live ); - static int oncoprotein_i = pCell->custom_data.find_variable_index( "oncoprotein" ); +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ return; } - phenotype.cycle.data.transition_rate( cycle_start_index ,cycle_end_index ) *= pCell->custom_data[oncoprotein_i] ; - - return; -} +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) +{ return; } + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) +{ return; } std::vector heterogeneity_coloring_function( Cell* pCell ) { - static int oncoprotein_i = pCell->custom_data.find_variable_index( "oncoprotein" ); + double p = get_single_signal( pCell, "custom:oncoprotein"); static double p_min = parameters.doubles( "oncoprotein_min" ); static double p_max = parameters.doubles( "oncoprotein_max" ); @@ -279,7 +339,7 @@ std::vector heterogeneity_coloring_function( Cell* pCell ) // live cells are green, but shaded by oncoprotein value if( pCell->phenotype.death.dead == false ) { - int oncoprotein = (int) round( (1.0/(p_max-p_min)) * (pCell->custom_data[oncoprotein_i]-p_min) * 255.0 ); + int oncoprotein = (int) round( (1.0/(p_max-p_min)) * (p-p_min) * 255.0 ); char szTempString [128]; sprintf( szTempString , "rgb(%u,%u,%u)", oncoprotein, oncoprotein, 255-oncoprotein ); output[0].assign( szTempString ); @@ -293,16 +353,14 @@ std::vector heterogeneity_coloring_function( Cell* pCell ) // if not, dead colors - if (pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::apoptotic ) // Apoptotic - Red + if( get_single_signal( pCell, "apoptotic") > 0.5 ) { output[0] = "rgb(255,0,0)"; output[2] = "rgb(125,0,0)"; } // Necrotic - Brown - if( pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_swelling || - pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic_lysed || - pCell->phenotype.cycle.current_phase().code == PhysiCell_constants::necrotic ) + if( get_single_signal(pCell, "necrotic") > 0.5 ) { output[0] = "rgb(250,138,38)"; output[2] = "rgb(139,69,19)"; @@ -310,3 +368,23 @@ std::vector heterogeneity_coloring_function( Cell* pCell ) return output; } + +void tumor_cell_phenotype_with_oncoprotein( Cell* pCell, Phenotype& phenotype, double dt ) +{ + update_cell_and_death_parameters_O2_based(pCell,phenotype,dt); + + // if cell is dead, don't bother with future phenotype changes. + if( get_single_signal( pCell, "dead") > 0.5 ) + { + pCell->functions.update_phenotype = NULL; + return; + } + + // multiply proliferation rate by the oncoprotein + + double cycle_rate = get_single_behavior( pCell, "cycle entry"); + cycle_rate *= get_single_signal( pCell , "custom:oncoprotein"); + set_single_behavior( pCell, "cycle entry" , cycle_rate ); + + return; +} \ No newline at end of file diff --git a/sample_projects/heterogeneity/custom_modules/heterogeneity.h b/sample_projects/heterogeneity/custom_modules/custom.h similarity index 91% rename from sample_projects/heterogeneity/custom_modules/heterogeneity.h rename to sample_projects/heterogeneity/custom_modules/custom.h index fdbc53e90..1d66a2fe9 100644 --- a/sample_projects/heterogeneity/custom_modules/heterogeneity.h +++ b/sample_projects/heterogeneity/custom_modules/custom.h @@ -71,16 +71,26 @@ using namespace BioFVM; using namespace PhysiCell; -// custom cell phenotype function to scale immunostimulatory factor with hypoxia -void tumor_cell_phenotype_with_oncoprotein( Cell* pCell, Phenotype& phenotype, double dt ); +// setup functions to help us along -// set the tumor cell properties, then call the function -// to set up the tumor cells void create_cell_types( void ); +void setup_tissue( void ); + +// set up the BioFVM microenvironment +void setup_microenvironment( void ); + +// custom pathology coloring function + +std::vector my_coloring_function( Cell* ); -void setup_tissue(); +// custom functions can go here -// set up the microenvironment to include the immunostimulatory factor -void setup_microenvironment( void ); // done +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ); + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ); std::vector heterogeneity_coloring_function( Cell* ); + +void tumor_cell_phenotype_with_oncoprotein( Cell* pCell, Phenotype& phenotype, double dt ); + diff --git a/sample_projects/cancer_biorobots/scripts/empty.txt b/sample_projects/heterogeneity/custom_modules/empty.txt similarity index 100% rename from sample_projects/cancer_biorobots/scripts/empty.txt rename to sample_projects/heterogeneity/custom_modules/empty.txt diff --git a/sample_projects/heterogeneity/main-heterogeneity.cpp b/sample_projects/heterogeneity/main.cpp similarity index 96% rename from sample_projects/heterogeneity/main-heterogeneity.cpp rename to sample_projects/heterogeneity/main.cpp index dcae79e93..09bd280c0 100644 --- a/sample_projects/heterogeneity/main-heterogeneity.cpp +++ b/sample_projects/heterogeneity/main.cpp @@ -33,7 +33,7 @@ # # # BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # # # -# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # # All rights reserved. # # # # Redistribution and use in source and binary forms, with or without # @@ -72,14 +72,13 @@ #include #include #include -#include #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" -// custom user modules +// put custom code modules here! -#include "./custom_modules/heterogeneity.h" +#include "./custom_modules/custom.h" using namespace BioFVM; using namespace PhysiCell; @@ -105,31 +104,29 @@ int main( int argc, char* argv[] ) // copy config file to output directry system( copy_command ); - + // OpenMP setup omp_set_num_threads(PhysiCell_settings.omp_num_threads); - // PNRG setup - SeedRandom(); - // time setup std::string time_units = "min"; /* Microenvironment setup */ - setup_microenvironment(); - + setup_microenvironment(); // modify this in the custom code + /* PhysiCell setup */ // set mechanics voxel size, and match the data structure to BioFVM double mechanics_voxel_size = 30; Cell_Container* cell_container = create_cell_container_for_microenvironment( microenvironment, mechanics_voxel_size ); - create_cell_types(); - setup_tissue(); - /* Users typically start modifying here. START USERMODS */ + create_cell_types(); + + setup_tissue(); + /* Users typically stop modifying here. END USERMODS */ // set MultiCellDS save options @@ -152,13 +149,13 @@ int main( int argc, char* argv[] ) // for simplicity, set a pathology coloring function - std::vector (*cell_coloring_function)(Cell*) = heterogeneity_coloring_function; + std::vector (*cell_coloring_function)(Cell*) = heterogeneity_coloring_function; sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); - create_plot_legend( filename , cell_coloring_function ); + create_plot_legend( filename , cell_coloring_function ); display_citations(); @@ -179,7 +176,7 @@ int main( int argc, char* argv[] ) // main loop try - { + { while( PhysiCell_globals.current_time < PhysiCell_settings.max_time + 0.1*diffusion_dt ) { // save data if it's time. @@ -214,13 +211,17 @@ int main( int argc, char* argv[] ) PhysiCell_globals.next_SVG_save_time += PhysiCell_settings.SVG_save_interval; } } - + // update the microenvironment microenvironment.simulate_diffusion_decay( diffusion_dt ); // run PhysiCell ((Cell_Container *)microenvironment.agent_container)->update_all_cells( PhysiCell_globals.current_time ); + /* + Custom add-ons could potentially go here. + */ + PhysiCell_globals.current_time += diffusion_dt; } diff --git a/sample_projects/heterogeneity/scripts/histogram_script.m b/sample_projects/heterogeneity/scripts/histogram_script.m deleted file mode 100644 index e0bdea0b8..000000000 --- a/sample_projects/heterogeneity/scripts/histogram_script.m +++ /dev/null @@ -1,101 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% If you use PhysiCell in your project, please cite PhysiCell and the version % -% number, such as below: % -% % -% We implemented and solved the model using PhysiCell (Version x.y.z) [1]. % -% % -% [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, % -% PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- % -% lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 % -% DOI: 10.1371/journal.pcbi.1005991 % -% % -% See VERSION.txt or call get_PhysiCell_version() to get the current version % -% x.y.z. Call display_citations() to get detailed information on all cite-% -% able software used in your PhysiCell application. % -% % -% Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM % -% as below: % -% % -% We implemented and solved the model using PhysiCell (Version x.y.z) [1], % -% with BioFVM [2] to solve the transport equations. % -% % -% [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, % -% PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- % -% lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 % -% DOI: 10.1371/journal.pcbi.1005991 % -% % -% [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- % -% llelized diffusive transport solver for 3-D biological simulations, % -% Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) % -% % -% Copyright (c) 2015-2018, Paul Macklin and the PhysiCell Project % -% All rights reserved. % -% % -% Redistribution and use in source and binary forms, with or without % -% modification, are permitted provided that the following conditions are met: % -% % -% 1. Redistributions of source code must retain the above copyright notice, % -% this list of conditions and the following disclaimer. % -% % -% 2. Redistributions in binary form must reproduce the above copyright % -% notice, this list of conditions and the following disclaimer in the % -% documentation and/or other materials provided with the distribution. % -% % -% 3. Neither the name of the copyright holder nor the names of its % -% contributors may be used to endorse or promote products derived from this % -% software without specific prior written permission. % -% % -% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" % -% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE % -% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE % -% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE % -% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR % -% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF % -% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS % -% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN % -% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % -% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % -% POSSIBILITY OF SUCH DAMAGE. % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -bin_thickness = 0.1; -bin_centers = 0.5*bin_thickness : bin_thickness : 2.0 - 0.5*bin_thickness; -bin_edges = 0:bin_thickness:2; - -for i=0:216:1080 - filename = sprintf('output%08i.xml', i ); - MCDS = read_MultiCellDS_xml( filename ); - - ind = MCDS.discrete_cells.live_cells; - - m = mean( MCDS.discrete_cells.custom.oncoprotein(ind)); - s = std( MCDS.discrete_cells.custom.oncoprotein(ind)); - - h = histogram( MCDS.discrete_cells.custom.oncoprotein(ind) , bin_edges ); - h.Normalization = 'probability'; - axis([0 2 0 0.5]); - axis square; - - text( .2 , .45 , sprintf('mean: %3.4f\ns.d.: %3.4f', m,s),'fontsize', 16 ) - - - xlabel('oncoprotein value', 'fontsize', 14 ); - ylabel('probability' ,'fontsize', 14 ); - str = sprintf( 'Oncoprotein distribution at %i days', i/24.0 ); - title( str ,'fontsize', 16); - - filename = sprintf( 'hist%08i.png' , i ); - print( '-dpng' , filename ); - filename = sprintf( 'hist%08i.eps' , i ); - print( '-deps' , filename ); -% filename = sprintf( 'hist%08i.pdf' , i ); -% print( '-dpdf' , filename ); - filename = sprintf( 'hist%08i.svg', i ); - print( '-dsvg' , filename ); - -end \ No newline at end of file diff --git a/sample_projects/interactions/Makefile b/sample_projects/interactions/Makefile index 602d17216..c50ae5386 100644 --- a/sample_projects/interactions/Makefile +++ b/sample_projects/interactions/Makefile @@ -263,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/interactions/config/PhysiCell_settings-with-substrate-in-SVG.xml b/sample_projects/interactions/config/PhysiCell_settings-with-substrate-in-SVG.xml new file mode 100644 index 000000000..0e218aadc --- /dev/null +++ b/sample_projects/interactions/config/PhysiCell_settings-with-substrate-in-SVG.xml @@ -0,0 +1,1542 @@ + + + -400 + 400 + -400 + 400 + -10 + 10 + 20 + 20 + 20 + true + + + + 10080 + min + micron + + 0.01 + 0.1 + 6 + + + + 6 + + + + output + + + 180 + true + + + + 30 + true + + toxin + 0.0 + 0.1 + + + + + false + + + + + false + true + false + false + + + + + + 100000.0 + 0.1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + + + + 100 + 0.1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 1000 + 0.1 + + 0.0 + 0.0 + + + + + + + + + + + + 1000 + 0.01 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 1000 + 0.1 + + 0.0 + 0.0 + + + + + + + + + + + true + true + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.00028 + + + + + + 0.00028 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 500 + 0.75 + 499 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.04 + 20.0 + 1.25 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + + 1.8 + 15.12 + + + + + 1 + 5 + 0.2 + + true + true + + false + resource + 1 + + + + true + false + + 1 + 0 + 0.1 + 0 + 0 + + + + + + + + + 0 + 1 + 30 + 0 + + + 0.0 + 0.0 + 0.0 + 100 + + + 0 + 0.0 + 0.0 + 1 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0.15 + 0.075 + 0.15 + 0.25 + 0.5 + 0.0 + 0.0 + 0.0 + 0.0 + 36 + 100 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + + 0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + 1.8 + 15.12 + + + + + 1 + 1 + .5 + + false + true + + false + debris + 1 + + + + false + false + + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1000 + 1 + 0 + 0 + + + 0.0 + 0.0 + 0 + 0.0 + + + 0.0 + 0.0 + 0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0.15 + 0.075 + 0.15 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + + 0.002 + + + + + + 5.3e-08 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + 1.8 + 15.12 + + + + + 1 + 1 + .5 + + false + true + + false + debris + 1 + + + + false + false + + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 1 + 1 + 0 + + + 0.0 + 0.0 + 0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + 0.0001 + 0 + 0 + 0 + + + + + + 0.15 + 0.075 + 0.15 + 0.0 + 0.0 + 0.4 + 100 + 0.1 + 0.1 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + + 5.3e-4 + + + + + + 5.3e-05 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + 1.8 + 15.12 + + + + + 1 + 1 + .5 + + false + true + + false + debris + 1 + + + + false + false + + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 1 + 10 + 0 + + + 0.0 + 0.0 + 0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0.15 + 0.075 + 0.15 + 0.0 + 0.0 + 0.2 + 100 + 0.0 + 0.0 + 0.0 + 0.0 + 0.5 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + + 0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 3000 + 0.75 + 600 + 0.05 + 0.045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.04 + 10.0 + 1.25 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + 1.8 + 15.12 + + + + + 1 + 5 + 0.1 + + true + true + + false + debris + 1 + + + + true + false + + 0 + 0 + 1 + 0 + 0.1 + + + + + + + + + 0 + 1 + 5 + 0 + + + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 1.0 + 0 + 0.0 + + + 0.0 + 0.0 + 5 + 0.0 + + + + 0.05 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0.15 + 0.075 + 0.15 + 0.05 + 0.01 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.005 + 0.1 + 1 + 0 + + + + + + + + 0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 3000 + 0.75 + 600 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.04 + 10.0 + 1.25 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + 1.8 + 15.12 + + + + + 1 + 5 + 0.1 + + true + true + + true + pro-inflammatory + 1 + + + + false + false + + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 1 + 5 + 0 + + + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 0.0 + 1 + 0.0 + + + 0.0 + 0.0 + 0 + 0.0 + + + + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 10 + 0 + 0 + 0 + 0 + 0 + 0 + + 1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0.15 + 0.075 + 0.15 + 0.0 + 0.5 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + + 0 + + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + + 1000 + 0.75 + 200 + 0.05 + 0.045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.04 + 10.0 + 1.25 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + 1.8 + 15.12 + + + + + 1 + 5 + 0.1 + + true + true + + true + pro-inflammatory + 1 + + + + false + false + + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 1 + 5 + 0 + + + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 0.0 + 0.0 + 0 + + + 0.0 + 0.0 + 1 + 0.0 + + + 0.0 + 0.0 + 0 + 0.0 + + + + 0 + + 0.05 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 1 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0.15 + 0.075 + 0.15 + 0.0 + 0.5 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + + + + cells.csv + + + + + 0 + 50 + 400 + 40 + 20 + 50 + 50 + 50 + 0.0075 + + + diff --git a/sample_projects/interactions/config/PhysiCell_settings.xml b/sample_projects/interactions/config/PhysiCell_settings.xml index 68404dc82..695a86733 100644 --- a/sample_projects/interactions/config/PhysiCell_settings.xml +++ b/sample_projects/interactions/config/PhysiCell_settings.xml @@ -48,6 +48,7 @@ false true false + false @@ -176,10 +177,10 @@ 86400 - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 @@ -372,10 +373,10 @@ 86400 - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 @@ -567,10 +568,10 @@ 86400 - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 @@ -762,10 +763,10 @@ 86400 - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 @@ -957,10 +958,10 @@ 86400 - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 @@ -1152,10 +1153,10 @@ 86400 - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 @@ -1347,10 +1348,10 @@ 86400 - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 diff --git a/sample_projects/interactions/custom_modules/custom.cpp b/sample_projects/interactions/custom_modules/custom.cpp index a141e9226..9481d3b83 100644 --- a/sample_projects/interactions/custom_modules/custom.cpp +++ b/sample_projects/interactions/custom_modules/custom.cpp @@ -342,6 +342,12 @@ std::vector my_coloring_function( Cell* pCell ) } +std::vector my_coloring_function_for_substrate( double concentration, double max_conc, double min_conc ) +{ + return paint_by_density_percentage( concentration, max_conc, min_conc); + +} + void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) { return; } diff --git a/sample_projects/interactions/custom_modules/custom.h b/sample_projects/interactions/custom_modules/custom.h index 7b6616bc3..0bb5ff9a7 100644 --- a/sample_projects/interactions/custom_modules/custom.h +++ b/sample_projects/interactions/custom_modules/custom.h @@ -83,6 +83,8 @@ void setup_microenvironment( void ); std::vector my_coloring_function( Cell* ); +std::vector my_coloring_function_for_substrate( double concentration, double max_conc, double min_conc ); + // custom functions can go here void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); diff --git a/sample_projects/interactions/main.cpp b/sample_projects/interactions/main.cpp index 100fdcb7c..665160186 100644 --- a/sample_projects/interactions/main.cpp +++ b/sample_projects/interactions/main.cpp @@ -150,9 +150,12 @@ int main( int argc, char* argv[] ) // for simplicity, set a pathology coloring function std::vector (*cell_coloring_function)(Cell*) = my_coloring_function; + + std::vector (*substrate_coloring_function)(double, double, double) = my_coloring_function_for_substrate; sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); - SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, substrate_coloring_function ); sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); create_plot_legend( filename , cell_coloring_function ); @@ -205,7 +208,7 @@ int main( int argc, char* argv[] ) if( PhysiCell_settings.enable_SVG_saves == true ) { sprintf( filename , "%s/snapshot%08u.svg" , PhysiCell_settings.folder.c_str() , PhysiCell_globals.SVG_output_index ); - SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, substrate_coloring_function ); PhysiCell_globals.SVG_output_index++; PhysiCell_globals.next_SVG_save_time += PhysiCell_settings.SVG_save_interval; @@ -242,7 +245,7 @@ int main( int argc, char* argv[] ) save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); sprintf( filename , "%s/final.svg" , PhysiCell_settings.folder.c_str() ); - SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, substrate_coloring_function ); // timer diff --git a/sample_projects/mechano/Makefile b/sample_projects/mechano/Makefile new file mode 100644 index 000000000..1381dd805 --- /dev/null +++ b/sample_projects/mechano/Makefile @@ -0,0 +1,288 @@ +VERSION := $(shell grep . VERSION.txt | cut -f1 -d:) +PROGRAM_NAME := project + +CC := g++ +# CC := g++-mp-7 # typical macports compiler name +# CC := g++-7 # typical homebrew compiler name + +# Check for environment definitions of compiler +# e.g., on CC = g++-7 on OSX +ifdef PHYSICELL_CPP + CC := $(PHYSICELL_CPP) +endif + +ARCH := native # best auto-tuning +# ARCH := core2 # a reasonably safe default for most CPUs since 2007 +# ARCH := corei7 +# ARCH := corei7-avx # earlier i7 +# ARCH := core-avx-i # i7 ivy bridge or newer +# ARCH := core-avx2 # i7 with Haswell or newer +# ARCH := nehalem +# ARCH := westmere +# ARCH := sandybridge # circa 2011 +# ARCH := ivybridge # circa 2012 +# ARCH := haswell # circa 2013 +# ARCH := broadwell # circa 2014 +# ARCH := skylake # circa 2015 +# ARCH := bonnell +# ARCH := silvermont +# ARCH := skylake-avx512 +# ARCH := nocona #64-bit pentium 4 or later + +# CFLAGS := -march=$(ARCH) -Ofast -s -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 +CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 + +ifeq ($(OS),Windows_NT) +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Darwin) + UNAME_P := $(shell uname -p) + var := $(shell which $(CC) | xargs file) + ifeq ($(lastword $(var)),arm64) + CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -fopenmp -m64 -std=c++11 + endif + endif +endif + +COMPILE_COMMAND := $(CC) $(CFLAGS) + +BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o + +PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ +PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ +PhysiCell_signal_behavior.o + +PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o \ +PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o + +# put your custom objects here (they should be in the custom_modules directory) + +PhysiCell_custom_module_OBJECTS := custom.o + +pugixml_OBJECTS := pugixml.o + +PhysiCell_OBJECTS := $(BioFVM_OBJECTS) $(pugixml_OBJECTS) $(PhysiCell_core_OBJECTS) $(PhysiCell_module_OBJECTS) +ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiCell_custom_module_OBJECTS) + +# compile the project + +all: main.cpp $(ALL_OBJECTS) + $(COMPILE_COMMAND) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp + make name + +name: + @echo "" + @echo "Executable name is" $(PROGRAM_NAME) + @echo "" + +# PhysiCell core components + +PhysiCell_phenotype.o: ./core/PhysiCell_phenotype.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_phenotype.cpp + +PhysiCell_digital_cell_line.o: ./core/PhysiCell_digital_cell_line.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_digital_cell_line.cpp + +PhysiCell_cell.o: ./core/PhysiCell_cell.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell.cpp + +PhysiCell_cell_container.o: ./core/PhysiCell_cell_container.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell_container.cpp + +PhysiCell_standard_models.o: ./core/PhysiCell_standard_models.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_standard_models.cpp + +PhysiCell_utilities.o: ./core/PhysiCell_utilities.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_utilities.cpp + +PhysiCell_custom.o: ./core/PhysiCell_custom.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_custom.cpp + +PhysiCell_constants.o: ./core/PhysiCell_constants.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_constants.cpp + +PhysiCell_signal_behavior.o: ./core/PhysiCell_signal_behavior.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_signal_behavior.cpp + +# BioFVM core components (needed by PhysiCell) + +BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_vector.cpp + +BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp + +BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp + +BioFVM_microenvironment.o: ./BioFVM/BioFVM_microenvironment.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_microenvironment.cpp + +BioFVM_solvers.o: ./BioFVM/BioFVM_solvers.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_solvers.cpp + +BioFVM_utilities.o: ./BioFVM/BioFVM_utilities.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_utilities.cpp + +BioFVM_basic_agent.o: ./BioFVM/BioFVM_basic_agent.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent.cpp + +BioFVM_matlab.o: ./BioFVM/BioFVM_matlab.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_matlab.cpp + +BioFVM_MultiCellDS.o: ./BioFVM/BioFVM_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_MultiCellDS.cpp + +pugixml.o: ./BioFVM/pugixml.cpp + $(COMPILE_COMMAND) -c ./BioFVM/pugixml.cpp + +# standard PhysiCell modules + +PhysiCell_SVG.o: ./modules/PhysiCell_SVG.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_SVG.cpp + +PhysiCell_pathology.o: ./modules/PhysiCell_pathology.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pathology.cpp + +PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_MultiCellDS.cpp + +PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp + +PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp + +PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + +PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + +PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp + +# user-defined PhysiCell modules + +custom.o: ./custom_modules/custom.cpp + $(COMPILE_COMMAND) -c ./custom_modules/custom.cpp + +# cleanup + +reset: + rm -f *.cpp + cp ./sample_projects/Makefile-default Makefile + rm -f ./custom_modules/* + touch ./custom_modules/empty.txt + touch ALL_CITATIONS.txt + touch ./core/PhysiCell_cell.cpp + rm ALL_CITATIONS.txt + cp ./config/PhysiCell_settings-backup.xml ./config/PhysiCell_settings.xml + touch ./config/empty.csv + rm -f ./config/*.csv + +clean: + rm -f *.o + rm -f $(PROGRAM_NAME)* + +data-cleanup: + rm -rf ./output + mkdir ./output + touch ./output/empty.txt + +# archival + +checkpoint: + zip -r $$(date +%b_%d_%Y_%H%M).zip Makefile *.cpp *.h config/*.xml custom_modules/* + +zip: + zip -r latest.zip Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.zip $$(date +%b_%d_%Y_%H%M).zip + cp latest.zip VERSION_$(VERSION).zip + mv *.zip archives/ + +tar: + tar --ignore-failed-read -czf latest.tar Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.tar $$(date +%b_%d_%Y_%H%M).tar + cp latest.tar VERSION_$(VERSION).tar + mv *.tar archives/ + +unzip: + cp ./archives/latest.zip . + unzip latest.zip + +untar: + cp ./archives/latest.tar . + tar -xzf latest.tar + +# easier animation + +FRAMERATE := 24 +OUTPUT := output + +jpeg: + @magick identify -format "%h" $(OUTPUT)/initial.svg > __H.txt + @magick identify -format "%w" $(OUTPUT)/initial.svg > __W.txt + @expr 2 \* \( $$(grep . __H.txt) / 2 \) > __H1.txt + @expr 2 \* \( $$(grep . __W.txt) / 2 \) > __W1.txt + @echo "$$(grep . __W1.txt)!x$$(grep . __H1.txt)!" > __resize.txt + @magick mogrify -format jpg -resize $$(grep . __resize.txt) $(OUTPUT)/s*.svg + rm -f __H*.txt __W*.txt __resize.txt + +gif: + magick convert $(OUTPUT)/s*.svg $(OUTPUT)/out.gif + +movie: + ffmpeg -r $(FRAMERATE) -f image2 -i $(OUTPUT)/snapshot%08d.jpg -vcodec libx264 -pix_fmt yuv420p -strict -2 -tune animation -crf 15 -acodec none $(OUTPUT)/out.mp4 + +# upgrade rules + +SOURCE := PhysiCell_upgrade.zip +get-upgrade: + @echo $$(curl https://raw.githubusercontent.com/MathCancer/PhysiCell/master/VERSION.txt) > VER.txt + @echo https://github.com/MathCancer/PhysiCell/releases/download/$$(grep . VER.txt)/PhysiCell_V.$$(grep . VER.txt).zip > DL_FILE.txt + rm -f VER.txt + $$(curl -L $$(grep . DL_FILE.txt) --output PhysiCell_upgrade.zip) + rm -f DL_FILE.txt + +PhysiCell_upgrade.zip: + make get-upgrade + +upgrade: $(SOURCE) + unzip $(SOURCE) PhysiCell/VERSION.txt + mv -f PhysiCell/VERSION.txt . + unzip $(SOURCE) PhysiCell/core/* + cp -r PhysiCell/core/* core + unzip $(SOURCE) PhysiCell/modules/* + cp -r PhysiCell/modules/* modules + unzip $(SOURCE) PhysiCell/sample_projects/* + cp -r PhysiCell/sample_projects/* sample_projects + unzip $(SOURCE) PhysiCell/BioFVM/* + cp -r PhysiCell/BioFVM/* BioFVM + unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf + mv -f PhysiCell/documentation/User_Guide.pdf documentation + rm -f -r PhysiCell + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/mechano/config/PhysiCell_settings.xml b/sample_projects/mechano/config/PhysiCell_settings.xml new file mode 100644 index 000000000..f47469856 --- /dev/null +++ b/sample_projects/mechano/config/PhysiCell_settings.xml @@ -0,0 +1,343 @@ + + + + -500 + 500 + -500 + 500 + -10 + 10 + 20 + 20 + 20 + true + + + + 14400 + min + micron + 0.01 + 0.1 + 6 + + + + 6 + + + + output + + 60 + true + + + 60 + true + + + false + + + + + false + true + false + + + + + + 100000.0 + 10 + + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + true + true + + ./config/initial.mat + + + ./config/dirichlet.mat + + + + + + + + + + 0.00072 + + + + + 1e-5 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + 0 + 10.0 + 1.6 + + 1 + 1.0 + + + 1.5 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 1 + 1 + .5 + + false + true + + false + substrate + 1 + + + false + false + + 0.0 + + + + + + + 0 + 1 + 0 + 0 + + + + 0 + + 0 + 0.0 + 0 + + + 0 + 0.0 + 0 + + 1 + + 0 + 0.0 + 0 + + + + + 0 + 0.0 + 0 + + + + + 1.0 + + + + + + + 0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + 0 + 100.0 + 1.25 + + 1.0 + 1.0 + + + 1.5 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 1 + 1 + .5 + + false + true + + false + substrate + 1 + + + false + false + + 0.0 + + + + + + + 0 + 1 + 0 + 0 + + + + 0 + + 0.0 + 0.0 + + + 0.0 + 0.0 + + 1 + + 0.0 + 0.0 + + + + + 0.0 + 0.0 + + + + + 1.0 + + + + + + + config + cells.csv + + + + + 0 + 0 + + \ No newline at end of file diff --git a/sample_projects/mechano/config/cells-double-membrane.csv b/sample_projects/mechano/config/cells-double-membrane.csv new file mode 100644 index 000000000..642dc9e72 --- /dev/null +++ b/sample_projects/mechano/config/cells-double-membrane.csv @@ -0,0 +1,907 @@ +-6.539663123273226120e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,-1.854287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,-1.708575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,-1.562862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,-1.417150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,-1.271437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,-1.125725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.701592641099862817e+02,-9.800130531100876397e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.747618683561373132e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.785719746579405012e+02,-8.343006321258144453e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.831745789040915326e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.701592641099862817e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.869846852058947206e+02,-6.885882111415412510e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.915872894520457805e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.747618683561373132e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.785719746579405012e+02,-5.428757901572680566e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.831745789040915326e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.701592641099862817e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.869846852058947206e+02,-3.971633691729948623e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.915872894520457805e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.747618683561373132e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.785719746579405012e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.953973957538489401e+02,-2.514509481887216680e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.831745789040915326e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.701592641099862817e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.869846852058947206e+02,-1.057385272044484736e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.915872894520457805e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-1.747618683561373132e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +1.785719746579405012e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +1.953973957538489401e+02,3.997389377982472070e+00,0.000000000000000000e+00,0.000000000000000000e+00 +-1.831745789040915326e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.701592641099862817e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.869846852058947206e+02,1.856863147640979150e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.915872894520457805e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.747618683561373132e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.785719746579405012e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.953973957538489401e+02,3.313987357483711094e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.831745789040915326e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.701592641099862817e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.869846852058947206e+02,4.771111567326443037e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.747618683561373132e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.785719746579405012e+02,6.228235777169174980e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.831745789040915326e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.701592641099862817e+02,7.685359987011906924e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.747618683561373132e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.617465535620320622e+02,9.142484196854638867e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.663491578081830653e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.495237367122745979e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.533338430140778428e+02,1.059960840669737081e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.579364472602288458e+02,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.411110261643203785e+02,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.449211324661235665e+02,1.205673261654010275e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.326983156163661306e+02,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.158728945204576632e+02,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.196830008222608512e+02,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.365084219181693470e+02,1.351385682638283470e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.242856050684118969e+02,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.074601839725034296e+02,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.063476287659496222e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.444486917839820705e+01,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.112702902743066460e+02,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.280957113702150707e+02,1.497098103622556664e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.904747342454919590e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.222205232864072855e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.539663123273226120e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.238131643862701026e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.920673753453547761e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.603215863044397338e+01,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.028575797263524123e+02,1.642810524606829858e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.380934178068649487e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.698392068477803463e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.015849958886956728e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.333307849296109993e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.507657397052630799e+00,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.031776369885583655e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.714318479476430213e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.396860589067276948e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.079402698658123683e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.761944808248971128e+01,1.788522945591103053e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.857121013682379385e+01,1.934235366575376247e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.174578904091532650e+01,1.934235366575376247e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.492036794500685914e+01,1.934235366575376247e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.905053150901608205e+00,1.934235366575376247e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.873047424681007556e+01,1.934235366575376247e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.555589534271854291e+01,1.934235366575376247e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.415872894520457521e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,-2.400000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.500000000000000000e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.331745789040915042e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.163491578081830085e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.995237367122745127e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.826983156163660169e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.658728945204575211e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.490474734245490254e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.322220523286405296e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.153966312327320338e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.985712101368235381e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.817457890409150423e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.649203679450065465e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.480949468490980507e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.312695257531895550e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.144441046572810592e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.976186835613725634e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.807932624654640676e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.639678413695555719e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.471424202736470761e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.303169991777385803e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.134915780818300846e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.966661569859215888e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.798407358900130930e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.630153147941045972e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.461898936981961015e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.293644726022876057e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.125390515063791099e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-9.571363041047061415e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.888820931456211838e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-6.206278821865362261e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.523736712274512684e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.841194602683663106e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.158652493092813529e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.238896164980360481e+00,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.206431726088885625e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.888973835679735203e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.571515945270584780e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +7.254058054861434357e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.936600164452283934e+01,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.061914227404313351e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.230168438363398309e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.398422649322483267e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.566676860281568224e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.734931071240653182e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.903185282199738140e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.071439493158823097e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.239693704117908055e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.407947915076993013e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.576202126036077971e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.744456336995162928e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.912710547954247886e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.080964758913332844e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.249218969872417802e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.417473180831502759e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.585727391790587717e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.753981602749672675e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.922235813708757632e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.090490024667842590e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.258744235626927548e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.426998446586012506e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.595252657545097463e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.763506868504182421e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.931761079463267379e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.100015290422352336e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.268269501381437294e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.436523712340522252e+02,-2.254287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.415872894520457521e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,-2.108575158031453327e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.415872894520457521e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,2.200000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.500000000000000000e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.331745789040915042e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.163491578081830085e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.995237367122745127e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.826983156163660169e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.658728945204575211e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.490474734245490254e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.322220523286405296e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.153966312327320338e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.985712101368235381e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.817457890409150423e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.649203679450065465e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.480949468490980507e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.312695257531895550e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.144441046572810592e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.976186835613725634e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.807932624654640676e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.639678413695555719e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.471424202736470761e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.303169991777385803e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.134915780818300846e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.966661569859215888e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.798407358900130930e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.630153147941045972e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.461898936981961015e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.293644726022876057e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.125390515063791099e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-9.571363041047061415e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.888820931456211838e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-6.206278821865362261e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.523736712274512684e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.841194602683663106e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.158652493092813529e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.238896164980360481e+00,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.206431726088885625e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.888973835679735203e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.571515945270584780e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +7.254058054861434357e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.936600164452283934e+01,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.061914227404313351e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.230168438363398309e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.398422649322483267e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.566676860281568224e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.734931071240653182e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.903185282199738140e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.071439493158823097e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.239693704117908055e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.407947915076993013e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.576202126036077971e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.744456336995162928e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.912710547954247886e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.080964758913332844e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.249218969872417802e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.417473180831502759e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.585727391790587717e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.753981602749672675e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.922235813708757632e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.090490024667842590e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.258744235626927548e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.426998446586012506e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.595252657545097463e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.763506868504182421e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.931761079463267379e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.100015290422352336e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.268269501381437294e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.436523712340522252e+02,2.345712420984273194e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.415872894520457521e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,2.491424841968546673e+02,0.000000000000000000e+00,1.000000000000000000e+00 diff --git a/sample_projects/mechano/config/cells-shell.csv b/sample_projects/mechano/config/cells-shell.csv new file mode 100644 index 000000000..9154f5c09 --- /dev/null +++ b/sample_projects/mechano/config/cells-shell.csv @@ -0,0 +1,824 @@ +x,y,z,type,volume,cycle entry,custom:GFP,custom:sample +-65.39663123273226,-185.42875790157268,0.0,cancer +-48.571210136823794,-185.42875790157268,0.0,cancer +-31.745789040915326,-185.42875790157268,0.0,cancer +-14.92036794500686,-185.42875790157268,0.0,cancer +1.9050531509016082,-185.42875790157268,0.0,cancer +18.730474246810076,-185.42875790157268,0.0,cancer +35.55589534271854,-185.42875790157268,0.0,cancer +52.38131643862701,-185.42875790157268,0.0,cancer +69.20673753453548,-185.42875790157268,0.0,cancer +-90.63476287659496,-170.85751580314536,0.0,cancer +-73.8093417806865,-170.85751580314536,0.0,cancer +-56.983920684778035,-170.85751580314536,0.0,cancer +-40.15849958886957,-170.85751580314536,0.0,cancer +-23.3330784929611,-170.85751580314536,0.0,cancer +-6.507657397052631,-170.85751580314536,0.0,cancer +10.317763698855837,-170.85751580314536,0.0,cancer +27.143184794764302,-170.85751580314536,0.0,cancer +43.96860589067277,-170.85751580314536,0.0,cancer +60.79402698658124,-170.85751580314536,0.0,cancer +77.61944808248971,-170.85751580314536,0.0,cancer +94.4448691783982,-170.85751580314536,0.0,cancer +-115.87289452045766,-156.28627370471804,0.0,cancer +-99.0474734245492,-156.28627370471804,0.0,cancer +-82.22205232864073,-156.28627370471804,0.0,cancer +-65.39663123273226,-156.28627370471804,0.0,cancer +-48.571210136823794,-156.28627370471804,0.0,cancer +-31.745789040915326,-156.28627370471804,0.0,cancer +-14.92036794500686,-156.28627370471804,0.0,cancer +1.9050531509016082,-156.28627370471804,0.0,cancer +18.730474246810076,-156.28627370471804,0.0,cancer +35.55589534271854,-156.28627370471804,0.0,cancer +52.38131643862701,-156.28627370471804,0.0,cancer +69.20673753453548,-156.28627370471804,0.0,cancer +86.03215863044397,-156.28627370471804,0.0,cancer +102.85757972635241,-156.28627370471804,0.0,cancer +119.68300082226085,-156.28627370471804,0.0,cancer +-141.11102616432038,-141.71503160629072,0.0,cancer +-124.2856050684119,-141.71503160629072,0.0,cancer +-107.46018397250343,-141.71503160629072,0.0,cancer +-90.63476287659496,-141.71503160629072,0.0,cancer +-73.8093417806865,-141.71503160629072,0.0,cancer +-56.983920684778035,-141.71503160629072,0.0,cancer +-40.15849958886957,-141.71503160629072,0.0,cancer +-23.3330784929611,-141.71503160629072,0.0,cancer +-6.507657397052631,-141.71503160629072,0.0,cancer +10.317763698855837,-141.71503160629072,0.0,cancer +27.143184794764302,-141.71503160629072,0.0,cancer +43.96860589067277,-141.71503160629072,0.0,cancer +60.79402698658124,-141.71503160629072,0.0,cancer +77.61944808248971,-141.71503160629072,0.0,cancer +94.4448691783982,-141.71503160629072,0.0,cancer +111.27029027430665,-141.71503160629072,0.0,cancer +128.09571137021507,-141.71503160629072,0.0,cancer +-149.5237367122746,-127.1437895078634,0.0,cancer +-132.69831561636613,-127.1437895078634,0.0,cancer +-115.87289452045766,-127.1437895078634,0.0,cancer +-99.0474734245492,-127.1437895078634,0.0,cancer +-82.22205232864073,-127.1437895078634,0.0,cancer +-65.39663123273226,-127.1437895078634,0.0,cancer +-48.571210136823794,-127.1437895078634,0.0,cancer +-31.745789040915326,-127.1437895078634,0.0,cancer +-14.92036794500686,-127.1437895078634,0.0,cancer +1.9050531509016082,-127.1437895078634,0.0,cancer +18.730474246810076,-127.1437895078634,0.0,cancer +35.55589534271854,-127.1437895078634,0.0,cancer +52.38131643862701,-127.1437895078634,0.0,cancer +69.20673753453548,-127.1437895078634,0.0,cancer +86.03215863044397,-127.1437895078634,0.0,cancer +102.85757972635241,-127.1437895078634,0.0,cancer +119.68300082226085,-127.1437895078634,0.0,cancer +136.50842191816935,-127.1437895078634,0.0,cancer +153.33384301407784,-127.1437895078634,0.0,cancer +-157.93644726022885,-112.57254740943608,0.0,cancer +-141.11102616432038,-112.57254740943608,0.0,cancer +-124.2856050684119,-112.57254740943608,0.0,cancer +-107.46018397250343,-112.57254740943608,0.0,cancer +-90.63476287659496,-112.57254740943608,0.0,cancer +-73.8093417806865,-112.57254740943608,0.0,cancer +-56.983920684778035,-112.57254740943608,0.0,cancer +-40.15849958886957,-112.57254740943608,0.0,cancer +-23.3330784929611,-112.57254740943608,0.0,cancer +-6.507657397052631,-112.57254740943608,0.0,cancer +10.317763698855837,-112.57254740943608,0.0,cancer +27.143184794764302,-112.57254740943608,0.0,cancer +43.96860589067277,-112.57254740943608,0.0,cancer +60.79402698658124,-112.57254740943608,0.0,cancer +77.61944808248971,-112.57254740943608,0.0,cancer +94.4448691783982,-112.57254740943608,0.0,cancer +111.27029027430665,-112.57254740943608,0.0,cancer +128.09571137021507,-112.57254740943608,0.0,cancer +144.92113246612357,-112.57254740943608,0.0,cancer +161.74655356203206,-112.57254740943608,0.0,cancer +-166.34915780818307,-98.00130531100876,0.0,cancer +-149.5237367122746,-98.00130531100876,0.0,cancer +-132.69831561636613,-98.00130531100876,0.0,cancer +-115.87289452045766,-98.00130531100876,0.0,cancer +-99.0474734245492,-98.00130531100876,0.0,cancer +-82.22205232864073,-98.00130531100876,0.0,cancer +-65.39663123273226,-98.00130531100876,0.0,cancer +-48.571210136823794,-98.00130531100876,0.0,cancer +-31.745789040915326,-98.00130531100876,0.0,cancer +-14.92036794500686,-98.00130531100876,0.0,cancer +1.9050531509016082,-98.00130531100876,0.0,cancer +18.730474246810076,-98.00130531100876,0.0,cancer +35.55589534271854,-98.00130531100876,0.0,cancer +52.38131643862701,-98.00130531100876,0.0,cancer +69.20673753453548,-98.00130531100876,0.0,cancer +86.03215863044397,-98.00130531100876,0.0,cancer +102.85757972635241,-98.00130531100876,0.0,cancer +119.68300082226085,-98.00130531100876,0.0,cancer +136.50842191816935,-98.00130531100876,0.0,cancer +153.33384301407784,-98.00130531100876,0.0,cancer +170.15926410998628,-98.00130531100876,0.0,cancer +-174.7618683561373,-83.43006321258144,0.0,cancer +-157.93644726022885,-83.43006321258144,0.0,cancer +-141.11102616432038,-83.43006321258144,0.0,cancer +-124.2856050684119,-83.43006321258144,0.0,cancer +-107.46018397250343,-83.43006321258144,0.0,cancer +-90.63476287659496,-83.43006321258144,0.0,cancer +-73.8093417806865,-83.43006321258144,0.0,cancer +-56.983920684778035,-83.43006321258144,0.0,cancer +-40.15849958886957,-83.43006321258144,0.0,cancer +-23.3330784929611,-83.43006321258144,0.0,cancer +-6.507657397052631,-83.43006321258144,0.0,cancer +10.317763698855837,-83.43006321258144,0.0,cancer +27.143184794764302,-83.43006321258144,0.0,cancer +43.96860589067277,-83.43006321258144,0.0,cancer +60.79402698658124,-83.43006321258144,0.0,cancer +77.61944808248971,-83.43006321258144,0.0,cancer +94.4448691783982,-83.43006321258144,0.0,cancer +111.27029027430665,-83.43006321258144,0.0,cancer +128.09571137021507,-83.43006321258144,0.0,cancer +144.92113246612357,-83.43006321258144,0.0,cancer +161.74655356203206,-83.43006321258144,0.0,cancer +178.5719746579405,-83.43006321258144,0.0,cancer +-183.17457890409153,-68.85882111415413,0.0,cancer +-166.34915780818307,-68.85882111415413,0.0,cancer +-149.5237367122746,-68.85882111415413,0.0,cancer +-132.69831561636613,-68.85882111415413,0.0,cancer +-115.87289452045766,-68.85882111415413,0.0,cancer +-99.0474734245492,-68.85882111415413,0.0,cancer +-82.22205232864073,-68.85882111415413,0.0,cancer +-65.39663123273226,-68.85882111415413,0.0,cancer +-48.571210136823794,-68.85882111415413,0.0,cancer +-31.745789040915326,-68.85882111415413,0.0,cancer +-14.92036794500686,-68.85882111415413,0.0,cancer +1.9050531509016082,-68.85882111415413,0.0,cancer +18.730474246810076,-68.85882111415413,0.0,cancer +35.55589534271854,-68.85882111415413,0.0,cancer +52.38131643862701,-68.85882111415413,0.0,cancer +69.20673753453548,-68.85882111415413,0.0,cancer +86.03215863044397,-68.85882111415413,0.0,cancer +102.85757972635241,-68.85882111415413,0.0,cancer +119.68300082226085,-68.85882111415413,0.0,cancer +136.50842191816935,-68.85882111415413,0.0,cancer +153.33384301407784,-68.85882111415413,0.0,cancer +170.15926410998628,-68.85882111415413,0.0,cancer +186.98468520589472,-68.85882111415413,0.0,cancer +-191.58728945204578,-54.287579015726806,0.0,cancer +-174.7618683561373,-54.287579015726806,0.0,cancer +-157.93644726022885,-54.287579015726806,0.0,cancer +-141.11102616432038,-54.287579015726806,0.0,cancer +-124.2856050684119,-54.287579015726806,0.0,cancer +-107.46018397250343,-54.287579015726806,0.0,cancer +-90.63476287659496,-54.287579015726806,0.0,cancer +-73.8093417806865,-54.287579015726806,0.0,cancer +-56.983920684778035,-54.287579015726806,0.0,cancer +-40.15849958886957,-54.287579015726806,0.0,cancer +-23.3330784929611,-54.287579015726806,0.0,cancer +-6.507657397052631,-54.287579015726806,0.0,cancer +10.317763698855837,-54.287579015726806,0.0,cancer +27.143184794764302,-54.287579015726806,0.0,cancer +43.96860589067277,-54.287579015726806,0.0,cancer +60.79402698658124,-54.287579015726806,0.0,cancer +77.61944808248971,-54.287579015726806,0.0,cancer +94.4448691783982,-54.287579015726806,0.0,cancer +111.27029027430665,-54.287579015726806,0.0,cancer +128.09571137021507,-54.287579015726806,0.0,cancer +144.92113246612357,-54.287579015726806,0.0,cancer +161.74655356203206,-54.287579015726806,0.0,cancer +178.5719746579405,-54.287579015726806,0.0,cancer +-183.17457890409153,-39.716336917299486,0.0,cancer +-166.34915780818307,-39.716336917299486,0.0,cancer +-149.5237367122746,-39.716336917299486,0.0,cancer +-132.69831561636613,-39.716336917299486,0.0,cancer +-115.87289452045766,-39.716336917299486,0.0,cancer +-99.0474734245492,-39.716336917299486,0.0,cancer +-82.22205232864073,-39.716336917299486,0.0,cancer +-65.39663123273226,-39.716336917299486,0.0,cancer +-48.571210136823794,-39.716336917299486,0.0,cancer +-31.745789040915326,-39.716336917299486,0.0,cancer +-14.92036794500686,-39.716336917299486,0.0,cancer +1.9050531509016082,-39.716336917299486,0.0,cancer +18.730474246810076,-39.716336917299486,0.0,cancer +35.55589534271854,-39.716336917299486,0.0,cancer +52.38131643862701,-39.716336917299486,0.0,cancer +69.20673753453548,-39.716336917299486,0.0,cancer +86.03215863044397,-39.716336917299486,0.0,cancer +102.85757972635241,-39.716336917299486,0.0,cancer +119.68300082226085,-39.716336917299486,0.0,cancer +136.50842191816935,-39.716336917299486,0.0,cancer +153.33384301407784,-39.716336917299486,0.0,cancer +170.15926410998628,-39.716336917299486,0.0,cancer +186.98468520589472,-39.716336917299486,0.0,cancer +-191.58728945204578,-25.145094818872167,0.0,cancer +-174.7618683561373,-25.145094818872167,0.0,cancer +-157.93644726022885,-25.145094818872167,0.0,cancer +-141.11102616432038,-25.145094818872167,0.0,cancer +-124.2856050684119,-25.145094818872167,0.0,cancer +-107.46018397250343,-25.145094818872167,0.0,cancer +-90.63476287659496,-25.145094818872167,0.0,cancer +-73.8093417806865,-25.145094818872167,0.0,cancer +-56.983920684778035,-25.145094818872167,0.0,cancer +-40.15849958886957,-25.145094818872167,0.0,cancer +-23.3330784929611,-25.145094818872167,0.0,cancer +-6.507657397052631,-25.145094818872167,0.0,cancer +10.317763698855837,-25.145094818872167,0.0,cancer +27.143184794764302,-25.145094818872167,0.0,cancer +43.96860589067277,-25.145094818872167,0.0,cancer +60.79402698658124,-25.145094818872167,0.0,cancer +77.61944808248971,-25.145094818872167,0.0,cancer +94.4448691783982,-25.145094818872167,0.0,cancer +111.27029027430665,-25.145094818872167,0.0,cancer +128.09571137021507,-25.145094818872167,0.0,cancer +144.92113246612357,-25.145094818872167,0.0,cancer +161.74655356203206,-25.145094818872167,0.0,cancer +178.5719746579405,-25.145094818872167,0.0,cancer +195.39739575384894,-25.145094818872167,0.0,cancer +-183.17457890409153,-10.573852720444847,0.0,cancer +-166.34915780818307,-10.573852720444847,0.0,cancer +-149.5237367122746,-10.573852720444847,0.0,cancer +-132.69831561636613,-10.573852720444847,0.0,cancer +-115.87289452045766,-10.573852720444847,0.0,cancer +-99.0474734245492,-10.573852720444847,0.0,cancer +-82.22205232864073,-10.573852720444847,0.0,cancer +-65.39663123273226,-10.573852720444847,0.0,cancer +-48.571210136823794,-10.573852720444847,0.0,cancer +-31.745789040915326,-10.573852720444847,0.0,cancer +-14.92036794500686,-10.573852720444847,0.0,cancer +1.9050531509016082,-10.573852720444847,0.0,cancer +18.730474246810076,-10.573852720444847,0.0,cancer +35.55589534271854,-10.573852720444847,0.0,cancer +52.38131643862701,-10.573852720444847,0.0,cancer +69.20673753453548,-10.573852720444847,0.0,cancer +86.03215863044397,-10.573852720444847,0.0,cancer +102.85757972635241,-10.573852720444847,0.0,cancer +119.68300082226085,-10.573852720444847,0.0,cancer +136.50842191816935,-10.573852720444847,0.0,cancer +153.33384301407784,-10.573852720444847,0.0,cancer +170.15926410998628,-10.573852720444847,0.0,cancer +186.98468520589472,-10.573852720444847,0.0,cancer +-191.58728945204578,3.997389377982472,0.0,cancer +-174.7618683561373,3.997389377982472,0.0,cancer +-157.93644726022885,3.997389377982472,0.0,cancer +-141.11102616432038,3.997389377982472,0.0,cancer +-124.2856050684119,3.997389377982472,0.0,cancer +-107.46018397250343,3.997389377982472,0.0,cancer +-90.63476287659496,3.997389377982472,0.0,cancer +-73.8093417806865,3.997389377982472,0.0,cancer +-56.983920684778035,3.997389377982472,0.0,cancer +-40.15849958886957,3.997389377982472,0.0,cancer +-23.3330784929611,3.997389377982472,0.0,cancer +-6.507657397052631,3.997389377982472,0.0,cancer +10.317763698855837,3.997389377982472,0.0,cancer +27.143184794764302,3.997389377982472,0.0,cancer +43.96860589067277,3.997389377982472,0.0,cancer +60.79402698658124,3.997389377982472,0.0,cancer +77.61944808248971,3.997389377982472,0.0,cancer +94.4448691783982,3.997389377982472,0.0,cancer +111.27029027430665,3.997389377982472,0.0,cancer +128.09571137021507,3.997389377982472,0.0,cancer +144.92113246612357,3.997389377982472,0.0,cancer +161.74655356203206,3.997389377982472,0.0,cancer +178.5719746579405,3.997389377982472,0.0,cancer +195.39739575384894,3.997389377982472,0.0,cancer +-183.17457890409153,18.56863147640979,0.0,cancer +-166.34915780818307,18.56863147640979,0.0,cancer +-149.5237367122746,18.56863147640979,0.0,cancer +-132.69831561636613,18.56863147640979,0.0,cancer +-115.87289452045766,18.56863147640979,0.0,cancer +-99.0474734245492,18.56863147640979,0.0,cancer +-82.22205232864073,18.56863147640979,0.0,cancer +-65.39663123273226,18.56863147640979,0.0,cancer +-48.571210136823794,18.56863147640979,0.0,cancer +-31.745789040915326,18.56863147640979,0.0,cancer +-14.92036794500686,18.56863147640979,0.0,cancer +1.9050531509016082,18.56863147640979,0.0,cancer +18.730474246810076,18.56863147640979,0.0,cancer +35.55589534271854,18.56863147640979,0.0,cancer +52.38131643862701,18.56863147640979,0.0,cancer +69.20673753453548,18.56863147640979,0.0,cancer +86.03215863044397,18.56863147640979,0.0,cancer +102.85757972635241,18.56863147640979,0.0,cancer +119.68300082226085,18.56863147640979,0.0,cancer +136.50842191816935,18.56863147640979,0.0,cancer +153.33384301407784,18.56863147640979,0.0,cancer +170.15926410998628,18.56863147640979,0.0,cancer +186.98468520589472,18.56863147640979,0.0,cancer +-191.58728945204578,33.13987357483711,0.0,cancer +-174.7618683561373,33.13987357483711,0.0,cancer +-157.93644726022885,33.13987357483711,0.0,cancer +-141.11102616432038,33.13987357483711,0.0,cancer +-124.2856050684119,33.13987357483711,0.0,cancer +-107.46018397250343,33.13987357483711,0.0,cancer +-90.63476287659496,33.13987357483711,0.0,cancer +-73.8093417806865,33.13987357483711,0.0,cancer +-56.983920684778035,33.13987357483711,0.0,cancer +-40.15849958886957,33.13987357483711,0.0,cancer +-23.3330784929611,33.13987357483711,0.0,cancer +-6.507657397052631,33.13987357483711,0.0,cancer +10.317763698855837,33.13987357483711,0.0,cancer +27.143184794764302,33.13987357483711,0.0,cancer +43.96860589067277,33.13987357483711,0.0,cancer +60.79402698658124,33.13987357483711,0.0,cancer +77.61944808248971,33.13987357483711,0.0,cancer +94.4448691783982,33.13987357483711,0.0,cancer +111.27029027430665,33.13987357483711,0.0,cancer +128.09571137021507,33.13987357483711,0.0,cancer +144.92113246612357,33.13987357483711,0.0,cancer +161.74655356203206,33.13987357483711,0.0,cancer +178.5719746579405,33.13987357483711,0.0,cancer +195.39739575384894,33.13987357483711,0.0,cancer +-183.17457890409153,47.71111567326443,0.0,cancer +-166.34915780818307,47.71111567326443,0.0,cancer +-149.5237367122746,47.71111567326443,0.0,cancer +-132.69831561636613,47.71111567326443,0.0,cancer +-115.87289452045766,47.71111567326443,0.0,cancer +-99.0474734245492,47.71111567326443,0.0,cancer +-82.22205232864073,47.71111567326443,0.0,cancer +-65.39663123273226,47.71111567326443,0.0,cancer +-48.571210136823794,47.71111567326443,0.0,cancer +-31.745789040915326,47.71111567326443,0.0,cancer +-14.92036794500686,47.71111567326443,0.0,cancer +1.9050531509016082,47.71111567326443,0.0,cancer +18.730474246810076,47.71111567326443,0.0,cancer +35.55589534271854,47.71111567326443,0.0,cancer +52.38131643862701,47.71111567326443,0.0,cancer +69.20673753453548,47.71111567326443,0.0,cancer +86.03215863044397,47.71111567326443,0.0,cancer +102.85757972635241,47.71111567326443,0.0,cancer +119.68300082226085,47.71111567326443,0.0,cancer +136.50842191816935,47.71111567326443,0.0,cancer +153.33384301407784,47.71111567326443,0.0,cancer +170.15926410998628,47.71111567326443,0.0,cancer +186.98468520589472,47.71111567326443,0.0,cancer +-174.7618683561373,62.28235777169175,0.0,cancer +-157.93644726022885,62.28235777169175,0.0,cancer +-141.11102616432038,62.28235777169175,0.0,cancer +-124.2856050684119,62.28235777169175,0.0,cancer +-107.46018397250343,62.28235777169175,0.0,cancer +-90.63476287659496,62.28235777169175,0.0,cancer +-73.8093417806865,62.28235777169175,0.0,cancer +-56.983920684778035,62.28235777169175,0.0,cancer +-40.15849958886957,62.28235777169175,0.0,cancer +-23.3330784929611,62.28235777169175,0.0,cancer +-6.507657397052631,62.28235777169175,0.0,cancer +10.317763698855837,62.28235777169175,0.0,cancer +27.143184794764302,62.28235777169175,0.0,cancer +43.96860589067277,62.28235777169175,0.0,cancer +60.79402698658124,62.28235777169175,0.0,cancer +77.61944808248971,62.28235777169175,0.0,cancer +94.4448691783982,62.28235777169175,0.0,cancer +111.27029027430665,62.28235777169175,0.0,cancer +128.09571137021507,62.28235777169175,0.0,cancer +144.92113246612357,62.28235777169175,0.0,cancer +161.74655356203206,62.28235777169175,0.0,cancer +178.5719746579405,62.28235777169175,0.0,cancer +-183.17457890409153,76.85359987011907,0.0,cancer +-166.34915780818307,76.85359987011907,0.0,cancer +-149.5237367122746,76.85359987011907,0.0,cancer +-132.69831561636613,76.85359987011907,0.0,cancer +-115.87289452045766,76.85359987011907,0.0,cancer +-99.0474734245492,76.85359987011907,0.0,cancer +-82.22205232864073,76.85359987011907,0.0,cancer +-65.39663123273226,76.85359987011907,0.0,cancer +-48.571210136823794,76.85359987011907,0.0,cancer +-31.745789040915326,76.85359987011907,0.0,cancer +-14.92036794500686,76.85359987011907,0.0,cancer +1.9050531509016082,76.85359987011907,0.0,cancer +18.730474246810076,76.85359987011907,0.0,cancer +35.55589534271854,76.85359987011907,0.0,cancer +52.38131643862701,76.85359987011907,0.0,cancer +69.20673753453548,76.85359987011907,0.0,cancer +86.03215863044397,76.85359987011907,0.0,cancer +102.85757972635241,76.85359987011907,0.0,cancer +119.68300082226085,76.85359987011907,0.0,cancer +136.50842191816935,76.85359987011907,0.0,cancer +153.33384301407784,76.85359987011907,0.0,cancer +170.15926410998628,76.85359987011907,0.0,cancer +-174.7618683561373,91.42484196854639,0.0,cancer +-157.93644726022885,91.42484196854639,0.0,cancer +-141.11102616432038,91.42484196854639,0.0,cancer +-124.2856050684119,91.42484196854639,0.0,cancer +-107.46018397250343,91.42484196854639,0.0,cancer +-90.63476287659496,91.42484196854639,0.0,cancer +-73.8093417806865,91.42484196854639,0.0,cancer +-56.983920684778035,91.42484196854639,0.0,cancer +-40.15849958886957,91.42484196854639,0.0,cancer +-23.3330784929611,91.42484196854639,0.0,cancer +-6.507657397052631,91.42484196854639,0.0,cancer +10.317763698855837,91.42484196854639,0.0,cancer +27.143184794764302,91.42484196854639,0.0,cancer +43.96860589067277,91.42484196854639,0.0,cancer +60.79402698658124,91.42484196854639,0.0,cancer +77.61944808248971,91.42484196854639,0.0,cancer +94.4448691783982,91.42484196854639,0.0,cancer +111.27029027430665,91.42484196854639,0.0,cancer +128.09571137021507,91.42484196854639,0.0,cancer +144.92113246612357,91.42484196854639,0.0,cancer +161.74655356203206,91.42484196854639,0.0,cancer +-166.34915780818307,105.99608406697371,0.0,cancer +-149.5237367122746,105.99608406697371,0.0,cancer +-132.69831561636613,105.99608406697371,0.0,cancer +-115.87289452045766,105.99608406697371,0.0,cancer +-99.0474734245492,105.99608406697371,0.0,cancer +-82.22205232864073,105.99608406697371,0.0,cancer +-65.39663123273226,105.99608406697371,0.0,cancer +-48.571210136823794,105.99608406697371,0.0,cancer +-31.745789040915326,105.99608406697371,0.0,cancer +-14.92036794500686,105.99608406697371,0.0,cancer +1.9050531509016082,105.99608406697371,0.0,cancer +18.730474246810076,105.99608406697371,0.0,cancer +35.55589534271854,105.99608406697371,0.0,cancer +52.38131643862701,105.99608406697371,0.0,cancer +69.20673753453548,105.99608406697371,0.0,cancer +86.03215863044397,105.99608406697371,0.0,cancer +102.85757972635241,105.99608406697371,0.0,cancer +119.68300082226085,105.99608406697371,0.0,cancer +136.50842191816935,105.99608406697371,0.0,cancer +153.33384301407784,105.99608406697371,0.0,cancer +-157.93644726022885,120.56732616540103,0.0,cancer +-141.11102616432038,120.56732616540103,0.0,cancer +-124.2856050684119,120.56732616540103,0.0,cancer +-107.46018397250343,120.56732616540103,0.0,cancer +-90.63476287659496,120.56732616540103,0.0,cancer +-73.8093417806865,120.56732616540103,0.0,cancer +-56.983920684778035,120.56732616540103,0.0,cancer +-40.15849958886957,120.56732616540103,0.0,cancer +-23.3330784929611,120.56732616540103,0.0,cancer +-6.507657397052631,120.56732616540103,0.0,cancer +10.317763698855837,120.56732616540103,0.0,cancer +27.143184794764302,120.56732616540103,0.0,cancer +43.96860589067277,120.56732616540103,0.0,cancer +60.79402698658124,120.56732616540103,0.0,cancer +77.61944808248971,120.56732616540103,0.0,cancer +94.4448691783982,120.56732616540103,0.0,cancer +111.27029027430665,120.56732616540103,0.0,cancer +128.09571137021507,120.56732616540103,0.0,cancer +144.92113246612357,120.56732616540103,0.0,cancer +-132.69831561636613,135.13856826382835,0.0,cancer +-115.87289452045766,135.13856826382835,0.0,cancer +-99.0474734245492,135.13856826382835,0.0,cancer +-82.22205232864073,135.13856826382835,0.0,cancer +-65.39663123273226,135.13856826382835,0.0,cancer +-48.571210136823794,135.13856826382835,0.0,cancer +-31.745789040915326,135.13856826382835,0.0,cancer +-14.92036794500686,135.13856826382835,0.0,cancer +1.9050531509016082,135.13856826382835,0.0,cancer +18.730474246810076,135.13856826382835,0.0,cancer +35.55589534271854,135.13856826382835,0.0,cancer +52.38131643862701,135.13856826382835,0.0,cancer +69.20673753453548,135.13856826382835,0.0,cancer +86.03215863044397,135.13856826382835,0.0,cancer +102.85757972635241,135.13856826382835,0.0,cancer +119.68300082226085,135.13856826382835,0.0,cancer +136.50842191816935,135.13856826382835,0.0,cancer +-124.2856050684119,149.70981036225567,0.0,cancer +-107.46018397250343,149.70981036225567,0.0,cancer +-90.63476287659496,149.70981036225567,0.0,cancer +-73.8093417806865,149.70981036225567,0.0,cancer +-56.983920684778035,149.70981036225567,0.0,cancer +-40.15849958886957,149.70981036225567,0.0,cancer +-23.3330784929611,149.70981036225567,0.0,cancer +-6.507657397052631,149.70981036225567,0.0,cancer +10.317763698855837,149.70981036225567,0.0,cancer +27.143184794764302,149.70981036225567,0.0,cancer +43.96860589067277,149.70981036225567,0.0,cancer +60.79402698658124,149.70981036225567,0.0,cancer +77.61944808248971,149.70981036225567,0.0,cancer +94.4448691783982,149.70981036225567,0.0,cancer +111.27029027430665,149.70981036225567,0.0,cancer +128.09571137021507,149.70981036225567,0.0,cancer +-99.0474734245492,164.281052460683,0.0,cancer +-82.22205232864073,164.281052460683,0.0,cancer +-65.39663123273226,164.281052460683,0.0,cancer +-48.571210136823794,164.281052460683,0.0,cancer +-31.745789040915326,164.281052460683,0.0,cancer +-14.92036794500686,164.281052460683,0.0,cancer +1.9050531509016082,164.281052460683,0.0,cancer +18.730474246810076,164.281052460683,0.0,cancer +35.55589534271854,164.281052460683,0.0,cancer +52.38131643862701,164.281052460683,0.0,cancer +69.20673753453548,164.281052460683,0.0,cancer +86.03215863044397,164.281052460683,0.0,cancer +102.85757972635241,164.281052460683,0.0,cancer +-73.8093417806865,178.8522945591103,0.0,cancer +-56.983920684778035,178.8522945591103,0.0,cancer +-40.15849958886957,178.8522945591103,0.0,cancer +-23.3330784929611,178.8522945591103,0.0,cancer +-6.507657397052631,178.8522945591103,0.0,cancer +10.317763698855837,178.8522945591103,0.0,cancer +27.143184794764302,178.8522945591103,0.0,cancer +43.96860589067277,178.8522945591103,0.0,cancer +60.79402698658124,178.8522945591103,0.0,cancer +77.61944808248971,178.8522945591103,0.0,cancer +-48.571210136823794,193.42353665753762,0.0,cancer +-31.745789040915326,193.42353665753762,0.0,cancer +-14.92036794500686,193.42353665753762,0.0,cancer +1.9050531509016082,193.42353665753762,0.0,cancer +18.730474246810076,193.42353665753762,0.0,cancer +35.55589534271854,193.42353665753762,0.0,cancer +-94.44410465728185,-315.4287579015727,0.0,BM +-77.61868356137342,-315.4287579015727,0.0,BM +-60.79326246546498,-315.4287579015727,0.0,BM +-43.96784136955654,-315.4287579015727,0.0,BM +-27.1424202736481,-315.4287579015727,0.0,BM +-10.31699917773966,-315.4287579015727,0.0,BM +6.508421918168779,-315.4287579015727,0.0,BM +23.333843014077218,-315.4287579015727,0.0,BM +40.159264109985656,-315.4287579015727,0.0,BM +56.984685205894095,-315.4287579015727,0.0,BM +73.81010630180253,-315.4287579015727,0.0,BM +90.63552739771097,-315.4287579015727,0.0,BM +-119.6822363011445,-300.85751580314536,0.0,BM +-102.85681520523606,-300.85751580314536,0.0,BM +-86.03139410932762,-300.85751580314536,0.0,BM +-69.20597301341918,-300.85751580314536,0.0,BM +-52.38055191751075,-300.85751580314536,0.0,BM +-35.55513082160231,-300.85751580314536,0.0,BM +-18.729709725693873,-300.85751580314536,0.0,BM +-1.904288629785432,-300.85751580314536,0.0,BM +14.921132466123007,-300.85751580314536,0.0,BM +31.746553562031444,-300.85751580314536,0.0,BM +48.57197465793988,-300.85751580314536,0.0,BM +65.39739575384833,-300.85751580314536,0.0,BM +82.22281684975677,-300.85751580314536,0.0,BM +99.0482379456652,-300.85751580314536,0.0,BM +115.87365904157365,-300.85751580314536,0.0,BM +132.69908013748207,-300.85751580314536,0.0,BM +-161.7457890409156,-286.28627370471804,0.0,BM +-144.92036794500717,-286.28627370471804,0.0,BM +-128.09494684909873,-286.28627370471804,0.0,BM +-111.2695257531903,-286.28627370471804,0.0,BM +-94.44410465728185,-286.28627370471804,0.0,BM +-77.61868356137342,-286.28627370471804,0.0,BM +-60.79326246546498,-286.28627370471804,0.0,BM +56.984685205894095,-286.28627370471804,0.0,BM +73.81010630180253,-286.28627370471804,0.0,BM +90.63552739771097,-286.28627370471804,0.0,BM +107.46094849361941,-286.28627370471804,0.0,BM +124.28636958952785,-286.28627370471804,0.0,BM +141.1117906854363,-286.28627370471804,0.0,BM +157.93721178134473,-286.28627370471804,0.0,BM +-186.98392068477827,-271.7150316062907,0.0,BM +-170.15849958886983,-271.7150316062907,0.0,BM +-153.3330784929614,-271.7150316062907,0.0,BM +-136.50765739705295,-271.7150316062907,0.0,BM +-119.6822363011445,-271.7150316062907,0.0,BM +-102.85681520523606,-271.7150316062907,0.0,BM +115.87365904157365,-271.7150316062907,0.0,BM +132.69908013748207,-271.7150316062907,0.0,BM +149.5245012333905,-271.7150316062907,0.0,BM +166.34992232929895,-271.7150316062907,0.0,BM +183.1753434252074,-271.7150316062907,0.0,BM +-195.3966312327325,-257.1437895078634,0.0,BM +-178.57121013682405,-257.1437895078634,0.0,BM +-161.7457890409156,-257.1437895078634,0.0,BM +-144.92036794500717,-257.1437895078634,0.0,BM +141.1117906854363,-257.1437895078634,0.0,BM +157.93721178134473,-257.1437895078634,0.0,BM +174.76263287725317,-257.1437895078634,0.0,BM +191.58805397316155,-257.1437895078634,0.0,BM +-220.63476287659515,-242.57254740943608,0.0,BM +-203.8093417806867,-242.57254740943608,0.0,BM +-186.98392068477827,-242.57254740943608,0.0,BM +-170.15849958886983,-242.57254740943608,0.0,BM +166.34992232929895,-242.57254740943608,0.0,BM +183.1753434252074,-242.57254740943608,0.0,BM +200.00076452111577,-242.57254740943608,0.0,BM +216.82618561702427,-242.57254740943608,0.0,BM +-229.04747342454937,-228.00130531100876,0.0,BM +-212.22205232864093,-228.00130531100876,0.0,BM +-195.3966312327325,-228.00130531100876,0.0,BM +191.58805397316155,-228.00130531100876,0.0,BM +208.41347506907005,-228.00130531100876,0.0,BM +225.23889616497854,-228.00130531100876,0.0,BM +-237.4601839725036,-213.43006321258144,0.0,BM +-220.63476287659515,-213.43006321258144,0.0,BM +-203.8093417806867,-213.43006321258144,0.0,BM +200.00076452111577,-213.43006321258144,0.0,BM +216.82618561702427,-213.43006321258144,0.0,BM +233.65160671293276,-213.43006321258144,0.0,BM +250.47702780884114,-213.43006321258144,0.0,BM +-262.69831561636624,-198.85882111415413,0.0,BM +-245.8728945204578,-198.85882111415413,0.0,BM +-229.04747342454937,-198.85882111415413,0.0,BM +-212.22205232864093,-198.85882111415413,0.0,BM +225.23889616497854,-198.85882111415413,0.0,BM +242.06431726088692,-198.85882111415413,0.0,BM +258.8897383567953,-198.85882111415413,0.0,BM +-271.11102616432044,-184.2875790157268,0.0,BM +-254.28560506841202,-184.2875790157268,0.0,BM +-237.4601839725036,-184.2875790157268,0.0,BM +233.65160671293276,-184.2875790157268,0.0,BM +250.47702780884114,-184.2875790157268,0.0,BM +267.30244890474955,-184.2875790157268,0.0,BM +-279.5237367122747,-169.7163369172995,0.0,BM +-262.69831561636624,-169.7163369172995,0.0,BM +-245.8728945204578,-169.7163369172995,0.0,BM +242.06431726088692,-169.7163369172995,0.0,BM +258.8897383567953,-169.7163369172995,0.0,BM +275.7151594527038,-169.7163369172995,0.0,BM +-287.9364472602289,-155.14509481887217,0.0,BM +-271.11102616432044,-155.14509481887217,0.0,BM +-254.28560506841202,-155.14509481887217,0.0,BM +250.47702780884114,-155.14509481887217,0.0,BM +267.30244890474955,-155.14509481887217,0.0,BM +284.12787000065805,-155.14509481887217,0.0,BM +-296.3491578081831,-140.57385272044485,0.0,BM +-279.5237367122747,-140.57385272044485,0.0,BM +-262.69831561636624,-140.57385272044485,0.0,BM +258.8897383567953,-140.57385272044485,0.0,BM +275.7151594527038,-140.57385272044485,0.0,BM +292.5405805486123,-140.57385272044485,0.0,BM +-304.7618683561373,-126.00261062201753,0.0,BM +-287.9364472602289,-126.00261062201753,0.0,BM +-271.11102616432044,-126.00261062201753,0.0,BM +267.30244890474955,-126.00261062201753,0.0,BM +284.12787000065805,-126.00261062201753,0.0,BM +300.95329109656655,-126.00261062201753,0.0,BM +-296.3491578081831,-111.43136852359021,0.0,BM +-279.5237367122747,-111.43136852359021,0.0,BM +275.7151594527038,-111.43136852359021,0.0,BM +292.5405805486123,-111.43136852359021,0.0,BM +309.3660016445207,-111.43136852359021,0.0,BM +-304.7618683561373,-96.86012642516289,0.0,BM +-287.9364472602289,-96.86012642516289,0.0,BM +284.12787000065805,-96.86012642516289,0.0,BM +300.95329109656655,-96.86012642516289,0.0,BM +-313.17457890409156,-82.28888432673557,0.0,BM +-296.3491578081831,-82.28888432673557,0.0,BM +-279.5237367122747,-82.28888432673557,0.0,BM +292.5405805486123,-82.28888432673557,0.0,BM +309.3660016445207,-82.28888432673557,0.0,BM +-321.58728945204575,-67.71764222830825,0.0,BM +-304.7618683561373,-67.71764222830825,0.0,BM +-287.9364472602289,-67.71764222830825,0.0,BM +284.12787000065805,-67.71764222830825,0.0,BM +300.95329109656655,-67.71764222830825,0.0,BM +317.7787121924749,-67.71764222830825,0.0,BM +-313.17457890409156,-53.14640012988093,0.0,BM +-296.3491578081831,-53.14640012988093,0.0,BM +292.5405805486123,-53.14640012988093,0.0,BM +309.3660016445207,-53.14640012988093,0.0,BM +-321.58728945204575,-38.57515803145361,0.0,BM +-304.7618683561373,-38.57515803145361,0.0,BM +-287.9364472602289,-38.57515803145361,0.0,BM +300.95329109656655,-38.57515803145361,0.0,BM +317.7787121924749,-38.57515803145361,0.0,BM +-313.17457890409156,-24.003915933026292,0.0,BM +-296.3491578081831,-24.003915933026292,0.0,BM +292.5405805486123,-24.003915933026292,0.0,BM +309.3660016445207,-24.003915933026292,0.0,BM +326.19142274042906,-24.003915933026292,0.0,BM +-321.58728945204575,-9.432673834598972,0.0,BM +-304.7618683561373,-9.432673834598972,0.0,BM +300.95329109656655,-9.432673834598972,0.0,BM +317.7787121924749,-9.432673834598972,0.0,BM +-313.17457890409156,5.138568263828347,0.0,BM +-296.3491578081831,5.138568263828347,0.0,BM +292.5405805486123,5.138568263828347,0.0,BM +309.3660016445207,5.138568263828347,0.0,BM +326.19142274042906,5.138568263828347,0.0,BM +-321.58728945204575,19.709810362255666,0.0,BM +-304.7618683561373,19.709810362255666,0.0,BM +300.95329109656655,19.709810362255666,0.0,BM +317.7787121924749,19.709810362255666,0.0,BM +-313.17457890409156,34.281052460682986,0.0,BM +-296.3491578081831,34.281052460682986,0.0,BM +292.5405805486123,34.281052460682986,0.0,BM +309.3660016445207,34.281052460682986,0.0,BM +326.19142274042906,34.281052460682986,0.0,BM +-321.58728945204575,48.852294559110305,0.0,BM +-304.7618683561373,48.852294559110305,0.0,BM +-287.9364472602289,48.852294559110305,0.0,BM +300.95329109656655,48.852294559110305,0.0,BM +317.7787121924749,48.852294559110305,0.0,BM +-313.17457890409156,63.423536657537625,0.0,BM +-296.3491578081831,63.423536657537625,0.0,BM +292.5405805486123,63.423536657537625,0.0,BM +309.3660016445207,63.423536657537625,0.0,BM +-304.7618683561373,77.99477875596494,0.0,BM +-287.9364472602289,77.99477875596494,0.0,BM +284.12787000065805,77.99477875596494,0.0,BM +300.95329109656655,77.99477875596494,0.0,BM +317.7787121924749,77.99477875596494,0.0,BM +-313.17457890409156,92.56602085439226,0.0,BM +-296.3491578081831,92.56602085439226,0.0,BM +-279.5237367122747,92.56602085439226,0.0,BM +275.7151594527038,92.56602085439226,0.0,BM +292.5405805486123,92.56602085439226,0.0,BM +309.3660016445207,92.56602085439226,0.0,BM +-304.7618683561373,107.13726295281958,0.0,BM +-287.9364472602289,107.13726295281958,0.0,BM +-271.11102616432044,107.13726295281958,0.0,BM +284.12787000065805,107.13726295281958,0.0,BM +300.95329109656655,107.13726295281958,0.0,BM +-296.3491578081831,121.7085050512469,0.0,BM +-279.5237367122747,121.7085050512469,0.0,BM +275.7151594527038,121.7085050512469,0.0,BM +292.5405805486123,121.7085050512469,0.0,BM +-287.9364472602289,136.27974714967422,0.0,BM +-271.11102616432044,136.27974714967422,0.0,BM +267.30244890474955,136.27974714967422,0.0,BM +284.12787000065805,136.27974714967422,0.0,BM +-279.5237367122747,150.85098924810154,0.0,BM +-262.69831561636624,150.85098924810154,0.0,BM +258.8897383567953,150.85098924810154,0.0,BM +275.7151594527038,150.85098924810154,0.0,BM +292.5405805486123,150.85098924810154,0.0,BM +-271.11102616432044,165.42223134652886,0.0,BM +-254.28560506841202,165.42223134652886,0.0,BM +250.47702780884114,165.42223134652886,0.0,BM +267.30244890474955,165.42223134652886,0.0,BM +284.12787000065805,165.42223134652886,0.0,BM +-262.69831561636624,179.99347344495618,0.0,BM +-245.8728945204578,179.99347344495618,0.0,BM +-229.04747342454937,179.99347344495618,0.0,BM +242.06431726088692,179.99347344495618,0.0,BM +258.8897383567953,179.99347344495618,0.0,BM +275.7151594527038,179.99347344495618,0.0,BM +-254.28560506841202,194.5647155433835,0.0,BM +-237.4601839725036,194.5647155433835,0.0,BM +-220.63476287659515,194.5647155433835,0.0,BM +216.82618561702427,194.5647155433835,0.0,BM +233.65160671293276,194.5647155433835,0.0,BM +250.47702780884114,194.5647155433835,0.0,BM +-245.8728945204578,209.13595764181082,0.0,BM +-229.04747342454937,209.13595764181082,0.0,BM +-212.22205232864093,209.13595764181082,0.0,BM +208.41347506907005,209.13595764181082,0.0,BM +225.23889616497854,209.13595764181082,0.0,BM +242.06431726088692,209.13595764181082,0.0,BM +-237.4601839725036,223.70719974023814,0.0,BM +-220.63476287659515,223.70719974023814,0.0,BM +-203.8093417806867,223.70719974023814,0.0,BM +-186.98392068477827,223.70719974023814,0.0,BM +200.00076452111577,223.70719974023814,0.0,BM +216.82618561702427,223.70719974023814,0.0,BM +233.65160671293276,223.70719974023814,0.0,BM +-212.22205232864093,238.27844183866546,0.0,BM +-195.3966312327325,238.27844183866546,0.0,BM +-178.57121013682405,238.27844183866546,0.0,BM +174.76263287725317,238.27844183866546,0.0,BM +191.58805397316155,238.27844183866546,0.0,BM +208.41347506907005,238.27844183866546,0.0,BM +225.23889616497854,238.27844183866546,0.0,BM +-203.8093417806867,252.84968393709278,0.0,BM +-186.98392068477827,252.84968393709278,0.0,BM +-170.15849958886983,252.84968393709278,0.0,BM +-153.3330784929614,252.84968393709278,0.0,BM +149.5245012333905,252.84968393709278,0.0,BM +166.34992232929895,252.84968393709278,0.0,BM +183.1753434252074,252.84968393709278,0.0,BM +200.00076452111577,252.84968393709278,0.0,BM +-178.57121013682405,267.4209260355201,0.0,BM +-161.7457890409156,267.4209260355201,0.0,BM +-144.92036794500717,267.4209260355201,0.0,BM +-128.09494684909873,267.4209260355201,0.0,BM +124.28636958952785,267.4209260355201,0.0,BM +141.1117906854363,267.4209260355201,0.0,BM +157.93721178134473,267.4209260355201,0.0,BM +174.76263287725317,267.4209260355201,0.0,BM +191.58805397316155,267.4209260355201,0.0,BM +-170.15849958886983,281.9921681339474,0.0,BM +-153.3330784929614,281.9921681339474,0.0,BM +-136.50765739705295,281.9921681339474,0.0,BM +-119.6822363011445,281.9921681339474,0.0,BM +-102.85681520523606,281.9921681339474,0.0,BM +-86.03139410932762,281.9921681339474,0.0,BM +-69.20597301341918,281.9921681339474,0.0,BM +82.22281684975677,281.9921681339474,0.0,BM +99.0482379456652,281.9921681339474,0.0,BM +115.87365904157365,281.9921681339474,0.0,BM +132.69908013748207,281.9921681339474,0.0,BM +149.5245012333905,281.9921681339474,0.0,BM +166.34992232929895,281.9921681339474,0.0,BM +-128.09494684909873,296.56341023237474,0.0,BM +-111.2695257531903,296.56341023237474,0.0,BM +-94.44410465728185,296.56341023237474,0.0,BM +-77.61868356137342,296.56341023237474,0.0,BM +-60.79326246546498,296.56341023237474,0.0,BM +-43.96784136955654,296.56341023237474,0.0,BM +-27.1424202736481,296.56341023237474,0.0,BM +-10.31699917773966,296.56341023237474,0.0,BM +6.508421918168779,296.56341023237474,0.0,BM +23.333843014077218,296.56341023237474,0.0,BM +40.159264109985656,296.56341023237474,0.0,BM +56.984685205894095,296.56341023237474,0.0,BM +73.81010630180253,296.56341023237474,0.0,BM +90.63552739771097,296.56341023237474,0.0,BM +107.46094849361941,296.56341023237474,0.0,BM +124.28636958952785,296.56341023237474,0.0,BM +141.1117906854363,296.56341023237474,0.0,BM +-102.85681520523606,311.13465233080206,0.0,BM +-86.03139410932762,311.13465233080206,0.0,BM +-69.20597301341918,311.13465233080206,0.0,BM +-52.38055191751075,311.13465233080206,0.0,BM +-35.55513082160231,311.13465233080206,0.0,BM +-18.729709725693873,311.13465233080206,0.0,BM +-1.904288629785432,311.13465233080206,0.0,BM +14.921132466123007,311.13465233080206,0.0,BM +31.746553562031444,311.13465233080206,0.0,BM +48.57197465793988,311.13465233080206,0.0,BM +65.39739575384833,311.13465233080206,0.0,BM +82.22281684975677,311.13465233080206,0.0,BM +99.0482379456652,311.13465233080206,0.0,BM +-43.96784136955654,325.7058944292294,0.0,BM +-27.1424202736481,325.7058944292294,0.0,BM +-10.31699917773966,325.7058944292294,0.0,BM +6.508421918168779,325.7058944292294,0.0,BM +23.333843014077218,325.7058944292294,0.0,BM +40.159264109985656,325.7058944292294,0.0,BM diff --git a/sample_projects/mechano/config/cells-single-membrane.csv b/sample_projects/mechano/config/cells-single-membrane.csv new file mode 100644 index 000000000..795aa7325 --- /dev/null +++ b/sample_projects/mechano/config/cells-single-membrane.csv @@ -0,0 +1,548 @@ +-5.415872894520457521e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.500000000000000000e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.331745789040915042e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.163491578081830085e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.995237367122745127e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.826983156163660169e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.658728945204575211e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.490474734245490254e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.322220523286405296e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.153966312327320338e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.985712101368235381e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.817457890409150423e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.649203679450065465e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.480949468490980507e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.312695257531895550e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.144441046572810592e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.976186835613725634e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.807932624654640676e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.639678413695555719e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.471424202736470761e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.303169991777385803e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.134915780818300846e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.966661569859215888e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.798407358900130930e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.630153147941045972e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.461898936981961015e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.293644726022876057e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.125390515063791099e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-9.571363041047061415e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.888820931456211838e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-6.206278821865362261e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.523736712274512684e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.841194602683663106e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.158652493092813529e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.238896164980360481e+00,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.206431726088885625e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.888973835679735203e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.571515945270584780e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +7.254058054861434357e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.936600164452283934e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.061914227404313351e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.230168438363398309e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.398422649322483267e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.566676860281568224e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.734931071240653182e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.903185282199738140e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.071439493158823097e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.239693704117908055e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.407947915076993013e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.576202126036077971e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.744456336995162928e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.912710547954247886e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.080964758913332844e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.249218969872417802e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.417473180831502759e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.585727391790587717e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.753981602749672675e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.922235813708757632e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.090490024667842590e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.258744235626927548e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.426998446586012506e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.595252657545097463e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.763506868504182421e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.931761079463267379e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.100015290422352336e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.268269501381437294e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.436523712340522252e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.415872894520457521e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.500000000000000000e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.331745789040915042e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.163491578081830085e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.995237367122745127e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.826983156163660169e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.658728945204575211e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.490474734245490254e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.322220523286405296e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.153966312327320338e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.985712101368235381e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.817457890409150423e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.649203679450065465e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.480949468490980507e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.312695257531895550e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.144441046572810592e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.976186835613725634e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.807932624654640676e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.639678413695555719e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.471424202736470761e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.303169991777385803e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.134915780818300846e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.966661569859215888e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.798407358900130930e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.630153147941045972e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.461898936981961015e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.293644726022876057e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.125390515063791099e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-9.571363041047061415e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.888820931456211838e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-6.206278821865362261e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.523736712274512684e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.841194602683663106e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.158652493092813529e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.238896164980360481e+00,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.206431726088885625e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.888973835679735203e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.571515945270584780e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +7.254058054861434357e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.936600164452283934e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.061914227404313351e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.230168438363398309e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.398422649322483267e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.566676860281568224e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.734931071240653182e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.903185282199738140e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.071439493158823097e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.239693704117908055e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.407947915076993013e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.576202126036077971e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.744456336995162928e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.912710547954247886e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.080964758913332844e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.249218969872417802e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.417473180831502759e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.585727391790587717e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.753981602749672675e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.922235813708757632e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.090490024667842590e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.258744235626927548e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.426998446586012506e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.595252657545097463e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.763506868504182421e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.931761079463267379e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.100015290422352336e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.268269501381437294e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.436523712340522252e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.904747342454919590e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.415872894520457805e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.444448691783981928e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.415872894520457805e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.444448691783981928e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.415872894520457805e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.444448691783981928e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 diff --git a/sample_projects/mechano/config/cells.csv b/sample_projects/mechano/config/cells.csv new file mode 100644 index 000000000..795aa7325 --- /dev/null +++ b/sample_projects/mechano/config/cells.csv @@ -0,0 +1,548 @@ +-5.415872894520457521e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,-3.750000000000000000e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.500000000000000000e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.331745789040915042e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.163491578081830085e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.995237367122745127e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.826983156163660169e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.658728945204575211e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.490474734245490254e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.322220523286405296e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.153966312327320338e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.985712101368235381e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.817457890409150423e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.649203679450065465e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.480949468490980507e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.312695257531895550e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.144441046572810592e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.976186835613725634e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.807932624654640676e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.639678413695555719e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.471424202736470761e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.303169991777385803e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.134915780818300846e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.966661569859215888e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.798407358900130930e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.630153147941045972e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.461898936981961015e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.293644726022876057e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.125390515063791099e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-9.571363041047061415e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.888820931456211838e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-6.206278821865362261e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.523736712274512684e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.841194602683663106e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.158652493092813529e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.238896164980360481e+00,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.206431726088885625e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.888973835679735203e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.571515945270584780e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +7.254058054861434357e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.936600164452283934e+01,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.061914227404313351e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.230168438363398309e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.398422649322483267e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.566676860281568224e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.734931071240653182e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.903185282199738140e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.071439493158823097e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.239693704117908055e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.407947915076993013e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.576202126036077971e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.744456336995162928e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.912710547954247886e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.080964758913332844e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.249218969872417802e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.417473180831502759e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.585727391790587717e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.753981602749672675e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.922235813708757632e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.090490024667842590e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.258744235626927548e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.426998446586012506e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.595252657545097463e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.763506868504182421e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.931761079463267379e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.100015290422352336e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.268269501381437294e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.436523712340522252e+02,-3.604287579015726806e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.415872894520457521e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.247618683561372563e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.079364472602287606e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.911110261643202648e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.742856050684117690e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.574601839725032733e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.406347628765947775e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.238093417806862817e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.069839206847777859e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.901584995888692902e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.733330784929607944e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.565076573970522986e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.396822363011438028e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.228568152052353071e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.060313941093268113e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.892059730134183155e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.723805519175098198e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.555551308216013524e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.387297097256928566e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.219042886297843609e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.050788675338758651e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.882534464379673693e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.714280253420588735e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.546026042461503778e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.377771831502418820e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.209517620543333720e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.041263409584248762e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-8.730091986251638048e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.047549876660788470e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.365007767069939604e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.682465657479090027e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.999923547888240449e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.173814382973906945e+00,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.365160671293458883e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.047702780884308282e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.730244890475157860e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +6.412787000066008147e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.095329109656857725e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +9.777871219247707302e+01,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.146041332883855688e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.314295543842940504e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.482549754802025461e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.650803965761110419e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.819058176720195377e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.987312387679280334e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.155566598638365292e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.323820809597450250e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.492075020556535208e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.660329231515620449e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.828583442474705407e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.996837653433790365e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.165091864392875323e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.333346075351960280e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.501600286311045238e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.669854497270130196e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.838108708229215154e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.006362919188300111e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.174617130147385069e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.342871341106470027e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.511125552065554984e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.679379763024639942e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.847633973983724900e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.015888184942809858e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.184142395901894815e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.352396606860979773e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.520650817820064731e+02,-3.458575158031453611e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.500000000000000000e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.331745789040915042e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-5.163491578081830085e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.995237367122745127e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.826983156163660169e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.658728945204575211e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.490474734245490254e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.322220523286405296e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.153966312327320338e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.985712101368235381e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.817457890409150423e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.649203679450065465e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.480949468490980507e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.312695257531895550e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-3.144441046572810592e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.976186835613725634e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.807932624654640676e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.639678413695555719e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.471424202736470761e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.303169991777385803e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.134915780818300846e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.966661569859215888e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.798407358900130930e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.630153147941045972e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.461898936981961015e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.293644726022876057e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.125390515063791099e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-9.571363041047061415e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-7.888820931456211838e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-6.206278821865362261e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.523736712274512684e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-2.841194602683663106e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-1.158652493092813529e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.238896164980360481e+00,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.206431726088885625e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.888973835679735203e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.571515945270584780e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +7.254058054861434357e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +8.936600164452283934e+01,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.061914227404313351e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.230168438363398309e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.398422649322483267e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.566676860281568224e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.734931071240653182e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +1.903185282199738140e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.071439493158823097e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.239693704117908055e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.407947915076993013e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.576202126036077971e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.744456336995162928e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +2.912710547954247886e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.080964758913332844e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.249218969872417802e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.417473180831502759e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.585727391790587717e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.753981602749672675e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +3.922235813708757632e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.090490024667842590e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.258744235626927548e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.426998446586012506e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.595252657545097463e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.763506868504182421e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +4.931761079463267379e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.100015290422352336e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.268269501381437294e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +5.436523712340522252e+02,-3.312862737047179849e+02,0.000000000000000000e+00,1.000000000000000000e+00 +-4.904747342454919590e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-3.104287579015726806e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.958575158031453611e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-2.812862737047180417e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-2.667150316062907223e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-2.521437895078634028e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-2.375725474094360834e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-2.230013053110087640e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.415872894520457805e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.444448691783981928e+02,-2.084300632125814445e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-1.938588211141541251e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.415872894520457805e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.444448691783981928e+02,-1.792875790157268057e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-1.647163369172994862e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.415872894520457805e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.444448691783981928e+02,-1.501450948188721668e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.360321586304439734e+02,-1.355738527204448474e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.276194480824897113e+02,-1.210026106220175279e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.331745789040915326e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.163491578081830653e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +1.192067375345354776e+02,-1.064313685235902085e+02,0.000000000000000000e+00,0.000000000000000000e+00 +-1.247618683561372990e+02,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.079364472602288316e+02,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.107940269865812439e+02,-9.186012642516288906e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.952373671227459795e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-8.269831561636613060e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +8.555589534271854291e+01,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.023813164386270103e+02,-7.728888432673556963e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-9.111102616432036427e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-7.428560506841189692e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-5.746018397250343668e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.031776369885583478e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +7.714318479476430923e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.396860589067277658e+01,-6.271764222830825020e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.587289452045766325e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.904747342454919590e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-3.222205232864072855e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-1.539663123273226120e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.428789863176206154e+00,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +1.825421095908467350e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +3.507963205499314086e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +5.190505315090160821e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +6.873047424681007556e+01,-4.814640012988093076e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-4.063476287659496933e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-2.380934178068650198e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +-6.983920684778032850e+00,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +9.841500411130434500e+00,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +2.666692150703890007e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 +4.349234260294736742e+01,-3.357515803145361133e+01,0.000000000000000000e+00,0.000000000000000000e+00 diff --git a/sample_projects/mechano/custom_modules/custom.cpp b/sample_projects/mechano/custom_modules/custom.cpp new file mode 100644 index 000000000..712c5a935 --- /dev/null +++ b/sample_projects/mechano/custom_modules/custom.cpp @@ -0,0 +1,291 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include "./custom.h" + +void create_cell_types( void ) +{ + // set the random seed + SeedRandom( parameters.ints("random_seed") ); + + /* + Put any modifications to default cell definition here if you + want to have "inherited" by other cell types. + + This is a good place to set default functions. + */ + + initialize_default_cell_definition(); + cell_defaults.phenotype.secretion.sync_to_microenvironment( µenvironment ); + + cell_defaults.functions.volume_update_function = standard_volume_update_function; + cell_defaults.functions.update_velocity = standard_update_cell_velocity; + + cell_defaults.functions.update_migration_bias = NULL; + cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based; + cell_defaults.functions.custom_cell_rule = NULL; + cell_defaults.functions.contact_function = NULL; + + cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; + cell_defaults.functions.calculate_distance_to_membrane = NULL; + + /* + This parses the cell definitions in the XML config file. + */ + + initialize_cell_definitions_from_pugixml(); + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + build_cell_definitions_maps(); + + /* + This intializes cell signal and response dictionaries + */ + + setup_signal_behavior_dictionaries(); + + /* + Put any modifications to individual cell definitions here. + + This is a good place to set custom functions. + */ + + cell_defaults.functions.update_phenotype = phenotype_function; + cell_defaults.functions.custom_cell_rule = custom_function; + cell_defaults.functions.contact_function = contact_function; + +/* + Cell_Definition* pCD = find_cell_definition( "cancer"); + pCD->phenotype.mechanics.maximum_number_of_attachments = 6; + pCD->phenotype.mechanics.attachment_elastic_constant = 0.002; // 0.00142; // 0.1; // 0.00142; // 0.1; + pCD->phenotype.mechanics.attachment_rate = 1; + pCD->phenotype.mechanics.detachment_rate = 0.01; // 0.01 + pCD->functions.update_phenotype = cancer_phenotype_function; + + pCD = find_cell_definition( "BM"); + pCD->phenotype.mechanics.maximum_number_of_attachments = 6; + pCD->phenotype.mechanics.attachment_elastic_constant = 1; // 0.0142; // 100; // 0.0142 ; // 1; + pCD->phenotype.mechanics.attachment_rate = 1; + pCD->phenotype.mechanics.detachment_rate = 0; +*/ + + Cell_Definition* pCD = find_cell_definition( "cancer"); + pCD->phenotype.mechanics.maximum_number_of_attachments = 6; + pCD->phenotype.mechanics.attachment_elastic_constant = 0.00142; // 0.00142; // 0.1 for confluent version; // 0.002 + pCD->phenotype.mechanics.attachment_rate = 1; + pCD->phenotype.mechanics.detachment_rate = 0.01; // 0.01 + pCD->functions.update_phenotype = cancer_phenotype_function; + + pCD = find_cell_definition( "BM"); + pCD->phenotype.mechanics.maximum_number_of_attachments = 6; + pCD->phenotype.mechanics.attachment_elastic_constant = 0.05; // 0.0142; // 1; + pCD->phenotype.mechanics.attachment_rate = 1; + pCD->phenotype.mechanics.detachment_rate = 0; + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + display_cell_definitions( std::cout ); + + return; +} + +void setup_microenvironment( void ) +{ + // set domain parameters + + // put any custom code to set non-homogeneous initial conditions or + // extra Dirichlet nodes here. + + // initialize BioFVM + + initialize_microenvironment(); + + return; +} + +void setup_tissue( void ) +{ + double Xmin = microenvironment.mesh.bounding_box[0]; + double Ymin = microenvironment.mesh.bounding_box[1]; + double Zmin = microenvironment.mesh.bounding_box[2]; + + double Xmax = microenvironment.mesh.bounding_box[3]; + double Ymax = microenvironment.mesh.bounding_box[4]; + double Zmax = microenvironment.mesh.bounding_box[5]; + + if( default_microenvironment_options.simulate_2D == true ) + { + Zmin = 0.0; + Zmax = 0.0; + } + + double Xrange = Xmax - Xmin; + double Yrange = Ymax - Ymin; + double Zrange = Zmax - Zmin; + + // create some of each type of cell + + Cell* pC; + + for( int k=0; k < cell_definitions_by_index.size() ; k++ ) + { + Cell_Definition* pCD = cell_definitions_by_index[k]; + std::cout << "Placing cells of type " << pCD->name << " ... " << std::endl; + for( int n = 0 ; n < parameters.ints("number_of_cells") ; n++ ) + { + std::vector position = {0,0,0}; + position[0] = Xmin + UniformRandom()*Xrange; + position[1] = Ymin + UniformRandom()*Yrange; + position[2] = Zmin + UniformRandom()*Zrange; + + pC = create_cell( *pCD ); + pC->assign_position( position ); + } + } + std::cout << std::endl; + + // load cells from your CSV file (if enabled) + load_cells_from_pugixml(); + + for( int n=0; n < (*all_cells).size() ; n++ ) + { + Cell* pC = (*all_cells)[n]; + if( fabs( pC->position[0]) > 450 ) + { set_single_behavior( pC, "is movable" , 0); } + + } + + return; +} + +std::vector my_coloring_function( Cell* pCell ) +{ + std::vector out = { "black" , "black" , "black" , "black"}; + + int n_springs = pCell->state.spring_attachments.size(); + if( pCell->type_name != "BM" ) + { + if( n_springs == 0 ) + { out[0] = "grey"; } + if( n_springs == 1 ) + { out[0] = "indigo"; } + if( n_springs == 2 ) + { out[0] = "blue"; } + if( n_springs == 3 ) + { out[0] = "green"; } + if( n_springs == 4 ) + { out[0] = "yellow"; } + if( n_springs == 5 ) + { out[0] = "orange"; } + if( n_springs == 6 ) + { out[0] = "red"; } + if( n_springs > 6 ) + { out[0] = "magenta"; } + } + + out[2] = out[0]; + out[3] = out[0]; + + // std::vector out = paint_by_number_cell_coloring(pCell); + return out; +} + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ + + return; +} + +void cancer_phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ + if( get_single_signal(pCell,"dead") > 0.5 ) + { return; } + + double b = get_single_base_behavior( pCell , "cycle entry" ); + if( get_single_signal( pCell , "pressure") > 0.75 ) + { b = 0; } + set_single_behavior( pCell , "cycle entry" , b ); + + if( get_single_signal(pCell,"time") > 10000 ) + { + set_single_behavior(pCell,"apoptosis",9e99); + set_single_behavior(pCell,"cell detachment rate",9e9); + } + return; +} + + +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) +{ return; } + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) +{ return; } \ No newline at end of file diff --git a/sample_projects/mechano/custom_modules/custom.h b/sample_projects/mechano/custom_modules/custom.h new file mode 100644 index 000000000..3602794a8 --- /dev/null +++ b/sample_projects/mechano/custom_modules/custom.h @@ -0,0 +1,93 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include "../core/PhysiCell.h" +#include "../modules/PhysiCell_standard_modules.h" + +using namespace BioFVM; +using namespace PhysiCell; + +// setup functions to help us along + +void create_cell_types( void ); +void setup_tissue( void ); + +// set up the BioFVM microenvironment +void setup_microenvironment( void ); + +// custom pathology coloring function + +std::vector my_coloring_function( Cell* ); + +// custom functions can go here + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ); + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ); + +void cancer_phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); \ No newline at end of file diff --git a/sample_projects/mechano/custom_modules/empty.txt b/sample_projects/mechano/custom_modules/empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/sample_projects/mechano/main.cpp b/sample_projects/mechano/main.cpp new file mode 100644 index 000000000..ffe29342f --- /dev/null +++ b/sample_projects/mechano/main.cpp @@ -0,0 +1,259 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "./core/PhysiCell.h" +#include "./modules/PhysiCell_standard_modules.h" + +// put custom code modules here! + +#include "./custom_modules/custom.h" + +using namespace BioFVM; +using namespace PhysiCell; + +int main( int argc, char* argv[] ) +{ + // load and parse settings file(s) + + bool XML_status = false; + char copy_command [1024]; + if( argc > 1 ) + { + XML_status = load_PhysiCell_config_file( argv[1] ); + sprintf( copy_command , "cp %s %s" , argv[1] , PhysiCell_settings.folder.c_str() ); + } + else + { + XML_status = load_PhysiCell_config_file( "./config/PhysiCell_settings.xml" ); + sprintf( copy_command , "cp ./config/PhysiCell_settings.xml %s" , PhysiCell_settings.folder.c_str() ); + } + if( !XML_status ) + { exit(-1); } + + // copy config file to output directry + system( copy_command ); + + // OpenMP setup + omp_set_num_threads(PhysiCell_settings.omp_num_threads); + + // time setup + std::string time_units = "min"; + + /* Microenvironment setup */ + + setup_microenvironment(); // modify this in the custom code + + /* PhysiCell setup */ + + // set mechanics voxel size, and match the data structure to BioFVM + double mechanics_voxel_size = 30; + Cell_Container* cell_container = create_cell_container_for_microenvironment( microenvironment, mechanics_voxel_size ); + + /* Users typically start modifying here. START USERMODS */ + + create_cell_types(); + + setup_tissue(); + + + /* Users typically stop modifying here. END USERMODS */ + + // set MultiCellDS save options + + set_save_biofvm_mesh_as_matlab( true ); + set_save_biofvm_data_as_matlab( true ); + set_save_biofvm_cell_data( true ); + set_save_biofvm_cell_data_as_custom_matlab( true ); + + // save a simulation snapshot + + char filename[1024]; + sprintf( filename , "%s/initial" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + + // save a quick SVG cross section through z = 0, after setting its + // length bar to 200 microns + + PhysiCell_SVG_options.length_bar = 200; + + + + // for simplicity, set a pathology coloring function + + std::vector (*cell_coloring_function)(Cell*) = my_coloring_function; + + sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + + sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); + create_plot_legend( filename , cell_coloring_function ); + + display_citations(); + + + + // set the performance timers + + BioFVM::RUNTIME_TIC(); + BioFVM::TIC(); + + std::ofstream report_file; + if( PhysiCell_settings.enable_legacy_saves == true ) + { + sprintf( filename , "%s/simulation_report.txt" , PhysiCell_settings.folder.c_str() ); + + report_file.open(filename); // create the data log file + report_file<<"simulated time\tnum cells\tnum division\tnum death\twall time"<update_all_cells( PhysiCell_globals.current_time ); + + /* + Custom add-ons could potentially go here. + */ + + PhysiCell_globals.current_time += diffusion_dt; + } + + if( PhysiCell_settings.enable_legacy_saves == true ) + { + log_output(PhysiCell_globals.current_time, PhysiCell_globals.full_output_index, microenvironment, report_file); + report_file.close(); + } + } + catch( const std::exception& e ) + { // reference to the base of a polymorphic object + std::cout << e.what(); // information from length_error printed + } + + // save a final simulation snapshot + + sprintf( filename , "%s/final" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + sprintf( filename , "%s/final.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + + // timer + + std::cout << std::endl << "Total simulation runtime: " << std::endl; + BioFVM::display_stopwatch_value( std::cout , BioFVM::runtime_stopwatch_value() ); + + return 0; +} diff --git a/sample_projects/pred_prey_farmer/Makefile b/sample_projects/pred_prey_farmer/Makefile index 8c3f91cb3..32ab68e3b 100644 --- a/sample_projects/pred_prey_farmer/Makefile +++ b/sample_projects/pred_prey_farmer/Makefile @@ -263,4 +263,27 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/pred_prey_farmer/config/PhysiCell_settings.xml b/sample_projects/pred_prey_farmer/config/PhysiCell_settings.xml index 5bd9044ed..1d4159620 100644 --- a/sample_projects/pred_prey_farmer/config/PhysiCell_settings.xml +++ b/sample_projects/pred_prey_farmer/config/PhysiCell_settings.xml @@ -121,6 +121,7 @@ false true + false @@ -262,10 +263,10 @@ - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 diff --git a/sample_projects/template/Makefile b/sample_projects/template/Makefile index f1bf12f38..1381dd805 100644 --- a/sample_projects/template/Makefile +++ b/sample_projects/template/Makefile @@ -263,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/template/config/PhysiCell_settings.xml b/sample_projects/template/config/PhysiCell_settings.xml index 335a8a916..fd8cdc5a0 100644 --- a/sample_projects/template/config/PhysiCell_settings.xml +++ b/sample_projects/template/config/PhysiCell_settings.xml @@ -104,7 +104,7 @@ output - 360 + 60 true @@ -121,6 +121,7 @@ false true + false @@ -224,10 +225,10 @@ - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 @@ -263,7 +264,7 @@ 4.0 10.0 0.01 - 10.0 + 0.0 0.0 diff --git a/sample_projects/virus_macrophage/Makefile b/sample_projects/virus_macrophage/Makefile index ff72d2db8..985c59d82 100644 --- a/sample_projects/virus_macrophage/Makefile +++ b/sample_projects/virus_macrophage/Makefile @@ -263,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/virus_macrophage/config/PhysiCell_settings.xml b/sample_projects/virus_macrophage/config/PhysiCell_settings.xml index d3443d0c2..11f849069 100644 --- a/sample_projects/virus_macrophage/config/PhysiCell_settings.xml +++ b/sample_projects/virus_macrophage/config/PhysiCell_settings.xml @@ -121,6 +121,7 @@ false true + false @@ -222,10 +223,10 @@ - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 diff --git a/sample_projects/worm/Makefile b/sample_projects/worm/Makefile index 5667f3067..c90103ac7 100644 --- a/sample_projects/worm/Makefile +++ b/sample_projects/worm/Makefile @@ -263,4 +263,26 @@ upgrade: $(SOURCE) unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf mv -f PhysiCell/documentation/User_Guide.pdf documentation rm -f -r PhysiCell - rm -f $(SOURCE) \ No newline at end of file + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ diff --git a/sample_projects/worm/config/PhysiCell_settings.xml b/sample_projects/worm/config/PhysiCell_settings.xml index 34349476c..6cdee6e31 100644 --- a/sample_projects/worm/config/PhysiCell_settings.xml +++ b/sample_projects/worm/config/PhysiCell_settings.xml @@ -121,6 +121,7 @@ false true + true @@ -188,10 +189,10 @@ - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile b/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile index 790163a30..8f2e90f48 100644 --- a/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/Makefile @@ -78,9 +78,10 @@ PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_signal_behavior.o PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o \ -PhysiCell_pugixml.o PhysiCell_settings.o +PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o # put your custom objects here (they should be in the custom_modules directory) +MaBoSS := ./addons/PhysiBoSS/MaBoSS-env-2.0/engine/src/BooleanNetwork.h PhysiBoSS_OBJECTS := maboss_network.o maboss_intracellular.o @@ -93,7 +94,7 @@ ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiCell_custom_module_OBJECTS) $(PhysiBo # compile the project -all: MaBoSS main.cpp $(ALL_OBJECTS) +all: main.cpp $(ALL_OBJECTS) $(MaBoSS) $(COMPILE_COMMAND) $(INC) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp $(LIB) @echo "" @echo "check for $(PROGRAM_NAME)" @@ -112,7 +113,7 @@ PhysiCell_phenotype.o: ./core/PhysiCell_phenotype.cpp PhysiCell_digital_cell_line.o: ./core/PhysiCell_digital_cell_line.cpp $(COMPILE_COMMAND) -c ./core/PhysiCell_digital_cell_line.cpp -PhysiCell_cell.o: ./core/PhysiCell_cell.cpp +PhysiCell_cell.o: ./core/PhysiCell_cell.cpp $(MaBoSS) $(COMPILE_COMMAND) $(INC) -c ./core/PhysiCell_cell.cpp PhysiCell_cell_container.o: ./core/PhysiCell_cell_container.cpp @@ -133,12 +134,6 @@ PhysiCell_constants.o: ./core/PhysiCell_constants.cpp PhysiCell_signal_behavior.o: ./core/PhysiCell_signal_behavior.cpp $(COMPILE_COMMAND) -c ./core/PhysiCell_signal_behavior.cpp -PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp - $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp - -PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp - $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp - # BioFVM core components (needed by PhysiCell) BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp @@ -185,32 +180,37 @@ PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp - PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp - $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp +PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + +PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp + # user-defined PhysiCell modules -Compile_MaBoSS: MaBoSS +Compile_MaBoSS: ./addons/PhysiBoSS/MaBoSS-env-2.0/engine/src/BooleanNetwork.h cd ./addons/PhysiBoSS/MaBoSS-env-2.0/engine/src;make CXX=$(CC) install_alib;make clean; cd ../../../../.. -MaBoSS: +$(MaBoSS): ifeq ($(OS), Windows_NT) python beta/setup_libmaboss.py else python3 beta/setup_libmaboss.py endif -maboss_network.o: ./addons/PhysiBoSS/src/maboss_network.cpp +maboss_network.o: ./addons/PhysiBoSS/src/maboss_network.cpp $(MaBoSS) $(COMPILE_COMMAND) $(INC) -c ./addons/PhysiBoSS/src/maboss_network.cpp -maboss_intracellular.o: ./addons/PhysiBoSS/src/maboss_intracellular.cpp +maboss_intracellular.o: ./addons/PhysiBoSS/src/maboss_intracellular.cpp $(MaBoSS) $(COMPILE_COMMAND) $(INC) -c ./addons/PhysiBoSS/src/maboss_intracellular.cpp -custom.o: ./custom_modules/custom.cpp +custom.o: ./custom_modules/custom.cpp $(MaBoSS) $(COMPILE_COMMAND) $(INC) -c ./custom_modules/custom.cpp # cleanup diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/config/PhysiCell_settings.xml b/sample_projects_intracellular/boolean/physiboss_cell_lines/config/PhysiCell_settings.xml index 76451efcb..b41a3fc53 100644 --- a/sample_projects_intracellular/boolean/physiboss_cell_lines/config/PhysiCell_settings.xml +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/config/PhysiCell_settings.xml @@ -1,272 +1,1068 @@ - - - - - - - - -100 - 200 - -100 - 100 - -20 - 20 - 10 - 10 - 10 - false - - - - 200 - min - micron - - 0.02 - 0.1 - 0.5 - - - - 6 - - - - output - - - 10 - true - - - - 10 - true - - - - true - - - - - - - 100000.0 - .1 - - 38.0 - 38.0 - - - - true - true - - - ./config/initial.mat - - - - ./config/dirichlet.mat - - - - - - - - - - - 0.0 - - - - - - 0 - - - - 0.0 - - - - - 1000 - - 0.0 - 0.0 - 0.0 - - - - - false - false - - - - ./config/model_0.bnd - ./config/model.cfg - - 1 - - - 1 - 0 - - - - - inhibition - 10 - 10 - - - - - activation - 5 - 0 - 5 - - - - - - - - - - - ./config/model_1.bnd - - - - - - - - - - 0.0 - - - - - - - - - - - - 0.2 - - - - - - - - - - - 0.25 - - - - - - - - - - - 0.0 - - - - - - - - - - 0 - C - - - + + + + -100 + 200 + -100 + 100 + -20 + 20 + 10 + 10 + 10 + false + + + + 200 + min + micron + 0.02 + 0.1 + 0.5 + + + + 6 + + + + output + + 10 + true + + + 10 + true + + + true + + + + + false + false + true + + + + + + 100000.0 + .1 + + 38.0 + 38.0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + true + true + + ./config/initial.mat + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + 0.0 + 0.0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + 1000 + 0.75 + 540 + 0.0 + 0.0 + 0.0 + 0 + 0 + 2.0 + + + 0 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 0.25 + 5 + 0.5 + + false + false + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + 0 + 38 + 10 + 0 + + + + 0.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + 1.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + ./config/model_0.bnd + ./config/model.cfg + + 1 + 0 + + + 1 + 0.0 + 1.0 + 0.0 + + + + + + + 1.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + 1000 + 0.75 + 540 + 0.0 + 0.0 + 0.0 + 0 + 0 + 2.0 + + + 0 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 0.25 + 5 + 0.5 + + false + false + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + 0 + 38 + 10 + 0 + + + + 0.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + 1.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + ./config/model_1.bnd + ./config/model.cfg + + 1 + 0 + + + 1 + 0.0 + 1.0 + 0.0 + + + + + + + 1.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + 1000 + 0.75 + 540 + 0.0 + 0.0 + 0.0 + 0 + 0 + 2.0 + + + 0 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 0.25 + 5 + 0.5 + + false + false + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + 0 + 38 + 10 + 0 + + + + 0.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + 1.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + ./config/model_0.bnd + ./config/model.cfg + + 1 + 0 + + + 1 + 0.0 + 1.0 + 0.0 + + + 0 + + + + + + + 1.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + 1000 + 0.75 + 540 + 0.0 + 0.0 + 0.0 + 0 + 0 + 2.0 + + + 0 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 0.25 + 5 + 0.5 + + false + false + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + 0 + 38 + 10 + 0 + + + + 0.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + 1.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + ./config/model_0.bnd + ./config/model.cfg + + 1 + 0 + + + 1 + 0.0 + 1.0 + 0.0 + + + 0.2 + + + + + + + 1.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + 1000 + 0.75 + 540 + 0.0 + 0.0 + 0.0 + 0 + 0 + 2.0 + + + 0 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 0.25 + 5 + 0.5 + + false + false + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + 0 + 38 + 10 + 0 + + + + 0.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + 1.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + ./config/model_0.bnd + ./config/model.cfg + + 1 + 0 + + + 1 + 0.0 + 0.25 + 0.0 + + + + + + + 1.0 + + + + + + + 0.0 + 0.0 + 0.0 + + + + + 0 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + 1000 + 0.75 + 540 + 0.0 + 0.0 + 0.0 + 0 + 0 + 2.0 + + + 0 + 10.0 + 1.25 + + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + 0.25 + 5 + 0.5 + + false + false + + false + oxygen + 1 + + + false + false + + 0.0 + + + + + + + 0 + 38 + 10 + 0 + + + + 0.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + 1.0 + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + + + + ./config/model_0.bnd + ./config/model.cfg + + 0 + 1 + + + 1 + 0.0 + 1.0 + 0.0 + + + 0.0 + + + + + + + 1.0 + + + + + + + ./config + cells.csv + + + + + 0 + C + \ No newline at end of file diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/config/cells.csv b/sample_projects_intracellular/boolean/physiboss_cell_lines/config/cells.csv new file mode 100644 index 000000000..186e7d313 --- /dev/null +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/config/cells.csv @@ -0,0 +1,486 @@ +-10,-10,0,0 +10,-10,0,1 +-10,10,0,2 +10,10,0,3 +110,10,0,4 +110,-10,0,5 +-10,-20,0,0 +10,-20,0,1 +-10,20,0,2 +10,20,0,3 +110,20,0,4 +110,-20,0,5 +-10,-30,0,0 +10,-30,0,1 +-10,30,0,2 +10,30,0,3 +110,30,0,4 +110,-30,0,5 +-10,-40,0,0 +10,-40,0,1 +-10,40,0,2 +10,40,0,3 +110,40,0,4 +110,-40,0,5 +-10,-50,0,0 +10,-50,0,1 +-10,50,0,2 +10,50,0,3 +110,50,0,4 +110,-50,0,5 +-10,-60,0,0 +10,-60,0,1 +-10,60,0,2 +10,60,0,3 +110,60,0,4 +110,-60,0,5 +-10,-70,0,0 +10,-70,0,1 +-10,70,0,2 +10,70,0,3 +110,70,0,4 +110,-70,0,5 +-10,-80,0,0 +10,-80,0,1 +-10,80,0,2 +10,80,0,3 +110,80,0,4 +110,-80,0,5 +-10,-90,0,0 +10,-90,0,1 +-10,90,0,2 +10,90,0,3 +110,90,0,4 +110,-90,0,5 +-20,-10,0,0 +20,-10,0,1 +-20,10,0,2 +20,10,0,3 +120,10,0,4 +120,-10,0,5 +-20,-20,0,0 +20,-20,0,1 +-20,20,0,2 +20,20,0,3 +120,20,0,4 +120,-20,0,5 +-20,-30,0,0 +20,-30,0,1 +-20,30,0,2 +20,30,0,3 +120,30,0,4 +120,-30,0,5 +-20,-40,0,0 +20,-40,0,1 +-20,40,0,2 +20,40,0,3 +120,40,0,4 +120,-40,0,5 +-20,-50,0,0 +20,-50,0,1 +-20,50,0,2 +20,50,0,3 +120,50,0,4 +120,-50,0,5 +-20,-60,0,0 +20,-60,0,1 +-20,60,0,2 +20,60,0,3 +120,60,0,4 +120,-60,0,5 +-20,-70,0,0 +20,-70,0,1 +-20,70,0,2 +20,70,0,3 +120,70,0,4 +120,-70,0,5 +-20,-80,0,0 +20,-80,0,1 +-20,80,0,2 +20,80,0,3 +120,80,0,4 +120,-80,0,5 +-20,-90,0,0 +20,-90,0,1 +-20,90,0,2 +20,90,0,3 +120,90,0,4 +120,-90,0,5 +-30,-10,0,0 +30,-10,0,1 +-30,10,0,2 +30,10,0,3 +130,10,0,4 +130,-10,0,5 +-30,-20,0,0 +30,-20,0,1 +-30,20,0,2 +30,20,0,3 +130,20,0,4 +130,-20,0,5 +-30,-30,0,0 +30,-30,0,1 +-30,30,0,2 +30,30,0,3 +130,30,0,4 +130,-30,0,5 +-30,-40,0,0 +30,-40,0,1 +-30,40,0,2 +30,40,0,3 +130,40,0,4 +130,-40,0,5 +-30,-50,0,0 +30,-50,0,1 +-30,50,0,2 +30,50,0,3 +130,50,0,4 +130,-50,0,5 +-30,-60,0,0 +30,-60,0,1 +-30,60,0,2 +30,60,0,3 +130,60,0,4 +130,-60,0,5 +-30,-70,0,0 +30,-70,0,1 +-30,70,0,2 +30,70,0,3 +130,70,0,4 +130,-70,0,5 +-30,-80,0,0 +30,-80,0,1 +-30,80,0,2 +30,80,0,3 +130,80,0,4 +130,-80,0,5 +-30,-90,0,0 +30,-90,0,1 +-30,90,0,2 +30,90,0,3 +130,90,0,4 +130,-90,0,5 +-40,-10,0,0 +40,-10,0,1 +-40,10,0,2 +40,10,0,3 +140,10,0,4 +140,-10,0,5 +-40,-20,0,0 +40,-20,0,1 +-40,20,0,2 +40,20,0,3 +140,20,0,4 +140,-20,0,5 +-40,-30,0,0 +40,-30,0,1 +-40,30,0,2 +40,30,0,3 +140,30,0,4 +140,-30,0,5 +-40,-40,0,0 +40,-40,0,1 +-40,40,0,2 +40,40,0,3 +140,40,0,4 +140,-40,0,5 +-40,-50,0,0 +40,-50,0,1 +-40,50,0,2 +40,50,0,3 +140,50,0,4 +140,-50,0,5 +-40,-60,0,0 +40,-60,0,1 +-40,60,0,2 +40,60,0,3 +140,60,0,4 +140,-60,0,5 +-40,-70,0,0 +40,-70,0,1 +-40,70,0,2 +40,70,0,3 +140,70,0,4 +140,-70,0,5 +-40,-80,0,0 +40,-80,0,1 +-40,80,0,2 +40,80,0,3 +140,80,0,4 +140,-80,0,5 +-40,-90,0,0 +40,-90,0,1 +-40,90,0,2 +40,90,0,3 +140,90,0,4 +140,-90,0,5 +-50,-10,0,0 +50,-10,0,1 +-50,10,0,2 +50,10,0,3 +150,10,0,4 +150,-10,0,5 +-50,-20,0,0 +50,-20,0,1 +-50,20,0,2 +50,20,0,3 +150,20,0,4 +150,-20,0,5 +-50,-30,0,0 +50,-30,0,1 +-50,30,0,2 +50,30,0,3 +150,30,0,4 +150,-30,0,5 +-50,-40,0,0 +50,-40,0,1 +-50,40,0,2 +50,40,0,3 +150,40,0,4 +150,-40,0,5 +-50,-50,0,0 +50,-50,0,1 +-50,50,0,2 +50,50,0,3 +150,50,0,4 +150,-50,0,5 +-50,-60,0,0 +50,-60,0,1 +-50,60,0,2 +50,60,0,3 +150,60,0,4 +150,-60,0,5 +-50,-70,0,0 +50,-70,0,1 +-50,70,0,2 +50,70,0,3 +150,70,0,4 +150,-70,0,5 +-50,-80,0,0 +50,-80,0,1 +-50,80,0,2 +50,80,0,3 +150,80,0,4 +150,-80,0,5 +-50,-90,0,0 +50,-90,0,1 +-50,90,0,2 +50,90,0,3 +150,90,0,4 +150,-90,0,5 +-60,-10,0,0 +60,-10,0,1 +-60,10,0,2 +60,10,0,3 +160,10,0,4 +160,-10,0,5 +-60,-20,0,0 +60,-20,0,1 +-60,20,0,2 +60,20,0,3 +160,20,0,4 +160,-20,0,5 +-60,-30,0,0 +60,-30,0,1 +-60,30,0,2 +60,30,0,3 +160,30,0,4 +160,-30,0,5 +-60,-40,0,0 +60,-40,0,1 +-60,40,0,2 +60,40,0,3 +160,40,0,4 +160,-40,0,5 +-60,-50,0,0 +60,-50,0,1 +-60,50,0,2 +60,50,0,3 +160,50,0,4 +160,-50,0,5 +-60,-60,0,0 +60,-60,0,1 +-60,60,0,2 +60,60,0,3 +160,60,0,4 +160,-60,0,5 +-60,-70,0,0 +60,-70,0,1 +-60,70,0,2 +60,70,0,3 +160,70,0,4 +160,-70,0,5 +-60,-80,0,0 +60,-80,0,1 +-60,80,0,2 +60,80,0,3 +160,80,0,4 +160,-80,0,5 +-60,-90,0,0 +60,-90,0,1 +-60,90,0,2 +60,90,0,3 +160,90,0,4 +160,-90,0,5 +-70,-10,0,0 +70,-10,0,1 +-70,10,0,2 +70,10,0,3 +170,10,0,4 +170,-10,0,5 +-70,-20,0,0 +70,-20,0,1 +-70,20,0,2 +70,20,0,3 +170,20,0,4 +170,-20,0,5 +-70,-30,0,0 +70,-30,0,1 +-70,30,0,2 +70,30,0,3 +170,30,0,4 +170,-30,0,5 +-70,-40,0,0 +70,-40,0,1 +-70,40,0,2 +70,40,0,3 +170,40,0,4 +170,-40,0,5 +-70,-50,0,0 +70,-50,0,1 +-70,50,0,2 +70,50,0,3 +170,50,0,4 +170,-50,0,5 +-70,-60,0,0 +70,-60,0,1 +-70,60,0,2 +70,60,0,3 +170,60,0,4 +170,-60,0,5 +-70,-70,0,0 +70,-70,0,1 +-70,70,0,2 +70,70,0,3 +170,70,0,4 +170,-70,0,5 +-70,-80,0,0 +70,-80,0,1 +-70,80,0,2 +70,80,0,3 +170,80,0,4 +170,-80,0,5 +-70,-90,0,0 +70,-90,0,1 +-70,90,0,2 +70,90,0,3 +170,90,0,4 +170,-90,0,5 +-80,-10,0,0 +80,-10,0,1 +-80,10,0,2 +80,10,0,3 +180,10,0,4 +180,-10,0,5 +-80,-20,0,0 +80,-20,0,1 +-80,20,0,2 +80,20,0,3 +180,20,0,4 +180,-20,0,5 +-80,-30,0,0 +80,-30,0,1 +-80,30,0,2 +80,30,0,3 +180,30,0,4 +180,-30,0,5 +-80,-40,0,0 +80,-40,0,1 +-80,40,0,2 +80,40,0,3 +180,40,0,4 +180,-40,0,5 +-80,-50,0,0 +80,-50,0,1 +-80,50,0,2 +80,50,0,3 +180,50,0,4 +180,-50,0,5 +-80,-60,0,0 +80,-60,0,1 +-80,60,0,2 +80,60,0,3 +180,60,0,4 +180,-60,0,5 +-80,-70,0,0 +80,-70,0,1 +-80,70,0,2 +80,70,0,3 +180,70,0,4 +180,-70,0,5 +-80,-80,0,0 +80,-80,0,1 +-80,80,0,2 +80,80,0,3 +180,80,0,4 +180,-80,0,5 +-80,-90,0,0 +80,-90,0,1 +-80,90,0,2 +80,90,0,3 +180,90,0,4 +180,-90,0,5 +-90,-10,0,0 +90,-10,0,1 +-90,10,0,2 +90,10,0,3 +190,10,0,4 +190,-10,0,5 +-90,-20,0,0 +90,-20,0,1 +-90,20,0,2 +90,20,0,3 +190,20,0,4 +190,-20,0,5 +-90,-30,0,0 +90,-30,0,1 +-90,30,0,2 +90,30,0,3 +190,30,0,4 +190,-30,0,5 +-90,-40,0,0 +90,-40,0,1 +-90,40,0,2 +90,40,0,3 +190,40,0,4 +190,-40,0,5 +-90,-50,0,0 +90,-50,0,1 +-90,50,0,2 +90,50,0,3 +190,50,0,4 +190,-50,0,5 +-90,-60,0,0 +90,-60,0,1 +-90,60,0,2 +90,60,0,3 +190,60,0,4 +190,-60,0,5 +-90,-70,0,0 +90,-70,0,1 +-90,70,0,2 +90,70,0,3 +190,70,0,4 +190,-70,0,5 +-90,-80,0,0 +90,-80,0,1 +-90,80,0,2 +90,80,0,3 +190,80,0,4 +190,-80,0,5 +-90,-90,0,0 +90,-90,0,1 +-90,90,0,2 +90,90,0,3 +190,90,0,4 +190,-90,0,5 \ No newline at end of file diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.cpp b/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.cpp index 4b3435684..02b7752de 100644 --- a/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.cpp +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/custom_modules/custom.cpp @@ -148,48 +148,8 @@ void setup_microenvironment( void ) void setup_tissue( void ) { - Cell* pC; - - // We have four different cells populations - // All start with A active and C inactive, B is random - // We print the value of C - - for (int i=0; i < 90; i+= 10) - for (int j=0; j < 90; j+= 10){ - - // bottom left : default - // the formula for C is A&B. Meaning that C will only activate for half the cells - pC = create_cell(get_cell_definition("default")); - pC->assign_position(-i-10, -j-10, 0.0 ); - - // bottom middle : other - // the formula for C is A|B. C will activate in all cells - pC = create_cell(get_cell_definition("other")); - pC->assign_position(i+10, -j-10, 0.0 ); - - // top left : another - // Here we mutate the C node at zero, so it will stay there - pC = create_cell(get_cell_definition("another")); - pC->assign_position(-i-10, j+10, 0.0 ); - - // top middle : yet_another - // Here we change the default value for the rates, acelerating the activation of C - pC = create_cell(get_cell_definition("yet_another")); - pC->assign_position(i+10, j+10, 0.0 ); - - // top right : yet_yet_another - // Here we acelerate the activation of C by changing the scaling value - pC = create_cell(get_cell_definition("yet_yet_another")); - pC->assign_position(i+110, j+10, 0.0 ); - - // bottom right : last_one - // Here we start with $time_scale = 0, then at the middle of the simulation we set it to 0.1 - pC = create_cell(get_cell_definition("last_one")); - pC->assign_position(i+110, -j-10, 0.0 ); - } - - - return; + // load cells from your CSV file + load_cells_from_pugixml(); } void pre_update_intracellular( Cell* pCell, Phenotype& phenotype, double dt ) @@ -199,6 +159,7 @@ void pre_update_intracellular( Cell* pCell, Phenotype& phenotype, double dt ) ){ pCell->phenotype.intracellular->set_parameter_value("$time_scale", 0.1); } + } void post_update_intracellular( Cell* pCell, Phenotype& phenotype, double dt ) diff --git a/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp b/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp index ea36f0dda..fbb71ca96 100644 --- a/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp +++ b/sample_projects_intracellular/boolean/physiboss_cell_lines/main.cpp @@ -88,13 +88,23 @@ int main( int argc, char* argv[] ) // load and parse settings file(s) bool XML_status = false; + char copy_command [1024]; if( argc > 1 ) - { XML_status = load_PhysiCell_config_file( argv[1] ); } + { + XML_status = load_PhysiCell_config_file( argv[1] ); + sprintf( copy_command , "cp %s %s" , argv[1] , PhysiCell_settings.folder.c_str() ); + } else - { XML_status = load_PhysiCell_config_file( "./config/PhysiCell_settings.xml" ); } + { + XML_status = load_PhysiCell_config_file( "./config/PhysiCell_settings.xml" ); + sprintf( copy_command , "cp ./config/PhysiCell_settings.xml %s" , PhysiCell_settings.folder.c_str() ); + } if( !XML_status ) { exit(-1); } + // copy config file to output directry + system( copy_command ); + // OpenMP setup omp_set_num_threads(PhysiCell_settings.omp_num_threads); @@ -154,6 +164,9 @@ int main( int argc, char* argv[] ) sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); + sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); + create_plot_legend( filename , cell_coloring_function ); + display_citations(); // set the performance timers diff --git a/sample_projects_intracellular/fba/cancer_metabolism/config/PhysiCell_settings.xml b/sample_projects_intracellular/fba/cancer_metabolism/config/PhysiCell_settings.xml index 9c9c67ecc..f6e8ca34e 100755 --- a/sample_projects_intracellular/fba/cancer_metabolism/config/PhysiCell_settings.xml +++ b/sample_projects_intracellular/fba/cancer_metabolism/config/PhysiCell_settings.xml @@ -121,6 +121,7 @@ false true + false @@ -195,10 +196,10 @@ - 0.05 - 0 - 1.66667e-02 - 5.83333e-03 + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 0 2.0 diff --git a/sample_projects_intracellular/fba/ecoli_acetic_switch/config/PhysiCell_settings.xml b/sample_projects_intracellular/fba/ecoli_acetic_switch/config/PhysiCell_settings.xml index 14c0baf0e..4271cce11 100644 --- a/sample_projects_intracellular/fba/ecoli_acetic_switch/config/PhysiCell_settings.xml +++ b/sample_projects_intracellular/fba/ecoli_acetic_switch/config/PhysiCell_settings.xml @@ -95,6 +95,10 @@ 3 + + false + + 8 diff --git a/sample_projects_intracellular/ode/ode1/config/PhysiCell_settings.xml b/sample_projects_intracellular/ode/ode1/config/PhysiCell_settings.xml index 7a36b80de..0bd220cb7 100644 --- a/sample_projects_intracellular/ode/ode1/config/PhysiCell_settings.xml +++ b/sample_projects_intracellular/ode/ode1/config/PhysiCell_settings.xml @@ -102,6 +102,7 @@ false + false diff --git a/sample_projects_intracellular/ode/ode2/config/PhysiCell_settings.xml b/sample_projects_intracellular/ode/ode2/config/PhysiCell_settings.xml index 038120faa..d5723a892 100644 --- a/sample_projects_intracellular/ode/ode2/config/PhysiCell_settings.xml +++ b/sample_projects_intracellular/ode/ode2/config/PhysiCell_settings.xml @@ -120,6 +120,7 @@ false + false diff --git a/sample_projects_intracellular/ode/ode_energy/config/PhysiCell_settings.xml b/sample_projects_intracellular/ode/ode_energy/config/PhysiCell_settings.xml index 4fde2d6d9..41901eff6 100644 --- a/sample_projects_intracellular/ode/ode_energy/config/PhysiCell_settings.xml +++ b/sample_projects_intracellular/ode/ode_energy/config/PhysiCell_settings.xml @@ -120,6 +120,7 @@ false + false diff --git a/sample_projects_intracellular/ode/test_sbml1/config/PhysiCell_settings.xml b/sample_projects_intracellular/ode/test_sbml1/config/PhysiCell_settings.xml index 7eea4b6f2..dc51b2b39 100644 --- a/sample_projects_intracellular/ode/test_sbml1/config/PhysiCell_settings.xml +++ b/sample_projects_intracellular/ode/test_sbml1/config/PhysiCell_settings.xml @@ -102,6 +102,7 @@ false + false diff --git a/tests/.DS_Store b/tests/.DS_Store deleted file mode 100644 index df997df48..000000000 Binary files a/tests/.DS_Store and /dev/null differ diff --git a/unit_tests/.DS_Store b/unit_tests/.DS_Store deleted file mode 100644 index f5663a5eb..000000000 Binary files a/unit_tests/.DS_Store and /dev/null differ diff --git a/unit_tests/custom_voxel_values/Makefile b/unit_tests/custom_voxel_values/Makefile new file mode 100644 index 000000000..e27362f79 --- /dev/null +++ b/unit_tests/custom_voxel_values/Makefile @@ -0,0 +1,309 @@ +VERSION := $(shell grep . VERSION.txt | cut -f1 -d:) +PROGRAM_NAME := test_voxel_values + +CC := g++ +# CC := g++-mp-7 # typical macports compiler name +# CC := g++-7 # typical homebrew compiler name + +# Check for environment definitions of compiler +# e.g., on CC = g++-7 on OSX +ifdef PHYSICELL_CPP + CC := $(PHYSICELL_CPP) +endif + +ARCH := native # best auto-tuning +# ARCH := core2 # a reasonably safe default for most CPUs since 2007 +# ARCH := corei7 +# ARCH := corei7-avx # earlier i7 +# ARCH := core-avx-i # i7 ivy bridge or newer +# ARCH := core-avx2 # i7 with Haswell or newer +# ARCH := nehalem +# ARCH := westmere +# ARCH := sandybridge # circa 2011 +# ARCH := ivybridge # circa 2012 +# ARCH := haswell # circa 2013 +# ARCH := broadwell # circa 2014 +# ARCH := skylake # circa 2015 +# ARCH := bonnell +# ARCH := silvermont +# ARCH := skylake-avx512 +# ARCH := nocona #64-bit pentium 4 or later + +# CFLAGS := -march=$(ARCH) -Ofast -s -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 +CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 + +ifeq ($(OS),Windows_NT) +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Darwin) + UNAME_P := $(shell uname -p) + var := $(shell which $(CC) | xargs file) + ifeq ($(lastword $(var)),arm64) + CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -fopenmp -m64 -std=c++11 + endif + endif +endif + +COMPILE_COMMAND := $(CC) $(CFLAGS) + +BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o + +PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ +PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ +PhysiCell_signal_behavior.o + +PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o \ +PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o + +# put your custom objects here (they should be in the custom_modules directory) + +PhysiCell_custom_module_OBJECTS := custom.o + +pugixml_OBJECTS := pugixml.o + +PhysiCell_OBJECTS := $(BioFVM_OBJECTS) $(pugixml_OBJECTS) $(PhysiCell_core_OBJECTS) $(PhysiCell_module_OBJECTS) +ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiCell_custom_module_OBJECTS) + +# compile the project + +all: main.cpp $(ALL_OBJECTS) + $(COMPILE_COMMAND) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp + make name + +name: + @echo "" + @echo "Executable name is" $(PROGRAM_NAME) + @echo "" + +# PhysiCell core components + +PhysiCell_phenotype.o: ./core/PhysiCell_phenotype.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_phenotype.cpp + +PhysiCell_digital_cell_line.o: ./core/PhysiCell_digital_cell_line.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_digital_cell_line.cpp + +PhysiCell_cell.o: ./core/PhysiCell_cell.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell.cpp + +PhysiCell_cell_container.o: ./core/PhysiCell_cell_container.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell_container.cpp + +PhysiCell_standard_models.o: ./core/PhysiCell_standard_models.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_standard_models.cpp + +PhysiCell_utilities.o: ./core/PhysiCell_utilities.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_utilities.cpp + +PhysiCell_custom.o: ./core/PhysiCell_custom.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_custom.cpp + +PhysiCell_constants.o: ./core/PhysiCell_constants.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_constants.cpp + +PhysiCell_signal_behavior.o: ./core/PhysiCell_signal_behavior.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_signal_behavior.cpp + +# BioFVM core components (needed by PhysiCell) + +BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_vector.cpp + +BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp + +BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp + +BioFVM_microenvironment.o: ./BioFVM/BioFVM_microenvironment.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_microenvironment.cpp + +BioFVM_solvers.o: ./BioFVM/BioFVM_solvers.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_solvers.cpp + +BioFVM_utilities.o: ./BioFVM/BioFVM_utilities.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_utilities.cpp + +BioFVM_basic_agent.o: ./BioFVM/BioFVM_basic_agent.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent.cpp + +BioFVM_matlab.o: ./BioFVM/BioFVM_matlab.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_matlab.cpp + +BioFVM_MultiCellDS.o: ./BioFVM/BioFVM_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_MultiCellDS.cpp + +pugixml.o: ./BioFVM/pugixml.cpp + $(COMPILE_COMMAND) -c ./BioFVM/pugixml.cpp + +# standard PhysiCell modules + +PhysiCell_SVG.o: ./modules/PhysiCell_SVG.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_SVG.cpp + +PhysiCell_pathology.o: ./modules/PhysiCell_pathology.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pathology.cpp + +PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_MultiCellDS.cpp + +PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp + +PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp + +PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + +PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + +PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp + +# user-defined PhysiCell modules + +custom.o: ./custom_modules/custom.cpp + $(COMPILE_COMMAND) -c ./custom_modules/custom.cpp + +# cleanup + +reset: + rm -f *.cpp + cp ./sample_projects/Makefile-default Makefile + rm -f ./custom_modules/* + touch ./custom_modules/empty.txt + touch ALL_CITATIONS.txt + touch ./core/PhysiCell_cell.cpp + rm ALL_CITATIONS.txt + cp ./config/PhysiCell_settings-backup.xml ./config/PhysiCell_settings.xml + touch ./config/empty.csv + rm -f ./config/*.csv + +clean: + rm -f *.o + rm -f $(PROGRAM_NAME)* + +data-cleanup: + rm -rf ./output + mkdir ./output + touch ./output/empty.txt + +# archival + +checkpoint: + zip -r $$(date +%b_%d_%Y_%H%M).zip Makefile *.cpp *.h config/*.xml custom_modules/* + +zip: + zip -r latest.zip Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.zip $$(date +%b_%d_%Y_%H%M).zip + cp latest.zip VERSION_$(VERSION).zip + mv *.zip archives/ + +tar: + tar --ignore-failed-read -czf latest.tar Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.tar $$(date +%b_%d_%Y_%H%M).tar + cp latest.tar VERSION_$(VERSION).tar + mv *.tar archives/ + +unzip: + cp ./archives/latest.zip . + unzip latest.zip + +untar: + cp ./archives/latest.tar . + tar -xzf latest.tar + +# easier animation + +FRAMERATE := 24 +OUTPUT := output + +jpeg: + @magick identify -format "%h" $(OUTPUT)/initial.svg > __H.txt + @magick identify -format "%w" $(OUTPUT)/initial.svg > __W.txt + @expr 2 \* \( $$(grep . __H.txt) / 2 \) > __H1.txt + @expr 2 \* \( $$(grep . __W.txt) / 2 \) > __W1.txt + @echo "$$(grep . __W1.txt)!x$$(grep . __H1.txt)!" > __resize.txt + @magick mogrify -format jpg -resize $$(grep . __resize.txt) $(OUTPUT)/s*.svg + rm -f __H*.txt __W*.txt __resize.txt + +gif: + magick convert $(OUTPUT)/s*.svg $(OUTPUT)/out.gif + +movie: + ffmpeg -r $(FRAMERATE) -f image2 -i $(OUTPUT)/snapshot%08d.jpg -vcodec libx264 -pix_fmt yuv420p -strict -2 -tune animation -crf 15 -acodec none $(OUTPUT)/out.mp4 + +# upgrade rules + +SOURCE := PhysiCell_upgrade.zip +get-upgrade: + @echo $$(curl https://raw.githubusercontent.com/MathCancer/PhysiCell/master/VERSION.txt) > VER.txt + @echo https://github.com/MathCancer/PhysiCell/releases/download/$$(grep . VER.txt)/PhysiCell_V.$$(grep . VER.txt).zip > DL_FILE.txt + rm -f VER.txt + $$(curl -L $$(grep . DL_FILE.txt) --output PhysiCell_upgrade.zip) + rm -f DL_FILE.txt + +PhysiCell_upgrade.zip: + make get-upgrade + +upgrade: $(SOURCE) + unzip $(SOURCE) PhysiCell/VERSION.txt + mv -f PhysiCell/VERSION.txt . + unzip $(SOURCE) PhysiCell/core/* + cp -r PhysiCell/core/* core + unzip $(SOURCE) PhysiCell/modules/* + cp -r PhysiCell/modules/* modules + unzip $(SOURCE) PhysiCell/sample_projects/* + cp -r PhysiCell/sample_projects/* sample_projects + unzip $(SOURCE) PhysiCell/BioFVM/* + cp -r PhysiCell/BioFVM/* BioFVM + unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf + mv -f PhysiCell/documentation/User_Guide.pdf documentation + rm -f -r PhysiCell + rm -f $(SOURCE) + +#=================================================================== +#------------- 1.10.5 addition to save user projects -------------- +# useage: make save PROJ=your_project_name +PROJ := my_project +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +# useage: make load PROJ=your_project_name +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ + +# useage: make share PROJ=your_project_name +share: + @echo "Preparing your project for sharing from $(PROJ) ... " + @echo " " + zip -r $(PROJ)_$$(date +%b_%d_%Y_%H%M).zip ./user_projects/$(PROJ)/* + @echo "Project saved in $(PROJ)_$$(date +%b_%d_%Y_%H%M).zip." + @echo "It can be unzipped (or use tar -xvf) in a PhysiCell root directory." + @echo " " + +# sci_package: make sci_package PROJ=your_project_name +sci_package: + @echo "Preparing your project for scientific archival from $(PROJ) ... " + @echo " " + touch output/empty.txt + zip -r $(PROJ)_packaged_$$(date +%b_%d_%Y_%H%M).zip main.cpp Makefile ./config/* ./BioFVM/* VERSION.txt ./custom_modules/* ./core/* ./addons/* ./licenses/* ./modules/* ./output/empty.txt + @echo "Project saved in $(PROJ)_packaged_$$(date +%b_%d_%Y_%H%M).zip." + @echo "It is fully self-contained and can be distributed as a separate GitHub repository." + @echo " " diff --git a/unit_tests/custom_voxel_values/config/PhysiCell_settings.xml b/unit_tests/custom_voxel_values/config/PhysiCell_settings.xml new file mode 100644 index 000000000..95c58f68b --- /dev/null +++ b/unit_tests/custom_voxel_values/config/PhysiCell_settings.xml @@ -0,0 +1,229 @@ + + + -30 + 30 + -30 + 30 + -30 + 30 + 20 + 20 + 20 + false + + + + 1 + min + micron + + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + + 1 + true + + + + 1 + true + + + + false + + + + + false + false + + + + + + 0 + 0 + + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + + + + + true + false + + + ./config/initial.mat + + + + ./config/dirichlet.mat + + + + + + + + + + 0.0 + + + + + + 5.31667e-05 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + + + 523.6 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + + 0.4 + 10.0 + 1.25 + + 1.0 + + + 1.8 + 15.12 + + 4.0 + 10.0 + 0.01 + 10.0 + 0.0 + + + + 1 + 1 + 1 + + true + false + + true + oxygen + 1 + + + false + false + + 0.01 + + + + + + + + 0 + 1 + 0 + 0 + + + + + 0.0 + + 0.0 + + + + 0.0 + + + 1.0 + + 0.0 + + + + + + + 0.0 + + + + + + 1.0 + + + + + + + + ./config + cells1.csv + + + + + 0 + 0 + + + \ No newline at end of file diff --git a/unit_tests/custom_voxel_values/custom_modules/custom.cpp b/unit_tests/custom_voxel_values/custom_modules/custom.cpp new file mode 100644 index 000000000..74f057adb --- /dev/null +++ b/unit_tests/custom_voxel_values/custom_modules/custom.cpp @@ -0,0 +1,229 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include "./custom.h" + +void create_cell_types( void ) +{ + // set the random seed + SeedRandom( parameters.ints("random_seed") ); + + /* + Put any modifications to default cell definition here if you + want to have "inherited" by other cell types. + + This is a good place to set default functions. + */ + + initialize_default_cell_definition(); + cell_defaults.phenotype.secretion.sync_to_microenvironment( µenvironment ); + + cell_defaults.functions.volume_update_function = standard_volume_update_function; + cell_defaults.functions.update_velocity = standard_update_cell_velocity; + + cell_defaults.functions.update_migration_bias = NULL; + cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based; + cell_defaults.functions.custom_cell_rule = NULL; + cell_defaults.functions.contact_function = NULL; + + cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; + cell_defaults.functions.calculate_distance_to_membrane = NULL; + + /* + This parses the cell definitions in the XML config file. + */ + + initialize_cell_definitions_from_pugixml(); + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + build_cell_definitions_maps(); + + /* + This intializes cell signal and response dictionaries + */ + + setup_signal_behavior_dictionaries(); + + /* + Put any modifications to individual cell definitions here. + + This is a good place to set custom functions. + */ + + cell_defaults.functions.update_phenotype = phenotype_function; + // cell_defaults.functions.custom_cell_rule = custom_function; + // cell_defaults.functions.contact_function = contact_function; + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + display_cell_definitions( std::cout ); + + return; +} + +void setup_microenvironment( void ) +{ + // initialize BioFVM + + initialize_microenvironment(); + + int idx_oxygen = 0; + double oxy_value = 40.0; // set voxel values sequentially + + int idx_xmax = microenvironment.mesh.x_coordinates.size() - 1; + int idx_ymax = microenvironment.mesh.y_coordinates.size() - 1; + int idx_zmax = microenvironment.mesh.z_coordinates.size() - 1; + + for (int idz=0; idzname << " ... " << std::endl; + // for( int n = 0 ; n < parameters.ints("number_of_cells") ; n++ ) + // { + // std::vector position = {0,0,0}; + // position[0] = Xmin + UniformRandom()*Xrange; + // position[1] = Ymin + UniformRandom()*Yrange; + // position[2] = Zmin + UniformRandom()*Zrange; + + // pC = create_cell( *pCD ); + // pC->assign_position( position ); + // } + // } + // std::cout << std::endl; + + // single cell at origin + Cell_Definition* pCD = cell_definitions_by_index[0]; + std::vector position = {0,0,0}; + pC = create_cell( *pCD ); + pC->assign_position( position ); + + + // load cells from your CSV file (if enabled) + load_cells_from_pugixml(); + return; +} + +std::vector my_coloring_function( Cell* pCell ) +{ return paint_by_number_cell_coloring(pCell); } + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ + return; +} + +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) +{ return; } + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) +{ return; } \ No newline at end of file diff --git a/unit_tests/custom_voxel_values/custom_modules/custom.h b/unit_tests/custom_voxel_values/custom_modules/custom.h new file mode 100644 index 000000000..0e6df8d02 --- /dev/null +++ b/unit_tests/custom_voxel_values/custom_modules/custom.h @@ -0,0 +1,92 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include "../core/PhysiCell.h" +#include "../modules/PhysiCell_standard_modules.h" + +using namespace BioFVM; +using namespace PhysiCell; + +// setup functions to help us along + +void create_cell_types( void ); +void setup_tissue( void ); + +// set up the BioFVM microenvironment +void setup_microenvironment( void ); + +// custom pathology coloring function + +std::vector my_coloring_function( Cell* ); + +// custom functions can go here + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ); + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ); + diff --git a/sample_projects/biorobots/main-biorobots.cpp b/unit_tests/custom_voxel_values/main.cpp similarity index 96% rename from sample_projects/biorobots/main-biorobots.cpp rename to unit_tests/custom_voxel_values/main.cpp index 05b39a49f..9d26e541d 100644 --- a/sample_projects/biorobots/main-biorobots.cpp +++ b/unit_tests/custom_voxel_values/main.cpp @@ -76,9 +76,9 @@ #include "./core/PhysiCell.h" #include "./modules/PhysiCell_standard_modules.h" -// custom user modules +// put custom code modules here! -#include "./custom_modules/biorobots.h" +#include "./custom_modules/custom.h" using namespace BioFVM; using namespace PhysiCell; @@ -108,27 +108,25 @@ int main( int argc, char* argv[] ) // OpenMP setup omp_set_num_threads(PhysiCell_settings.omp_num_threads); - // PNRG setup - SeedRandom(); - // time setup std::string time_units = "min"; /* Microenvironment setup */ - setup_microenvironment(); - + setup_microenvironment(); // modify this in the custom code + /* PhysiCell setup */ // set mechanics voxel size, and match the data structure to BioFVM double mechanics_voxel_size = 30; Cell_Container* cell_container = create_cell_container_for_microenvironment( microenvironment, mechanics_voxel_size ); - create_cell_types(); - setup_tissue(); - /* Users typically start modifying here. START USERMODS */ + create_cell_types(); + + setup_tissue(); + /* Users typically stop modifying here. END USERMODS */ // set MultiCellDS save options @@ -139,7 +137,7 @@ int main( int argc, char* argv[] ) set_save_biofvm_cell_data_as_custom_matlab( true ); // save a simulation snapshot - + char filename[1024]; sprintf( filename , "%s/initial" , PhysiCell_settings.folder.c_str() ); save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); @@ -151,13 +149,13 @@ int main( int argc, char* argv[] ) // for simplicity, set a pathology coloring function - std::vector (*cell_coloring_function)(Cell*) = robot_coloring_function; + std::vector (*cell_coloring_function)(Cell*) = my_coloring_function; sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function ); sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); - create_plot_legend( filename , cell_coloring_function ); + create_plot_legend( filename , cell_coloring_function ); display_citations(); @@ -178,7 +176,7 @@ int main( int argc, char* argv[] ) // main loop try - { + { while( PhysiCell_globals.current_time < PhysiCell_settings.max_time + 0.1*diffusion_dt ) { // save data if it's time. @@ -213,13 +211,17 @@ int main( int argc, char* argv[] ) PhysiCell_globals.next_SVG_save_time += PhysiCell_settings.SVG_save_interval; } } - + // update the microenvironment microenvironment.simulate_diffusion_decay( diffusion_dt ); // run PhysiCell ((Cell_Container *)microenvironment.agent_container)->update_all_cells( PhysiCell_globals.current_time ); + /* + Custom add-ons could potentially go here. + */ + PhysiCell_globals.current_time += diffusion_dt; } diff --git a/user_projects/empty.txt b/user_projects/empty.txt new file mode 100644 index 000000000..e69de29bb