## Working with PhysiCell MultiCellDS digital snapshots in Matlab

PhysiCell 1.2.1 and later saves data as a specialized MultiCellDS digital snapshot, which includes chemical substrate fields, mesh information, and a readout of the cells and their phenotypes at single simulation time point. This tutorial will help you learn to use the matlab processing files included with PhysiCell.

This tutorial assumes you know (1) how to work at the shell / command line of your operating system, and (2) basic plotting and other functions in Matlab.

### Key elements of a PhysiCell digital snapshot

A PhysiCell digital snapshot (a customized form of the MultiCellDS digital simulation snapshot) includes the following elements saved as XML and MAT files:

1. output12345678.xml : This is the “base” output file, in MultiCellDS format. It includes key metadata such as when the file was created, the software, microenvironment information, and custom data saved at the simulation time. The Matlab files read this base file to find other related files (listed next). Example: output00003696.xml
2. initial_mesh0.mat : This is the computational mesh information for BioFVM at time 0.0. Because BioFVM and PhysiCell do not use moving meshes, we do not save this data at any subsequent time.
3. output12345678_microenvironment0.mat : This saves each biochemical substrate in the microenvironment at the computational voxels defined in the mesh (see above). Example: output00003696_microenvironment0.mat
4. output12345678_cells.mat : This saves very basic cellular information related to BioFVM, including cell positions, volumes, secretion rates, uptake rates, and secretion saturation densities. Example: output00003696_cells.mat
5. output12345678_cells_physicell.mat : This saves extra PhysiCell data for each cell agent, including volume information, cell cycle status, motility information, cell death information, basic mechanics, and any user-defined custom data. Example: output00003696_cells_physicell.mat

These snapshots make extensive use of Matlab Level 4 .mat files, for fast, compact, and well-supported saving of array data. Note that even if you cannot ready MultiCellDS XML files, you can work to parse the .mat files themselves.

### The PhysiCell Matlab .m files

Every PhysiCell distribution includes some matlab functions to work with PhysiCell digital simulation snapshots, stored in the matlab subdirectory. The main ones are:

1. composite_cutaway_plot.m : provides a quick, coarse 3-D cutaway plot of the discrete cells, with different colors for live (red), apoptotic (b), and necrotic (black) cells.
2. read_MultiCellDS_xml.m : reads the “base” PhysiCell snapshot and its associated matlab files.
3. set_MCDS_constants.m : creates a data structure MCDS_constants that has the same constants as PhysiCell_constants.h. This is useful for identifying cell cycle phases, etc.
4. simple_cutaway_plot.m : provides a quick, coarse 3-D cutaway plot of user-specified cells.
5. simple_plot.m : provides, a quick, coarse 3-D plot of the user-specified cells, without a cutaway or cross-sectional clipping plane.

#### A note on GNU Octave

Unfortunately, GNU octave does not include XML file parsing without some significant user tinkering. And one you’re done, it is approximately one order of magnitude slower than Matlab. Octave users can directly import the .mat files described above, but without the helpful metadata in the XML file. We’ll provide more information on the structure of these MAT files in a future blog post. Moreover, we plan to provide python and other tools for users without access to Matlab.

### A sample digital snapshot

We provide a 3-D simulation snapshot from the final simulation time of the cancer-immune example in Ghaffarizadeh et al. (2017, in review) at:

The corresponding SVG cross-section for that time (through = 0 μm) looks like this:

Unzip the sample dataset in any directory, and make sure the matlab files above are in the same directory (or in your Matlab path). If you’re inside matlab:

!unzip 3D_PhysiCell_matlab_sample.zip


MCDS = read_MultiCellDS_xml( 'output00003696.xml');


This will load the mesh, substrates, and discrete cells into the MCDS data structure, and give a basic summary:

Typing ‘MCDS’ and then hitting ‘tab’ (for auto-completion) shows the overall structure of MCDS, stored as metadata, mesh, continuum variables, and discrete cells:

To get simulation metadata, such as the current simulation time, look at MCDS.metadata.current_time

Here, we see that the current simulation time is 30240 minutes, or 21 days. MCDS.metadata.current_runtime gives the elapsed walltime to up to this point: about 53 hours (1.9e5 seconds), including file I/O time to write full simulation data once per 3 simulated minutes after the start of the adaptive immune response.

### Plotting chemical substrates

Let’s make an oxygen contour plot through z = 0 μm. First, we find the index corresponding to this z-value:

k = find( MCDS.mesh.Z_coordinates == 0 );


Next, let’s figure out which variable is oxygen. Type “MCDS.continuum_variables.name”, which will show the array of variable names:

Here, oxygen is the first variable, (index 1). So, to make a filled contour plot:

contourf( MCDS.mesh.X(:,:,k), MCDS.mesh.Y(:,:,k), ...
MCDS.continuum_variables(1).data(:,:,k) , 20 ) ;


Now, let’s set this to a correct aspect ratio (no stretching in x or y), add a colorbar, and set the axis labels, using

axis image
colorbar
xlabel( sprintf( 'x (%s)' , MCDS.metadata.spatial_units) );
ylabel( sprintf( 'y (%s)' , MCDS.metadata.spatial_units) );


Lastly, let’s add an appropriate (time-based) title:

