Skip to content

Commit

Permalink
Merge pull request #20 from MathCancer/development
Browse files Browse the repository at this point in the history
Development - 1.5.2 release
  • Loading branch information
MathCancer committed Jun 11, 2019
2 parents ddbc4b4 + ad10ba7 commit 3f6ae1f
Show file tree
Hide file tree
Showing 14 changed files with 642 additions and 46 deletions.
14 changes: 9 additions & 5 deletions BioFVM/BioFVM_basic_agent.cpp
Expand Up @@ -180,10 +180,7 @@ void Basic_Agent::register_microenvironment( Microenvironment* microenvironment_
return;
}

Microenvironment* Basic_Agent::get_microenvironment( void )
{ return microenvironment; }

Basic_Agent::~Basic_Agent()
void Basic_Agent::release_internalized_substrates( void )
{
Microenvironment* pS = get_default_microenvironment();

Expand All @@ -198,11 +195,18 @@ Basic_Agent::~Basic_Agent()

// release this amount into the environment

(*pS)(current_voxel_index) += *internalized_substrates;
(*pS)(current_voxel_index) += *internalized_substrates;

// zero out the now-removed substrates

internalized_substrates->assign( internalized_substrates->size() , 0.0 );

return;
}

Microenvironment* Basic_Agent::get_microenvironment( void )
{ return microenvironment; }

Basic_Agent* create_basic_agent( void )
{
Basic_Agent* pNew;
Expand Down
3 changes: 2 additions & 1 deletion BioFVM/BioFVM_basic_agent.h
Expand Up @@ -88,6 +88,7 @@ class Basic_Agent
std::vector<double> * internalized_substrates;
std::vector<double> * fraction_released_at_death;
std::vector<double> * fraction_transferred_when_ingested;
void release_internalized_substrates( void );

void set_internal_uptake_constants( double dt ); // any time you update the cell volume or rates, should call this function.

Expand All @@ -106,7 +107,7 @@ class Basic_Agent
void update_position( double dt );

Basic_Agent();
~Basic_Agent();

// simulate secretion and uptake at the nearest voxel at the indicated microenvironment.
// if no microenvironment indicated, use the currently selected microenvironment.
void simulate_secretion_and_uptake( Microenvironment* M, double dt );
Expand Down
4 changes: 2 additions & 2 deletions 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.5.1) [1].
We implemented and solved the model using PhysiCell (Version 1.5.2) [1].

[1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin,
PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu-
Expand All @@ -11,7 +11,7 @@ We implemented and solved the model using PhysiCell (Version 1.5.1) [1].
Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM
as below:

We implemented and solved the model using PhysiCell (Version 1.5.1) [1],
We implemented and solved the model using PhysiCell (Version 1.5.2) [1],
with BioFVM [2] to solve the transport equations.

[1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin,
Expand Down
31 changes: 20 additions & 11 deletions README.md
@@ -1,13 +1,12 @@
# PhysiCell: an Open Source Physics-Based Cell Simulator for 3-D Multicellular Systems.

**Version:** 1.5.1
**Version:** 1.5.2

**Release date:** 7 June 2019
**Release date:** 11 June 2019

## 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.
Expand Down Expand Up @@ -61,7 +60,9 @@ See changes.md for the full change log.

## 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.
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.

Expand All @@ -71,22 +72,30 @@ This minor release fixes bugs in the new virus-macrophage sample project. Users

### Minor new features and changes:

+ None
+ 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):

+ None
+ 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:

+ In the virus-macrophage sample project, switch cell death (in epithelial_function) from apoptosis to cell_lysis to demonstrate the new function.
+ Move code for internalized substrate release from the Basic_Agent destructor to the new Basic_Agent::release_internalized_substrates() function.

+ In the virus-macrophage sample project, enable internalized substrate tracking in the setup_microenvironment() function.
+ Basic_Agent::release_internalized_substrates() is now called from delete_cell(int) in PhysiCell_cell.cpp.

+ In the virus-macrophage sample project, use a slower viral replication rate. (Should take 240 minutes to reach the lysis threshold.)
+ 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.

+ In the virus-macrophage sample project, switched to a maximum simulation time of 24 hours (1440 minutes).
+ 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.
Expand Down
2 changes: 1 addition & 1 deletion VERSION.txt
@@ -1 +1 @@
1.5.1
1.5.2
123 changes: 102 additions & 21 deletions beta/anim_svg_step.py → beta/anim_svg.py
@@ -1,19 +1,19 @@
#
# anim_svg_step.py: render/animate PhysiCell .svg files, using left/right arrows on keyboard
# anim_svg.py: render/animate PhysiCell .svg files, using left/right arrows on keyboard
#
# Usage:
# python anim_svg_step.py <show_nucleus start_index axes_min axes_max scale_radius>
# python anim_svg.py <show_nucleus start_index axes_min axes_max>
# i.e., the arguments <...> are optional and have defaults.
#
# Keyboard arrows: right/left arrows will single step forward/backward; up/down will increment/decrement step size
#
# Dependencies include matplotlib and numpy. We recommend installing the Anaconda Python3 distribution.
#
# Examples (run from directory containing the .svg files):
# python anim_svg_step.py
# python anim_svg_step.py 0 5 700 1300 12
# python anim_svg.py
# python anim_svg.py 0 5 700 1300
#
# Author: Randy Heiland
# Author: Randy Heiland (except for the circles() function)
#
#
__author__ = "Randy Heiland"
Expand All @@ -27,6 +27,8 @@
try:
import matplotlib
import matplotlib.colors as mplc
from matplotlib.patches import Circle, Ellipse, Rectangle
from matplotlib.collections import PatchCollection
except:
print("\n---Error: cannot import matplotlib")
print("---Try: python -m pip install matplotlib")
Expand Down Expand Up @@ -62,8 +64,7 @@
current_idx = 0
axes_min = 0.0
axes_max = 1000 # but overridden by "width" attribute in .svg
scale_radius = 1.0
if (len(sys.argv) == 6):
if (len(sys.argv) == 5):
use_defaults = False
kdx = 1
show_nucleus = int(sys.argv[kdx])
Expand All @@ -73,14 +74,12 @@
axes_min = float(sys.argv[kdx])
kdx += 1
axes_max = float(sys.argv[kdx])
kdx += 1
scale_radius = float(sys.argv[kdx])
elif (len(sys.argv) != 1):
print("Please provide either no args or 5 args:")
usage_str = "show_nucleus start_index axes_min axes_max scale_radius"
print("Please provide either no args or 4 args:")
usage_str = "show_nucleus start_index axes_min axes_max"
print(usage_str)
print("e.g.,")
eg_str = "%s 0 0 0 2000 1" % (sys.argv[0])
eg_str = "%s 0 0 0 2000" % (sys.argv[0])
print(eg_str)
sys.exit(1)

Expand All @@ -89,7 +88,6 @@
print("current_idx=",current_idx)
print("axes_min=",axes_min)
print("axes_max=",axes_max)
print("scale_radius=",scale_radius)
#"""

"""
Expand All @@ -98,14 +96,12 @@
if (len(sys.argv) > 2):
axes_min = float(sys.argv[2])
axes_max = float(sys.argv[3])
if (len(sys.argv) == 5):
scale_radius = float(sys.argv[4])
if (len(sys.argv) > 5):
usage_str = "[<start_index> [<axes_min axes_max [scale_radius]]]"
if (len(sys.argv) > 4):
usage_str = "[<start_index> [<axes_min axes_max>]]"
print(usage_str)
print("e.g.,")
eg_str = "%s 10 700 1300 4" % (sys.argv[0])
eg_str = "%s 1 10 700 1300" % (sys.argv[0])
print(eg_str)
sys.exit(1)
"""
Expand Down Expand Up @@ -134,6 +130,82 @@

count = -1
#while True:

#-----------------------------------------------------
def circles(x, y, s, c='b', vmin=None, vmax=None, **kwargs):
"""
See https://gist.github.com/syrte/592a062c562cd2a98a83
Make a scatter plot of circles.
Similar to plt.scatter, but the size of circles are in data scale.
Parameters
----------
x, y : scalar or array_like, shape (n, )
Input data
s : scalar or array_like, shape (n, )
Radius of circles.
c : color or sequence of color, optional, default : 'b'
`c` can be a single color format string, or a sequence of color
specifications of length `N`, or a sequence of `N` numbers to be
mapped to colors using the `cmap` and `norm` specified via kwargs.
Note that `c` should not be a single numeric RGB or RGBA sequence
because that is indistinguishable from an array of values
to be colormapped. (If you insist, use `color` instead.)
`c` can be a 2-D array in which the rows are RGB or RGBA, however.
vmin, vmax : scalar, optional, default: None
`vmin` and `vmax` are used in conjunction with `norm` to normalize
luminance data. If either are `None`, the min and max of the
color array is used.
kwargs : `~matplotlib.collections.Collection` properties
Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls),
norm, cmap, transform, etc.
Returns
-------
paths : `~matplotlib.collections.PathCollection`
Examples
--------
a = np.arange(11)
circles(a, a, s=a*0.2, c=a, alpha=0.5, ec='none')
plt.colorbar()
License
--------
This code is under [The BSD 3-Clause License]
(http://opensource.org/licenses/BSD-3-Clause)
"""

if np.isscalar(c):
kwargs.setdefault('color', c)
c = None

if 'fc' in kwargs:
kwargs.setdefault('facecolor', kwargs.pop('fc'))
if 'ec' in kwargs:
kwargs.setdefault('edgecolor', kwargs.pop('ec'))
if 'ls' in kwargs:
kwargs.setdefault('linestyle', kwargs.pop('ls'))
if 'lw' in kwargs:
kwargs.setdefault('linewidth', kwargs.pop('lw'))
# You can set `facecolor` with an array for each patch,
# while you can only set `facecolors` with a value for all.

zipped = np.broadcast(x, y, s)
patches = [Circle((x_, y_), s_)
for x_, y_, s_ in zipped]
collection = PatchCollection(patches, **kwargs)
if c is not None:
c = np.broadcast_to(c, zipped.shape).ravel()
collection.set_array(c)
collection.set_clim(vmin, vmax)

ax = plt.gca()
ax.add_collection(collection)
ax.autoscale_view()
plt.draw_if_interactive()
if c is not None:
plt.sci(collection)
return collection

#-----------------------------------------------------
def plot_svg():
global current_idx, axes_max
fname = "snapshot%08d.svg" % current_idx
Expand Down Expand Up @@ -218,12 +290,13 @@ def plot_svg():
break

rval = float(circle.attrib['r'])
# if (rgb[0] > rgb[1]):
# print(num_cells,rgb, rval)
# print('rval=',rval)

xlist.append(xval)
ylist.append(yval)
rlist.append(rval)
rgb_list.append(rgb)
# print('rgb_list = ',rgb_list)

# For .svg files with cells that *have* a nucleus, there will be a 2nd
if (show_nucleus == 0):
Expand All @@ -242,6 +315,8 @@ def plot_svg():
yvals = np.array(ylist)
rvals = np.array(rlist)
rgbs = np.array(rgb_list)
# print('type(rgbs) = ',type(rgbs))
# print('rgbs = ',rgbs)
#print("xvals[0:5]=",xvals[0:5])
#print("rvals[0:5]=",rvals[0:5])
# print("rvals.min, max=",rvals.min(),rvals.max())
Expand All @@ -251,7 +326,13 @@ def plot_svg():
plt.title(title_str)
plt.xlim(axes_min,axes_max)
plt.ylim(axes_min,axes_max)
plt.scatter(xvals,yvals, s=rvals*scale_radius, c=rgbs)
# plt.scatter(xvals,yvals, s=rvals*scale_radius, c=rgbs)
# plt.scatter(xvals,yvals, s=rvals*scale_radius, c=rgbs, alpha=0.5, edgecolor='black')
# plt.scatter(xvals,yvals, s=rvals*scale_radius, c=rgbs, alpha=1.0, edgecolor='black')
# circles(xvals,yvals, s=rvals, c=rgbs, alpha=1.0, edgecolor='black')
# circles(xvals,yvals, s=rvals)
# circles(xvals,yvals, s=rvals, c=rgbs)
circles(xvals,yvals, s=rvals, color=rgbs)
#plt.xlim(0,2000) # TODO - get these values from width,height in .svg at top
#plt.ylim(0,2000)
plt.pause(time_delay)
Expand Down

0 comments on commit 3f6ae1f

Please sign in to comment.