title( sprintf('%s (%s) at t = %3.2f %s, z = %3.2f %s', MCDS.continuum_variables(1).name , ...
MCDS.continuum_variables(1).units , ...
MCDS.mesh.Z_coordinates(k), ...


Here’s the end result:

We can easily export graphics, such as to PNG format:

print( '-dpng' , 'output_o2.png' );


For more on plotting BioFVM data, see the tutorial
at http://www.mathcancer.org/blog/saving-multicellds-data-from-biofvm/

### Plotting cells in space

#### 3-D point cloud

First, let’s plot all the cells in 3D:

plot3( MCDS.discrete_cells.state.position(:,1) , MCDS.discrete_cells.state.position(:,2), ...
MCDS.discrete_cells.state.position(:,3) , 'bo' );


At first glance, this does not look good: some cells are far out of the simulation domain, distorting the automatic range of the plot:

This does not ordinarily happen in PhysiCell (the default cell mechanics functions have checks to prevent such behavior), but this example includes a simple Hookean elastic adhesion model for immune cell attachment to tumor cells. In rare circumstances, an attached tumor cell or immune cell can apoptose on its own (due to its background apoptosis rate),
without “knowing” to detach itself from the surviving cell in the pair. The remaining cell attempts to calculate its elastic velocity based upon an invalid cell position (no longer in memory), creating an artificially large velocity that “flings” it out of the simulation domain. Such cells  are not simulated any further, so this is effectively equivalent to an extra apoptosis event (only 3 cells are out of the simulation domain after tens of millions of cell-cell elastic adhesion calculations). Future versions of this example will include extra checks to prevent this rare behavior.

The plot can simply be fixed by changing the axis:

axis( 1000*[-1 1 -1 1 -1 1] )
axis square


Notice that this is a very difficult plot to read, and very non-interactive (laggy) to rotation and scaling operations. We can make a slightly nicer plot by searching for different cell types and plotting them with different colors:

% make it easier to work with the cell positions;
P = MCDS.discrete_cells.state.position;

% find type 1 cells
ind1 = find( MCDS.discrete_cells.metadata.type == 1 );
% better still, eliminate those out of the simulation domain
ind1 = find( MCDS.discrete_cells.metadata.type == 1 & ...
abs(P(:,1))' < 1000 & abs(P(:,2))' < 1000 & abs(P(:,3))' < 1000 );

% find type 0 cells
ind0 = find( MCDS.discrete_cells.metadata.type == 0 & ...
abs(P(:,1))' < 1000 & abs(P(:,2))' < 1000 & abs(P(:,3))' < 1000 );

%now plot them
P = MCDS.discrete_cells.state.position;
plot3( P(ind0,1), P(ind0,2), P(ind0,3), 'bo' )
hold on
plot3( P(ind1,1), P(ind1,2), P(ind1,3), 'ro' )
hold off
axis( 1000*[-1 1 -1 1 -1 1] )
axis square


However, this isn’t much better. You can use the scatter3 function to gain more control on the size and color of the plotted cells, or even make macros to plot spheres in the cell locations (with shading and lighting), but Matlab is very slow when plotting beyond 103 cells. Instead, we recommend the faster preview functions below for data exploration, and higher-quality plotting (e.g., by POV-ray) for final publication-

#### Fast 3-D cell data previewers

Notice that plot3 and scatter3 are painfully slow for any nontrivial number of cells. We can use a few fast previewers to quickly get a sense of the data. First, let’s plot all the dead cells, and make them red:

clf
simple_plot( MCDS,  MCDS, MCDS.discrete_cells.dead_cells , 'r' )


This function creates a coarse-grained 3-D indicator function (0 if no cells are present; 1 if they are), and plots a 3-D level surface. It is very responsive to rotations and other operations to explore the data. You may notice the second argument is a list of indices: only these cells are plotted. This gives you a method to select cells with specific characteristics when plotting. (More on that below.) If you want to get a sense of the interior structure, use a cutaway plot:

clf
simple_cutaway_plot( MCDS, MCDS, MCDS.discrete_cells.dead_cells , 'r' )


We also provide a fast “composite” cutaway which plots all live cells as red, apoptotic cells as blue (without the cutaway), and all necrotic cells as black:

clf
composite_cutaway_plot( MCDS )


Lastly, we show an improved plot that uses different colors for the immune cells, and Matlab’s “find” function to help set up the indexing:

constants = set_MCDS_constants

% find the type 0 necrotic cells
ind0_necrotic = find( MCDS.discrete_cells.metadata.type == 0 & ...
(MCDS.discrete_cells.phenotype.cycle.current_phase == constants.necrotic_swelling | ...
MCDS.discrete_cells.phenotype.cycle.current_phase == constants.necrotic_lysed | ...
MCDS.discrete_cells.phenotype.cycle.current_phase == constants.necrotic) );

% find the live type 0 cells
ind0_live = find( MCDS.discrete_cells.metadata.type == 0 & ...
(MCDS.discrete_cells.phenotype.cycle.current_phase ~= constants.necrotic_swelling & ...
MCDS.discrete_cells.phenotype.cycle.current_phase ~= constants.necrotic_lysed & ...
MCDS.discrete_cells.phenotype.cycle.current_phase ~= constants.necrotic & ...
MCDS.discrete_cells.phenotype.cycle.current_phase ~= constants.apoptotic) );

clf
% plot live tumor cells red, in cutaway view
simple_cutaway_plot( MCDS, ind0_live , 'r' );
hold on
% plot dead tumor cells black, in cutaway view
simple_cutaway_plot( MCDS, ind0_necrotic , 'k' )
% plot all immune cells, but without cutaway (to show how they infiltrate)
simple_plot( MCDS, ind1, 'g' )
hold off


### A small cautionary note on future compatibility

PhysiCell 1.2.1 uses the <custom> data tag (allowed as part of the MultiCellDS specification) to encode its cell data, to allow a more compact data representation, because the current PhysiCell daft does not support such a formulation, and Matlab is painfully slow at parsing XML files larger than ~50 MB. Thus, PhysiCell snapshots are not yet fully compatible with general MultiCellDS tools, which would by default ignore custom data. In the future, we will make available converter utilities to transform “native” custom PhysiCell snapshots to MultiCellDS snapshots that encode all the cellular information in a more verbose but compatible XML format.

### Closing words and future work

Because Octave is not a great option for parsing XML files (with critical MultiCellDS metadata), we plan to write similar functions to read and plot PhysiCell snapshots in Python, as an open source alternative. Moreover, our lab in the next year will focus on creating further MultiCellDS configuration, analysis, and visualization routines. We also plan to provide additional 3-D functions for plotting the discrete cells and varying color with their properties.

In the longer term, we will develop open source, stand-alone analysis and visualization tools for MultiCellDS snapshots (including PhysiCell snapshots). Please stay tuned!

Tags :

## Running the PhysiCell sample projects

### Introduction

In PhysiCell 1.2.1 and later, we include four sample projects on cancer heterogeneity, bioengineered multicellular systems, and cancer immunology. This post will walk you through the steps to build and run the examples.

If you are new to PhysiCell, you should first make sure you’re ready to run it. (Please note that this applies in particular for OSX users, as Xcode’s g++ is not compatible out-of-the-box.) Here are tutorials on getting ready to Run PhysiCell:

1. Setting up a 64-bit gcc environment in Windows.
2. Setting up gcc / OpenMP on OSX (MacPorts edition)
3. Setting up gcc / OpenMP on OSX (Homebrew edition)
Note: This is the preferred method for Mac OSX.
4. Getting started with a PhysiCell Virtual Appliance (for virtual machines like VirtualBox)
Note: The “native” setups above are preferred, but the Virtual Appliance is a great “plan B” if you run into trouble

Please note that we expect to expand this tutorial.

### Building, running, and viewing the sample projects

All of these projects will create data of the following forms:

1. Scalable vector graphics (SVG) cross-section plots through = 0.0 μm at each output time. Filenames will look like snapshot00000000.svg.
2. Matlab (Level 4) .mat files to store raw BioFVM data. Filenames will look like output00000000_microenvironment0.mat (for the chemical substrates) and output00000000_cells.mat (for basic agent data).
3. Matlab .mat files to store additional PhysiCell agent data. Filenames will look like output00000000_cells_physicell.mat.
4. MultiCellDS .xml files that give further metadata and structure for the .mat files. Filenames will look like output00000000.xml.

You can read the combined data in the XML and MAT files with the read_MultiCellDS_xml function, stored in the matlab directory of every PhysiCell download. (Copy the read_MultiCellDS_xml.m and set_MultiCelLDS_constants.m files to the same directory as your data for the greatest simplicity.)

(If you are using Mac OSX and PhysiCell version > 1.2.1, remember to set the PHYSICELL_CPP environment variable to be an OpenMP-capable compiler – rf. Homebrew setup.)

#### Biorobots (2D)

Type the following from a terminal window in your root PhysiCell directory:

make biorobots-sample
make
./biorobots
make reset # optional -- gets a clean slate to try other samples


Because this is a 2-D example, the SVG snapshot files will provide the simplest method of visualizing these outputs. You can use utilities like ImageMagick to convert them into other formats for publications, such as PNG or EPS.

#### Anti-cancer biorobots (2D)

make cancer-biorobots-sample
make
./cancer_biorobots
make reset # optional -- gets a clean slate to try other samples


#### Cancer heterogeneity (2D)

make heterogeneity-sample
make project
./heterogeneity
make reset # optional -- gets a clean slate to try other samples


#### Cancer immunology (3D)

make cancer-immune-sample
make
./cancer_immune_3D
make reset # optional -- gets a clean slate to try other samples


## Getting started with a PhysiCell Virtual Appliance

Note: This is part of a series of “how-to” blog posts to help new users and developers of BioFVM and PhysiCell. This guide is for for users in OSX, Linux, or Windows using the VirtualBox virtualization software to run a PhysiCell virtual appliance.

These instructions should get you up and running without needed to install a compiler, makefile capabilities, or any other software (beyond the virtual machine and the PhysiCell virtual appliance). We note that using the PhysiCell source with your own compiler is still the preferred / ideal way to get started, but the virtual appliance option is a fast way to start even if you’re having troubles setting up your development environment.

### What’s a Virtual Machine? What’s a Virtual Appliance?

A virtual machine is a full simulated computer (with its own disk space, operating system, etc.) running on another. They are designed to let a user test on a completely different environment, without affecting the host (main) environment. They also allow a very robust way of taking and reproducing the state of a full working environment.

A virtual appliance is just this: a full image of an installed system (and often its saved state) on a virtual machine, which can easily be installed on a new virtual machine. In this tutorial, you will download our PhysiCell virtual appliance and use its pre-configured compiler and other tools.

### What you’ll need:

• VirtualBox: This is a free, cross-platform program to run virtual machines on OSX, Linux, Windows, and other platforms. It is a safe and easy way to install one full operating (a client system) on your main operating system (the host system). For us, this means that we can distribute a fully working Linux environment with a working copy of all the tools you need to compile and run PhysiCell. As of August 1, 2017, this will download Version 5.1.26.
• PhysiCell Virtual Appliance: This is a single-file distribution of a virtual machine running Alpine Linux, including all key tools needed to compile and run PhysiCell. As of July 31, 2017, this will download PhysiCell 1.2.2 with g++ 6.3.0.
• A computer with hardware support for virtualization: Your CPU needs to have hardware support for virtualization (almost all of them do now), and it has to be enabled in your BIOS. Consult your computer maker on how to turn this on if you get error messages later.

### Main steps:

#### 2) Import the PhysiCell Virtual Appliance

Go the “File” menu and choose “Import Virtual Appliance”. Browse to find the .ova file you just downloaded.

Click on “Next,” and import with all the default options. That’s it!

#### 3) [Optional] Change settings

You most likely won’t need this step, but you can increase/decrease the amount of RAM used for the virtual machine if you select the PhysiCell VM, click the Settings button (orange gear), and choose “System”:We set the Virtual Machine to have 4 GB of RAM. If you have a machine with lots of RAM (16 GB or more), you may want to set this to 8 GB.

Also, you can choose how many virtual CPUs to give to your VM:

We selected 4 when we set up the Virtual Appliance, but you should match the number of physical processor cores on your machine. In my case, I have a quad core processor with hyperthreading. This means 4 real cores, 8 virtual cores, so I select 4 here.

Select the PhysiCell machine, and click the green “start” button. After the virtual machine boots (with the good old LILO boot manager that I’ve missed), you should see this:

Click the "More ..." button, and log in with username: physicell, password: physicell

#### 5) Test the compiler and run your first simulation

Notice that PhysiCell is already there on the desktop in the PhysiCell folder. Right-click, and choose “open terminal here.” You’ll already be in the main PhysiCell root directory.

Now, let’s compile your first project! Type “make template2D && make” And run your project! Type “./project” and let it go!Go ahead and run either the first few days of the simulation (until about 7200 minutes), then hit <control>-C to cancel out. Or run the whole simulation–that’s fine, too.

#### 6) Look at the results

We bundled a few tools to easily look at results. First, ristretto is a very fast image viewer. Let’s view the SVG files: As a nice tip, you can press the left and right arrows to advance through the SVG images, or hold the right arrow down to advance through quickly.

Now, let’s use ImageMagick to convert the SVG files into JPG file: call “magick mogrify -format jpg snap*.svg”

Next, let’s turn those images into a movie. I generally create moves that are 24 frames pers se, so that 1 second of the movie is 1 hour of simulations time. We’ll use mencoder, with options below given to help get a good quality vs. size tradeoff:

When you’re done, view the movie with mplayer. The options below scale the window to fit within the virtual monitor:

If you want to loop the movie, add “-loop 999” to your command.

#### 7) Get familiar with other tools

Use nano (useage: nano <filename>) to quickly change files at the command line. Hit <control>-O to save your results. Hit <control>-X to exit.  <control>-W will search within the file.

Use nedit (useage: nedit <filename> &) to open up one more text files in a graphical editor. This is a good way to edit multiple files at once.

Sometimes, you need to run commands at elevated (admin or root) privileges. Use sudo. Here’s an example, searching the Alpine Linux package manager apk for clang:

physicell:~$sudo apk search gcc [sudo] password for physicell: physicell:~$ sudo apk search clang
clang-analyzer-4.0.0-r0
clang-libs-4.0.0-r0
clang-dev-4.0.0-r0
clang-static-4.0.0-r0
emscripten-fastcomp-1.37.10-r0
clang-doc-4.0.0-r0
clang-4.0.0-r0
physicell:~/Desktop/PhysiCell$ If you want to install clang/llvm (as an alternative compiler): physicell:~$ sudo apk add gcc
physicell:~$sudo apk search clang clang-analyzer-4.0.0-r0 clang-libs-4.0.0-r0 clang-dev-4.0.0-r0 clang-static-4.0.0-r0 emscripten-fastcomp-1.37.10-r0 clang-doc-4.0.0-r0 clang-4.0.0-r0 physicell:~/Desktop/PhysiCell$


Coming soon.

### Why both with zipped source, then?

Given that we can get a whole development environment by just downloading and importing a virtual appliance, why
bother with all the setup of a native development environment, like this tutorial (Windows) or this tutorial (Mac)?

One word: performance. In my testing, I still have not found the performance running inside a
virtual machine to match compiling and running directly on your system. So, the Virtual Appliance is a great
option to get up and running quickly while trying things out, but I still recommend setting up natively with
one of the tutorials I linked in the preceding paragraphs.

### What’s next?

In the coming weeks, we’ll post further tutorials on using PhysiCell. In the meantime, have a look at the
PhysiCell project website, and these links as well:

1. BioFVM on MathCancer.org: http://BioFVM.MathCancer.org
2. BioFVM on SourceForge: http://BioFVM.sf.net
3. BioFVM Method Paper in BioInformatics: http://dx.doi.org/10.1093/bioinformatics/btv730
4. PhysiCell on MathCancer.org: http://PhysiCell.MathCancer.org
5. PhysiCell on Sourceforge: http://PhysiCell.sf.net
6. PhysiCell Method Paper (preprint): https://doi.org/10.1101/088773

## MathCancer C++ Style and Practices Guide

As PhysiCell, BioFVM, and other open source projects start to gain new users and contributors, it’s time to lay out a coding style. We have three goals here:

1. Consistency: It’s easier to understand and contribute to the code if it’s written in a consistent way.
2. Readability: We want the code to be as readable as possible.
3. Reducing errors: We want to avoid coding styles that are more prone to errors. (e.g., code that can be broken by introducing whitespace).

So, here is the guide (revised June 2017). I expect to revise this guide from time to time.

### Place braces on separate lines in functions and classes.

I find it much easier to read a class if the braces are on separate lines, with good use of whitespace. Remember: whitespace costs almost nothing, but reading and understanding (and time!) are expensive.

#### DON’T

class Cell{
public:
double some_variable;
bool some_extra_variable;

Cell(); };

class Phenotype{
public:
double some_variable;
bool some_extra_variable;

Phenotype();
};


#### DO:

class Cell
{
public:
double some_variable;
bool some_extra_variable;

Cell();
};

class Phenotype
{
public:
double some_variable;
bool some_extra_variable;

Phenotype();
};


### Enclose all logic in braces, even when optional.

In C/C++, you can omit the curly braces in some cases. For example, this is legal

if( distance > 1.5*cell_radius )
interaction = false;
force = 0.0; // is this part of the logic, or a separate statement?
error = false;


However, this code is ambiguous to interpret. Moreover, small changes to whitespace–or small additions to the logic–could mess things up here. Use braces to make the logic crystal clear:

#### DON’T

if( distance > 1.5*cell_radius )
interaction = false;
force = 0.0; // is this part of the logic, or a separate statement?
error = false;

if( condition1 == true )
do_something1 = true;
elseif( condition2 == true )
do_something2 = true;
else
do_something3 = true;


#### DO

if( distance > 1.5*cell_radius )
{
interaction = false;
force = 0.0;
}
error = false;

if( condition1 == true )
{ do_something1 = true; }
elseif( condition2 == true )
{ do_something2 = true; }
else
{ do_something3 = true; }


### Put braces on separate lines in logic, except for single-line logic.

This style rule relates to the previous point, to improve readability.

#### DON’T

if( distance > 1.5*cell_radius ){
interaction = false;
force = 0.0; }

if( condition1 == true ){ do_something1 = true; }
elseif( condition2 == true ){
do_something2 = true; }
else
{ do_something3 = true; error = true; }


#### DO

if( distance > 1.5*cell_radius )
{
interaction = false;
force = 0.0;
}

if( condition1 == true )
{ do_something1 = true; } // this is fine
elseif( condition2 == true )
{
do_something2 = true; // this is better
}
else
{
do_something3 = true;
error = true;
}


See how much easier that code is to read? The logical structure is crystal clear, and adding more to the logic is simple.

### End all functions with a return, even if void.

For clarity, definitively state that a function is done by using return.

#### DON’T

void my_function( Cell& cell )
{
cell.phenotype.volume.total *= 2.0;
cell.phenotype.death.rates[0] = 0.02;
// Are we done, or did we forget something?
// is somebody still working here?
}


#### DO

void my_function( Cell& cell )
{
cell.phenotype.volume.total *= 2.0;
cell.phenotype.death.rates[0] = 0.02;
return;
}


### Use tabs to indent the contents of a class or function.

This is to make the code easier to read. (Unfortunately PHP/HTML makes me use five spaces here instead of tabs.)

#### DON’T

class Secretion
{
public:
std::vector<double> secretion_rates;
std::vector<double> uptake_rates;
std::vector<double> saturation_densities;
};

void my_function( Cell& cell )
{
cell.phenotype.volume.total *= 2.0;
cell.phenotype.death.rates[0] = 0.02;
return;
}


#### DO

class Secretion
{
public:
std::vector<double> secretion_rates;
std::vector<double> uptake_rates;
std::vector<double> saturation_densities;
};

void my_function( Cell& cell )
{
cell.phenotype.volume.total *= 2.0;
cell.phenotype.death.rates[0] = 0.02;
return;
}


### Use a single space to indent public and other keywords in a class.

This gets us some nice formatting in classes, without needing two tabs everywhere.

#### DON’T

class Secretion
{
public:
std::vector<double> secretion_rates;
std::vector<double> uptake_rates;
std::vector<double> saturation_densities;
}; // not enough whitespace

class Errors
{
private:
public:
std::string error_message;
int error_code;
}; // too much whitespace!


#### DO

class Secretion
{
private:
public:
std::vector<double> secretion_rates;
std::vector<double> uptake_rates;
std::vector<double> saturation_densities;
};

class Errors
{
private:
public:
std::string error_message;
int error_code;
};


### Avoid arcane operators, when clear logic statements will do.

It can be difficult to decipher code with statements like this:

phenotype.volume.fluid=phenotype.volume.fluid<0?0:phenotype.volume.fluid;


Moreover, C and C++ can treat precedence of ternary operators very differently, so subtle bugs can creep in when using the “fancier” compact operators. Variations in how these operators work across languages are an additional source of error for programmers switching between languages in their daily scientific workflows. Wherever possible (and unless there is a significant performance reason to do so), use clear logical structures that are easy to read even if you only dabble in C/C++. Compiler-time optimizations will most likely eliminate any performance gains from these goofy operators.

#### DON’T

// if the fluid volume is negative, set it to zero
phenotype.volume.fluid=phenotype.volume.fluid<0.0?0.0:pCell->phenotype.volume.fluid;


#### DO

if( phenotype.volume.fluid < 0.0 )
{
phenotype.volume.fluid = 0.0;
}


Here’s the funny thing: the second logic is much clearer, and it took fewer characters, even with extra whitespace for readability!

### Pass by reference where possible.

Passing by reference is a great way to boost performance: we can avoid (1) allocating new temporary memory, (2) copying data into the temporary memory, (3) passing the temporary data to the function, and (4) deallocating the temporary memory once finished.

#### DON’T

double some_function( Cell cell )
{
return = cell.phenotype.volume.total + 3.0;
}
// This copies cell and all its member data!


#### DO

double some_function( Cell& cell )
{
return = cell.phenotype.volume.total + 3.0;
}
// This just accesses the original cell data without recopying it.


### Where possible, pass by reference instead of by pointer.

There is no performance advantage to passing by pointers over passing by reference, but the code is simpler / clearer when you can pass by reference. It makes code easier to write and understand if you can do so. (If nothing else, you save yourself character of typing each time you can replace “->” by “.”!)

#### DON’T

double some_function( Cell* pCell )
{
return = pCell->phenotype.volume.total + 3.0;
}
// Writing and debugging this code can be error-prone.


#### DO

double some_function( Cell& cell )
{
return = cell.phenotype.volume.total + 3.0;
}
// This is much easier to write.


### Be careful with static variables. Be thread safe!

PhysiCell relies heavily on parallelization by OpenMP, and so you should write functions under the assumption that they may be executed many times simultaneously. One easy source of errors is in static variables:

#### DON’T

double some_function( Cell& cell )
{
static double four_pi = 12.566370614359172;
static double output;
output *= output;
output *= four_pi;
return output;
}
// If two instances of some_function are running, they will both modify
// the *same copy* of output


#### DO

double some_function( Cell& cell )
{
static double four_pi = 12.566370614359172;
double output;
output *= output;
output *= four_pi;
return output;
}
// If two instances of some_function are running, they will both modify
// the their own copy of output, but still use the more efficient, once-
// allocated copy of four_pi. This one is safe for OpenMP.


### Use std:: instead of “using namespace std”

PhysiCell uses the BioFVM and PhysiCell namespaces to avoid potential collision with other codes. Other codes using PhysiCell may use functions that collide with the standard namespace. So, we formally use std:: whenever using functions in the standard namespace.

#### DON’T

using namespace std;

cout << "Hi, Mom, I learned to code today!" << endl;
string my_string = "Cheetos are good, but Doritos are better.";
cout << my_string << endl;

vector<double> my_vector;
vector.resize( 3, 0.0 );


#### DO

std::cout << "Hi, Mom, I learned to code today!" << std::endl;
std::string my_string = "Cheetos are good, but Doritos are better.";
std::cout << my_string << std::endl;

std::vector<double> my_vector;
my_vector.resize( 3, 0.0 );


### Camelcase is ugly. Use underscores.

This is purely an aesthetic distinction, but CamelCaseCodeIsUglyAndDoYouUseDNAorDna?

#### DON’T

double MyVariable1;
bool ProteinsInExosomes;
int RNAtranscriptionCount;

void MyFunctionDoesSomething( Cell& ImmuneCell );


#### DO

double my_variable1;
bool proteins_in_exosomes;
int RNA_transcription_count;

void my_function_does_something( Cell& immune_cell );


### Use capital letters to declare a class. Use lowercase for instances.

To help in readability and consistency, declare classes with capital letters (but no camelcase), and use lowercase for instances of those classes.

#### DON’T

class phenotype;

class cell
{
public:
std::vector<double> position;
phenotype Phenotype;
};

class ImmuneCell : public cell
{
public:
std::vector<double> surface_receptors;
};

void do_something( cell& MyCell , ImmuneCell& immuneCell );

cell Cell;
ImmuneCell MyImmune_cell;

do_something( Cell, MyImmune_cell );


#### DO

class Phenotype;

class Cell
{
public:
std::vector<double> position;
Phenotype phenotype;
};

class Immune_Cell : public Cell
{
public:
std::vector<double> surface_receptors;
};

void do_something( Cell& my_cell , Immune_Cell& immune_cell );

Cell cell;
Immune_Cell my_immune_cell;

do_something( cell, my_immune_cell );


## Setting up gcc / OpenMP on OSX (Homebrew edition)

Note: This is part of a series of “how-to” blog posts to help new users and developers of BioFVM and PhysiCell. This guide is for OSX users. Windows users should use this guide instead. A Linux guide is expected soon.

These instructions should get you up and running with a minimal environment for compiling 64-bit C++ projects with OpenMP (e.g., BioFVM and PhysiCell) using gcc. These instructions were tested with OSX 10.11 (El Capitan) and 10.12 (Sierra), but they should work on any reasonably recent version of OSX.

In the end result, you’ll have a compiler and key makefile capabilities. The entire toolchain is free and open source.

Of course, you can use other compilers and more sophisticated integrated desktop environments, but these instructions will get you a good baseline system with support for 64-bit binaries and OpenMP parallelization.

Note 1: OSX / Xcode appears to have gcc out of the box (you can type “gcc” in a Terminal window), but this really just maps back onto Apple’s build of clang. Alas, this will not support OpenMP for parallelization.

Note 2: In this post, we showed how to set up gcc using the popular MacPorts package manager. Because MacPorts builds gcc (and all its dependencies!) from source, it takes a very, very long time. On my 2012 Macbook Air, this step took 16 hours.  This tutorial uses Homebrew to dramatically speed up the process!

Note 3: This is an update over the previous version. It incorporates new information that Xcode command line tools can be installed without the full 4.41 GB download / installation of Xcode. Many thanks to Walter de Back and Tim at the Homebrew project for their help!

### What you’ll need:

• XCode Command Line Tools: These command line tools are needed for Homebrew and related package managers. Installation instructions are now very simple and included below. As of January 18, 2016, this will install Version 2343.
• Homebrew: This is a package manager for OSX, which will let you easily download and install many linux utilities without building them from source. You’ll particularly need it for getting gcc. Installation is a simple command-line script, as detailed below. As of August 2, 2017, this will download Version 1.3.0.
• gcc (from Homebrew): This will be an up-to-date 64-bit version of gcc, with support for OpenMP. As of August 2, 2017, this will download Version 7.1.0.

### Main steps:

#### 1) Install the XCode Command Line Tools

Open a terminal window (Open Launchpad, then “Other”, then “Terminal”), and run:

user$xcode-select --install  A window should pop up asking you to either get Xcode or install. Choose the “install” option to avoid the huge 4+ GB Xcode download. It should only take a few minutes to complete. #### 2) Install Homebrew Open a terminal window (Open Launchpad, then “Other”, then “Terminal”), and run: user$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"  Let the script run, and answer “y” whenever asked. This will not take very long. #### 3) Get, install, and prepare gcc Open a terminal window (see above), and search for gcc, version 7.x or above user$ brew search gcc


You should see a list of packages, including gcc7. (In 2015, this looked like “gcc5”. In 2017, this looks like “gcc@7”.)

user$brew install gcc  This will download whatever dependencies are needed, generally already pre-compiled. The whole process should only take five or ten minutes. Lastly, you need to get the exact name of your compiler. In your terminal window, type g++, and then hit tab twice to see a list. On my system, I see this: Pauls-MBA:~ pmacklin$ g++
g++       g++-7     g++-mp-7


Look for the version of g++ without an “mp” (from MacPorts) in its name. In my case, it’s g++-7. Double-check that you have the right one by checking its version. It should look something like this:

Pauls-MBA:~ pmacklin$g++-7 --version g++-7 (Homebrew GCC 7.1.0) 7.1.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Notice that Homebrew shows up in the information. The correct compiler is g++-7. One last thing: If you don’t update your paths, make will may fail as it continues to combine Apple’s “gcc” toolchain with real gcc. (This seems to happen most often if you installed an older gcc like gcc5 with MacPorts earlier.) You may see errors like this: user$ make
g++-7 -march=core2 -O3 -fomit-frame-pointer -fopenmp -std=c++11 -c BioFVM_vector.cpp
FATAL:/opt/local/bin/../libexec/as/x86_64/as: I don't understand 'm' flag!
make: *** [BIOFVM_vector.o] Error 1


To avoid this, run:

echo export PATH=/usr/local/bin:$PATH >> ~/.bash_profile  Note that you’ll need to open a new Terminal window for this fix to apply. #### 4) Test the compiler ##### Write a basic parallelized program: Open Terminal (see above). You should be in your user profile’s root directory. Make a new subdirectory, enter it, and create a new file: user$ mkdir omp_test
user$cd omp_test user$ nano omp_test.cpp


Then, write your basic OpenMP test:

#include <iostream>
#include <cmath>
#include <vector>
#include <omp.h>
int main( int argc, char* argv[] )
{

double pi = acos( -1.0 );

std::cout << "Allocating memory ..." << std::endl;
std::vector<double> my_vector( 128000000, 0.0 );
std::cout << "Done!" << std::endl << std::endl;

std::cout << "Entering main loop ... " << std::endl;

#pragma omp parallel for
for( int i=0; i < my_vector.size(); i++ )
{
my_vector[i] = exp( -sin( i*i + pi*log(i+1) ) );
}
std::cout << "Done!" << std::endl;

return 0;
}


Save the file (as omp_test.cpp). (In nano, use [Control]+X, Y, and then confirm the choice of filename.)

In the omp_set_num_threads() line above, replace 8 with the maximum number of virtual processors on your CPU. (For a quad-core CPU with hyperthreading, this number is 8. On a hex-core CPU without hyperthreading, this number is 6.) If in doubt, leave it alone for now.

##### Write a makefile:

Next,  create a Makefile to start editing:

user$nano Makefile  Add the following contents: CC := g++-7 # replace this with your correct compiler as identified above ARCH := core2 # Replace this with your CPU architecture. # core2 is pretty safe for most modern machines. CFLAGS := -march=$(ARCH) -O3 -fopenmp -m64 -std=c++11

COMPILE_COMMAND := $(CC)$(CFLAGS)

OUTPUT := my_test

all: omp_test.cpp
$(COMPILE_COMMAND) -o$(OUTPUT) omp_test.cpp

clean:
rm -f *.o $(OUTPUT).*  Go ahead and save this (as Makefile). ([Control]+X, Y, confirm the filename.) Note: The Makefile in PhysiCell (versions > 1.2.1) can use an environment variable to specify an OpenMP-capable g++ compiler. You should go ahead and set that now, e.g., for the bash shell: export PHYSICELL_CPP=g++-7 echo export PHYSICELL_CPP=g++-7 >> ~/.bash_profile  ##### Compile and run the test: Go back to your (still open) command prompt. Compile and run the program: user$ make
user$./my_test  The output should look something like this: Allocating memory ... Done! Entering main loop ... Done!  Note 1: If the make command gives errors like “**** missing separator”, then you need to replace the white space (e.g., one or more spaces) at the start of the “$(COMPILE_COMMAND)” and “rm -f” lines with a single tab character.

Note 2: If the compiler gives an error like “fatal error: ‘omp.h’ not found”, you probably used Apple’s build of clang, which does not include OpenMP support. You’ll need to make sure that you set the environment variable PHYSICELL_CPP as above (for PhysiCell 1.2.2 or later), or specify your compiler on the CC line of your makefile (for PhysiCell 1.2.1 or earlier).

Now, let’s verify that the code is using OpenMP.

Open another Terminal window. While the code is running, run top. Take a look at the performance, particularly CPU usage. While your program is running, you should see CPU usage fairly close to ‘100% user’. (This is a good indication that your code is running the OpenMP parallelization as expected.)

### What’s next?

Download a copy of BioFVM and try out the included examples! Visit BioFVM at MathCancer.org.

2. BioFVM on MathCancer.org: http://BioFVM.MathCancer.org
3. BioFVM on SourceForge: http://BioFVM.sf.net
4. BioFVM Method Paper in BioInformatics: http://dx.doi.org/10.1093/bioinformatics/btv730

## Setting up gcc / OpenMP on OSX (Homebrew edition) (outdated)

Note 1: This is the part of a series of “how-to” blog posts to help new users and developers of BioFVM and PhysiCell. This guide is for OSX users. Windows users should use this guide instead. A Linux guide is expected soon.

Note 2: This tutorial is outdated. Please see this updated version.

These instructions should get you up and running with a minimal environment for compiling 64-bit C++ projects with OpenMP (e.g., BioFVM and PhysiCell) using gcc. These instructions were tested with OSX 10.11 (El Capitan), but they should work on any reasonably recent version of OSX.

In the end result, you’ll have a compiler and key makefile capabilities. The entire toolchain is free and open source.

Of course, you can use other compilers and more sophisticated integrated desktop environments, but these instructions will get you a good baseline system with support for 64-bit binaries and OpenMP parallelization.

Note 3: OSX / Xcode appears to have gcc out of the box (you can type “gcc” in a Terminal window), but this really just maps back onto Apple’s build of clang. Alas, this will not support OpenMP for parallelization.

Note 4: Yesterday in this post, we showed how to set up gcc using the popular MacPorts package manager. Because MacPorts builds gcc (and all its dependencies!) from source, it takes a very, very long time. On my 2012 Macbook Air, this step took 16 hours.  This tutorial uses Homebrew to dramatically speed up the process!

### What you’ll need:

• XCode: This includes command line development tools. Evidently, it is required for both Homebrew and its competitors (e.g., MacPorts). Download the latest version in the App Store. (Search for xcode.) As of January 15, 2016, the App Store will install Version 7.2. Please note that this is a 4.41 GB download!
• Homebrew: This is a package manager for OSX, which will let you easily download and install many linux utilities without building them from source. You’ll particularly need it for getting gcc. Installation is a simple command-line script, as detailed below. As of January 17, 2016, this will download Version 0.9.5.
• gcc5 (from Homebrew): This will be an up-to-date 64-bit version of gcc, with support for OpenMP. As of January 17, 2016, this will download Version 5.2.0.

### Main steps:

As mentioned above, open the App Store, search for Xcode, and start the download / install. Go ahead and grab a coffee while it’s downloading and installing 4+ GB. Once it has installed, open Xcode, agree to the license, and let it install whatever components it needs.

Now, you need to get the command line tools. Go to the Xcode menu, select “Open Developer Tool”, and choose “More Developer Tools …”. This will open up a site in Safari and prompt you to log in.

Sign on with your AppleID, agree to yet more licensing terms, and then search for “command line tools” for your version of Xcode and OSX. (In my case, this is OSX 10.11 with Xcode 7.2) Click the + next to the correct version, and then the link for the dmg file. (Command_Line_Tools_OS_X_10.11_for_Xcode_7.2.dmg).

Double-click the dmg file. Double-click pkg file it contains. Click “continue”, “OK”, and “agree” as much as it takes to install. Once done, go ahead and exit the installer and close the dmg file.

#### 2) Install Homebrew

Open a terminal window (Open Launchpad, then “Other”, then “Terminal”), and run:

> ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"  Let the script run, and answer “y” whenever asked. This will not take very long. #### 3) Get, install, and prepare gcc Open a terminal window (see above), and search for gcc, version 5.x or above > brew search gcc5  You should see a list of packages, including gcc5. Take a note of what is found. (In my case, it found homebrew/versions/gcc5.) Then, download and install gcc5: > brew install homebrew/versions/gcc5  This will download whatever dependencies are needed, generally already pre-compiled. The whole process should only take five or ten minutes. Lastly, you need to get the exact name of your compiler. In your terminal window, type g++, and then hit tab twice to see a list. On my system, I see this: Pauls-MBA:~ pmacklin$ g++
g++       g++-5       g++-mp-5


Look for the version of g++ without an “mp” (for MacPorts) in its name. In my case, it’s g++-5. Double-check that you have the right one by checking its version. It should look something like this:

Pauls-MBA:~ pmacklin$g++-5 --version g++-5 (Homebrew gcc5 5.2.0) 5.2.0 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Notice that Homebrew shows up in the information. The correct compiler is g++-5. #### 5) Test the compiler ##### Write a basic parallelized program: Open Terminal (see above). You should be in your user profile’s root directory. Make a new subdirectory, enter it, and create a new file: > mkdir omp_test > cd omp_test > nano omp_test.cpp  Then, write your basic OpenMP test: #include <iostream> #include <cmath> #include <vector> #include <omp.h> int main( int argc, char* argv[] ) { omp_set_num_threads( 8 ); double pi = acos( -1.0 ); std::cout << "Allocating memory ..." << std::endl; std::vector<double> my_vector( 128000000, 0.0 ); std::cout << "Done!" << std::endl << std::endl; std::cout << "Entering main loop ... " << std::endl; #pragma omp parallel for for( int i=0; i < my_vector.size(); i++ ) { my_vector[i] = exp( -sin( i*i + pi*log(i+1) ) ); } std::cout << "Done!" << std::endl; return 0; }  Save the file (as omp_test.cpp). (In nano, use [Control]+X, Y, and then confirm the choice of filename.) In the omp_set_num_threads() line above, replace 8 with the maximum number of virtual processors on your CPU. (For a quad-core CPU with hyperthreading, this number is 8. On a hex-core CPU without hyperthreading, this number is 6.) If in doubt, leave it alone for now. ##### Write a makefile: Next, create a Makefile to start editing: > nano Makefile  Add the following contents: CC := g++-5 # replace this with your correct compiler as identified above ARCH := core2 # Replace this with your CPU architecture. # core2 is pretty safe for most modern machines. CFLAGS := -march=$(ARCH) -O3 -fopenmp -m64 -std=c++11

COMPILE_COMMAND := $(CC)$(CFLAGS)

OUTPUT := my_test

all: omp_test.cpp
$(COMPILE_COMMAND) -o$(OUTPUT) omp_test.cpp

clean:
rm -f *.o $(OUTPUT).*  Go ahead and save this (as Makefile). ([Control]-X, Y, confirm the filename.) ##### Compile and run the test: Go back to your (still open) command prompt. Compile and run the program: > make > ./my_test  The output should look something like this: Allocating memory ... Done! Entering main loop ... Done!  Note 1: If the make command gives errors like “**** missing separator”, then you need to replace the white space (e.g., one or more spaces) at the start of the “$(COMPILE_COMMAND)” and “rm -f” lines with a single tab character.

Note 2: If the compiler gives an error like “fatal error: ‘omp.h’ not found”, you probably used Apple’s build of clang, which does not include OpenMP support. You’ll need to make sure that you specify your compiler on the CC line of your makefile.

Now, let’s verify that the code is using OpenMP.

Open another Terminal window. While the code is running, run top. Take a look at the performance, particularly CPU usage. While your program is running, you should see CPU usage fairly close to ‘100% user’. (This is a good indication that your code is running the OpenMP parallelization as expected.)

### What’s next?

Download a copy of BioFVM and try out the included examples! Visit BioFVM at MathCancer.org.

2. BioFVM on MathCancer.org: http://BioFVM.MathCancer.org
3. BioFVM on SourceForge: http://BioFVM.sf.net
4. BioFVM Method Paper in BioInformatics: http://dx.doi.org/10.1093/bioinformatics/btv730

## Setting up gcc / OpenMP on OSX (MacPorts edition)

Note: This is the part of a series of “how-to” blog posts to help new users and developers of BioFVM and PhysiCell. This guide is for OSX users. Windows users should use this guide instead. A Linux guide is expected soon.

These instructions should get you up and running with a minimal environment for compiling 64-bit C++ projects with OpenMP (e.g., BioFVM and PhysiCell) using gcc. These instructions were tested with OSX 10.11 (El Capitan), but they should work on any reasonably recent version of OSX.

In the end result, you’ll have a compiler and key makefile capabilities. The entire toolchain is free and open source.

Of course, you can use other compilers and more sophisticated integrated desktop environments, but these instructions will get you a good baseline system with support for 64-bit binaries and OpenMP parallelization.

Note 1: OSX / Xcode appears to have gcc out of the box (you can type “gcc” in a Terminal window), but this really just maps back onto Apple’s build of clang. Alas, this will not support OpenMP for parallelization.

Note 2: This process is somewhat painful because MacPorts compiles everything from source, rather than using pre-compiled binaries. This tutorial uses Homebrew: a newer package manager that uses pre-compiled binaries to dramatically speed up the process. I highly recommend using the Homebrew version of this tutorial.

### What you’ll need:

1. XCode: This includes command line development tools. Evidently, it is required for both Macports and its competitors (e.g., Homebrew). Download the latest version in the App Store. (Search for xcode.) As of January 15, 2016, the App Store will install Version 7.2. Please note that this is a 4.41 GB download!
2. MacPorts: This is a package manager for OSX, which will let you easily download, build and install many linux utilities. You’ll particularly need it for getting gcc. Download the latest installer (MacPorts-2.3.4-10.11-ElCapitan.pkg) here. As of August 2, 2017, this will download Version 2.4.1.
3. gcc7 (from MacPorts): This will be an up-to-date 64-bit version of gcc, with support for OpenMP. As of August 2, 2017, this will download Version 7.1.1.

### Main steps:

As mentioned above, open the App Store, search for Xcode, and start the download / install. Go ahead and grab a coffee while it’s downloading and installing 4+ GB. Once it has installed, open Xcode, agree to the license, and let it install whatever components it needs.

Now, you need to get the command line tools. Go to the Xcode menu, select “Open Developer Tool”, and choose “More Developer Tools …”. This will open up a site in Safari and prompt you to log in.

Sign on with your AppleID, agree to yet more licensing terms, and then search for “command line tools” for your version of Xcode and OSX. (In my case, this is OSX 10.11 with Xcode 7.2) Click the + next to the correct version, and then the link for the dmg file. (Command_Line_Tools_OS_X_10.11_for_Xcode_7.2.dmg).

Double-click the dmg file. Double-click pkg file it contains. Click “continue”, “OK”, and “agree” as much as it takes to install. Once done, go ahead and exit the installer and close the dmg file.

#### 2) Install Macports

Double-click the MacPorts pkg file you downloaded above. OSX may complain with a message like this:

“MacPorts-2.4.1-10.11-ElCapitan.pkg” can’t be opened because it is from an unidentified developer.

If so, follow the directions here.

Leave all the default choices as they are in the installer. Click OK a bunch of times. The package scripts might take awhile.

Open a terminal window (Open Launchpad, then “Other”, then “Terminal”), and run:

sudo port -v selfupdate


to make sure that everything is up-to-date.

#### 3) Get, install, and prepare gcc

Open a terminal window (see above), and search for gcc, version 7.x or above

port search gcc7


You should see a list of packages, including gcc7.

sudo port install gcc7


You should see a list of packages, including gcc7.

This will download, build, and install any dependencies necessary for gcc7, including llvm and many, many other things. This takes even longer than the 4.4 GB download of Xcode. Go get dinner and a coffee. You may well need to let this run overnight. (On my 2012 Macbook Air, it required 16 hours to fully build gcc7 and its dependencies in a prior tutorial. We’ll discuss this point further below.)

Lastly, you need to get the exact name of your compiler. In your terminal window, type g++, and then hit tab twice to see a list. On my system, I see this:

Pauls-MBA:~ pmacklin$g++ g++ g++-mp-7  Look for the version of g++ with an “mp” in its name. In my case, it’s g++-mp-7. Double-check that you have the right one by checking its version. It should look something like this: Pauls-MBA:~ pmacklin$ g++-mp-7 --version

g++-mp-7 (MacPorts gcc7 7-20170622_0) 7.1.1 20170622
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO warranty; not even
for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Notice that MacPorts shows up in the information. The correct compiler is g++-mp-7.

#### 4) Test the compiler

##### Write a basic parallelized program:

Open Terminal (see above). You should be in your user profile’s root directory. Make a new subdirectory, enter it, and create a new file:

mkdir omp_test
cd omp_test
nano omp_test.cpp


Then, write your basic OpenMP test:

#include <iostream>
#include <cmath>
#include <vector>
#include <omp.h>

int main( int argc, char* argv[] )
{

double pi = acos( -1.0 );

std::cout << "Allocating memory ..." << std::endl;
std::vector<double> my_vector( 128000000, 0.0 );
std::cout << "Done!" << std::endl << std::endl;

std::cout << "Entering main loop ... " << std::endl;

#pragma omp parallel for
for( int i=0; i < my_vector.size(); i++ )
{
my_vector[i] = exp( -sin( i*i + pi*log(i+1) ) );
}
std::cout << "Done!" << std::endl;

return 0;
}


Save the file (as omp_test.cpp). (In nano, use [Control]-X, Y, and then confirm the choice of filename.)

In the omp_set_num_threads() line above, replace 8 with the maximum number of virtual processors on your CPU. (For a quad-core CPU with hyperthreading, this number is 8. On a hex-core CPU without hyperthreading, this number is 6.) If in doubt, leave it alone for now, or set it at a relatively safe value of 4.

##### Write a makefile:

Next,  create a Makefile to start editing:

nano Makefile


CC := g++-mp-7
# replace this with your correct compiler as identified above

ARCH := core2 # Replace this with your CPU architecture.
# core2 is pretty safe for most modern machines.

CFLAGS := -march=$(ARCH) -O3 -fopenmp -m64 -std=c++11 COMPILE_COMMAND :=$(CC) $(CFLAGS) OUTPUT := my_test all: omp_test.cpp$(COMPILE_COMMAND) -o $(OUTPUT) omp_test.cpp clean: rm -f *.o$(OUTPUT).*


Go ahead and save this (as Makefile). ([Control]+X, Y, confirm the filename.)

Note: The Makefile in PhysiCell (versions > 1.2.1) can use an environment variable to specify an OpenMP-capable g++ compiler. You should go ahead and set that now, e.g., for the bash shell:

export PHYSICELL_CPP=g++-mp-7
echo export PHYSICELL_CPP=g++-mp-7 >> ~/.bash_profile

##### Compile and run the test:

Go back to your (still open) command prompt. Compile and run the program:

make
./my_test


The output should look something like this:

Allocating memory ...
Done!
Entering main loop ...
Done!


Note 1: If the make command gives errors like “**** missing separator”, then you need to replace the white space (e.g., one or more spaces) at the start of the “$(COMPILE_COMMAND)” and “rm -f” lines with a single tab character. Note 2: If the compiler gives an error like “fatal error: ‘omp.h’ not found”, you probably used Apple’s build of clang, which does not include OpenMP support. You’ll need to make sure that you set the environment variable PHYSICELL_CPP as above (for PhysiCell 1.2.2 or later), or specify your compiler on the CC line of your makefile. Now, let’s verify that the code is using OpenMP. Open another Terminal window. While the code is running, run top. Take a look at the performance, particularly CPU usage. While your program is running, you should see CPU usage fairly close to ‘100% user’. (This is a good indication that your code is running the OpenMP parallelization as expected.) ### MacPorts and Pain MacPorts builds all the tools from source. While this ensures that you get very up-to-date binaries, it is very, very slow! However, all hope is not lost. It turns out that Homebrew will install pre-compiled binaries, so the 16-hour process of installing gcc is reduced to about 5-10 minutes. Check back tomorrow for a follow-up tutorial on how to use Homebrew to set up gcc. ### What’s next? Download a copy of BioFVM and try out the included examples! Visit BioFVM at MathCancer.org. 1. BioFVM announcement on this blog: [click here] 2. BioFVM on MathCancer.org: http://BioFVM.MathCancer.org 3. BioFVM on SourceForge: http://BioFVM.sf.net 4. BioFVM Method Paper in BioInformatics: http://dx.doi.org/10.1093/bioinformatics/btv730 5. BioFVM tutorials: [click here] Share this: ## Setting up a 64-bit gcc/OpenMP environment on Windows Note: This is the part of a series of “how-to” blog posts to help new users and developers of BioFVM and PhysiCell. This guide is for Windows users. OSX users should use this guide for Homebrew (preferred method) or this guide for MacPorts (much slower but reliable). A Linux guide is expected soon. These instructions should get you up and running with a minimal environment for compiling 64-bit C++ projects with OpenMP (e.g., BioFVM and PhysiCell) using a 64-bit Windows port of gcc. These instructions should work for any modern Windows installation, say Windows 7 or above. This tutorial assumes you have a 64-bit CPU running on a 64-bit operating system. In the end result, you’ll have a compiler, key makefile capabilities, and a decent text editor. The entire toolchain is free and open source. Of course, you can use other compilers and more sophisticated integrated desktop environments, but these instructions will get you a good baseline system with support for 64-bit binaries and OpenMP parallelization. ### What you’ll need: 1. MinGW-w64 compiler: This is a native port of the venerable gcc compiler for windows, with support for 64-bit executables. Download the latest installer (mingw-w64-install.exe) here. As of January 8, 2016, this installer will download gcc 5.3.0. 2. MSYS tools: This gets you some of the common command-line utilities from Linux, Unix, and BSD systems (make, touch, etc.). Download the latest installer (mingw-get-setup.exe) here. 3. Notepad++ text editor: This is a full-featured text editor for Windows, including syntax highlighting, easy commenting, tabbed editing, etc. Download the latest version here. As of January 8, 2016, this will download Version 6.8.8. ### Main steps: #### 1) Install the compiler Run the mingw-w64-install.exe. When asked, select: Version: 5.3.0 (or later) Architecture: x86_64 Threads: win32 (While I have tested posix, the native threading should be faster.) Exception: seh (While sjlj works and should be more compatible with various GNU tools, the native SEH should be faster.) Build version: 0 (or the default) Leave the destination folder wherever the installer wants to put it. In my case, it is: c:\Program Files\mingw-w64\x86_64-5.3.0-win32-seh-rt_v4_rev0  Let MinGW-w64 download and install whatever it needs. #### 2) Install the MSYS tools Run mingw-get-setup.exe. Leave the default installation directory and any other defaults on the initial screen. Click “continue” and let it download what it needs to get started. (a bunch of XML files, for the most part.) Click “Continue” when it’s done. This will open up a new package manager. Our goal here is just to grab MSYS, rather than the full (but merely 32-bit) compiler. Scroll through and select (“mark for installation”) the following: • mingw-developer-toolkit. (Note: This should automatically select msys-base.) Next, click “Apply Changes” in the “Installation” menu. When prompted, click “Apply.” Let the package manager download and install what it needs (on the order of 95 packages). Go ahead and close things once the installation is done, including the package manager. #### 3) Install the text editor Run the Notepad++ installer. You can stick with the defaults. #### 4) Add these tools to your system path Adding the compiler, text editor, and MSYS tools to your path helps you to run make files from the compiler. First, get the path of your compiler: 1. Open Windows Explorer ( [Windows]+E ) 2. Browse through C:\, then Program Files, mingw-w64, then a messy path name corresponding to our installation choices (in my case, x86_64-5.3.0-win32-seh_rt_v4-rev0), then mingw64, and finally bin. 3. Open notepad ([Windows]+R , notepad), 4. Go to the address bar of Explorer and copy ([Control]+C) the full path of the directory you just browsed to. 5. Paste it into notepad ([Control]+V), preceded and followed by a semicolon, and a final slash if it isn’t there. In my case: ;c:\Program Files\mingw-w64\x86_64-5.3.0-win32-seh-rt_v4_rev0\mingw64\bin\;  Then, get the path to Notepad++. 1. Go back to Explorer, and choose “This PC” or “My Computer” from the left column. 2. Browse through C:\, then Program Files (x86), then Notepad++. 3. Copy the path from the Explorer address bar. 4. Paste this path just after the final semicolon in notepad, followed by a backslash and a semicolon. In my case: ;c:\Program Files\mingw-w64\x86_64-5.3.0-win32-seh-rt_v4_rev0\mingw64\bin\;c:\Program Files (x86)\Notepad++\;  Then, get the path for MSYS: 1. Go back to Explorer, and choose “This PC” or “My Computer” from the left column. 2. Browse through C:\, then MinGW, then msys, then 1.0, and finally bin. 3. Copy the path from the Explorer address bar. 4. Paste this path just after the final semicolon in notepad, followed by a backslash and a semicolon. In my case: ;c:\Program Files\mingw-w64\x86_64-5.3.0-win32-seh-rt_v4_rev0\mingw64\bin\;c:\Program Files (x86)\Notepad++\;C:\MinGW\msys\1.0\bin\;  Lastly, add these paths to the system path: 1. Go the Start Menu, the right-click “This PC” or “My Computer”, and chose “Properties.” 2. Click on “Advanced system settings” 3. Click on “Environment Variables…” in the “Advanced” tab 4. Scroll through the “System Variables” below until you find Path. 5. Select “Path”, then click “Edit…” 6. At the very end of “Variable Value”, paste what you made in Notepad in the prior steps. Make sure to paste at the end of the existing value, rather than overwriting it! 7. Hit OK, OK, and OK to completely exit the “Advanced system settings.” #### 5) Test the compiler ##### Write a basic parallelized program: Enter a command prompt ( [windows]+R, then cmd ). You should be in your user profile’s root directory. Make a new subdirectory, enter it, and create a new file: mkdir omp_test cd omp_test notepad++ omp_test.cpp  Then, write your basic OpenMP test: #include <iostream> #include <cmath> #include <vector> #include <omp.h> int main( int argc, char* argv[] ) { omp_set_num_threads( 8 ); double pi = acos( -1.0 ); std::cout << "Allocating memory ..." << std::endl; std::vector<double> my_vector( 128000000, 0.0 ); std::cout << "Done!" << std::endl << std::endl; std::cout << "Entering main loop ... " << std::endl; #pragma omp parallel for for( int i=0; i < my_vector.size(); i++ ) { my_vector[i] = exp( -sin( i*i + pi*log(i+1) ) ); } std::cout << "Done!" << std::endl; return 0; }  Save the file (as omp_test.cpp). In the omp_set_num_threads() line above, replace 8 with the maximum number of virtual processors on your CPU. (For a quad-core CPU with hyperthreading, this number is 8. On a hex-core CPU without hyperthreading, this number is 6.) If in doubt, leave it alone for now. ##### Write a makefile: Next, open up a new tab in Notepad++, and save it as “Makefile”. Add the following contents: CC := g++ ARCH := core2 # Replace this your CPU architecture. # core2 is pretty safe for most modern machines. CFLAGS := -march=$(ARCH) -O3 -fopenmp -m64 -std=c++11

COMPILE_COMMAND := $(CC)$(CFLAGS)

OUTPUT := my_test

all: omp_test.cpp
$(COMPILE_COMMAND) -o$(OUTPUT) omp_test.cpp

clean:

### What’s next?

Download a copy of BioFVM and try out the included examples! Visit BioFVM at MathCancer.org.