CellSystem: A biological simulation framework.¶
CellSystem¶
An agent-based framework for the simulation of biological cell systems.
This was created to simulate cancer growth, taking into account nutrients and cell migration while allowing to track mutations, cell division and cell position history to study tumour phylogeny reconstruction algorithms.


Example¶
A use case integrated in the repository:
>>> from cellsystem import *
# The cell system will simulate cell growth
# while tracking the steps in that process.
>>> system = CellSystem(grid_shape=(100, 100))
# Initialize the first cell
# in the middle of the grid
>>> system.seed()
New cell 0 added @ (50, 50)
# Take 35 steps forward in time
>>> system.run(steps=30)
Cell no. 0 mutating @ site (50, 50) (father None)
Initial mutations: []
Initial genome: AAAAAAAAAA
Final mutations: [(4, 'G')]
Final genome: AAAAGAAAAA
Cell no. 0 dividing @ (50, 50)
New cells: 1 @ (49, 50) and 2 @ (50, 51)
Cell no. 2 dividing @ (50, 51)
New cells: 3 @ (51, 52) and 4 @ (51, 52)
Cell no. 4 mutating @ site (51, 52) (father 2)
Initial mutations: [(4, 'G')]
Initial genome: AAAAGAAAAA
Final mutations: [(4, 'G'), (7, 'A')]
Final genome: AAAAGAAAAA
Cell no. 1 death @ site (49, 50) (father None)
Cell no. 3 death @ site (51, 52) (father 2)
Cell no. 4 mutating @ site (51, 52) (father 2)
Initial mutations: [(4, 'G'), (7, 'A')]
Initial genome: AAAAGAAAAA
Final mutations: [(4, 'G'), (7, 'A'), (2, 'T')]
Final genome: AATAGAAAAA
Cell no. 4 migrating from site (51, 52) (father 2)
New site: (50, 52)
...
...
...
# Prepare to explore the simulation logs
>>> history = system['log']
# First, let's see the cells' evolution in time and space!
>>> history.worldlines().show()
# Remove the cells that died somewhere along the way
>>> history.worldlines(prune_death=True).show()


>>> tree_style = {'show_leaf_name' : True,
... 'mode' : 'c', # Circular
... 'arc_start' : -135, # Degrees
... 'arc_span' : 270 } # Degrees also
# Lookup the tree formed by cellular division
>>> history.ancestry().show(styling=tree_style)
# Now, remove cells that are no longer alive
>>> history.ancestry(prune_death=True).show(styling=tree_style)


# Now, check out the tree formed by the mutations
>>> history.mutations().show(styling=tree_style)
# Remove genomes with no living representatives.
>>> history.mutations(prune_death=True).show(styling=tree_style)


For more examples and usage, please refer to the [Wiki](wikigoeshere.com).
Meta¶
Author: Ad115 - Github – a.garcia230395@gmail.com
Distributed under the MIT license. See LICENSE for more information.
Warning: The project is still in alpha stage, so the API is just stabilizing and may change in the near future. This also means that if you want to contribute, now is the right moment to make important change suggestions ;D
Contributing¶
- Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
- Fork the repository on GitHub to start making your changes to a feature branch, derived from the master branch.
- Write a test which shows that the bug was fixed or that the feature works as expected.
- Send a pull request and bug the maintainer until it gets merged and published.
cellsystem¶
cellsystem package¶
Subpackages¶
cellsystem.logging package¶
Subpackages¶
-
class
cellsystem.logging.core.multi.
MultiLog
[source]¶ Bases:
cellsystem.logging.core.log.Log
An aggregate of logs.
-
class
cellsystem.logging.core.weak.
WeakLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.log.Log
Ignore silently calls to not implemented log methods.
The fundamental interfaces for logging.
-
class
cellsystem.logging.core.
Log
(*args, **kwargs)[source]¶ Bases:
object
A logger class that registers certain actions.
-
class
cellsystem.logging.core.
WeakLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.log.Log
Ignore silently calls to not implemented log methods.
-
class
cellsystem.logging.core.
MultiLog
[source]¶ Bases:
cellsystem.logging.core.log.Log
An aggregate of logs.
Submodules¶
cellsystem.logging.full module¶
-
class
cellsystem.logging.full.
FullLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.multi.MultiLog
A log that records geometric information, mutations, ancestry and prints the actions to the screen.
Each part can be accesed with:
log[{{logname}}]
where {{logname}} can be one of: ‘geometry’, ‘mutations’, ‘ancestry’ or ‘printer’.
also, each log can be (de)activated with:
# Deactivate log log[{{logname}}].silence() # Rectivate log log[{{logname}}].activate()
cellsystem.logging.geometric module¶
This module defines functionality for following the geometric evolution of the cell blob through time.
The classes GeometricLog and WorldLines are defined here.
-
class
cellsystem.logging.geometric.
GeometricLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.weak.WeakLog
Registers the geometric positions of the cells.
cellsystem.logging.simple module¶
cellsystem.logging.treelogs module¶
-
class
cellsystem.logging.treelogs.
AncestryLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.treelogs.TreeLog
A tree log that maintains a “family tree”.
Each leaf represents a cell. When that cell divides, the leaf branches into leaves representing the daughters.
-
class
cellsystem.logging.treelogs.
MutationsLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.treelogs.TreeLog
A tree log that maintains a record of genome branching events.
Each leaf represents a genome that may be present in one or more cells. When one of those cells mutates, the new genome is added as a child of that leaf.
-
class
cellsystem.logging.treelogs.
TreeLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.weak.WeakLog
Base class for logs that grow trees.
-
alive_nodes
¶
-
Module contents¶
Logging classes.
Classes related to the recording of the simulation progress, analysis and history.
-
class
cellsystem.logging.
FullLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.multi.MultiLog
A log that records geometric information, mutations, ancestry and prints the actions to the screen.
Each part can be accesed with:
log[{{logname}}]
where {{logname}} can be one of: ‘geometry’, ‘mutations’, ‘ancestry’ or ‘printer’.
also, each log can be (de)activated with:
# Deactivate log log[{{logname}}].silence() # Rectivate log log[{{logname}}].activate()
-
class
cellsystem.logging.
PrinterLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.log.Log
Simple logger that limits to print the action.
-
class
cellsystem.logging.
MutationsLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.treelogs.TreeLog
A tree log that maintains a record of genome branching events.
Each leaf represents a genome that may be present in one or more cells. When one of those cells mutates, the new genome is added as a child of that leaf.
-
class
cellsystem.logging.
AncestryLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.treelogs.TreeLog
A tree log that maintains a “family tree”.
Each leaf represents a cell. When that cell divides, the leaf branches into leaves representing the daughters.
-
class
cellsystem.logging.
GeometricLog
(*args, **kwargs)[source]¶ Bases:
cellsystem.logging.core.weak.WeakLog
Registers the geometric positions of the cells.
cellsystem.simulation package¶
Submodules¶
cellsystem.simulation.cells module¶
Structures representing the biological entities.
-
class
cellsystem.simulation.cells.
Cell
(lineage, index)[source]¶ Bases:
object
A single cell.
It acts according to it’s state, and the states of nearby cells and sites.
-
+ Index
A label that identifies it among others in the same lineage.
-
+ Father
The index (lineage label) of it’s father.
-
+ CellLine
The lineage this cell belongs to.
-
+ Site
The place in the grid this cell inhabits in.
-
+ Mutations
The mutations in this cell relative to the cell lineage’s reference
-
add_mutation
(position, mutated)[source]¶ Add a mutation to the cell in the given position of the genome.
Note: The genome may not represent a nucleotide sequence, so these mutations may not represent SNPs.
-
ancestral_genome
¶ Ancestral genome of the cell lineage.
-
coordinates
¶ Coordinates of the site that the cell inhabits.
-
genome
¶ Genome of the cell.
It is assembled from the cell’s ancestral genome and it’s mutations.
-
genome_alphabet
¶ Genome alphabet of the cell line.
The set of characters a genome is composed of. (The genome characters may really represent genes, aminoacids, etc…)
-
initialize
(site=None, father=None, mutations=None)[source]¶ Initialize grid site, mutations and father.
-
mutations
¶ Record of the mutations the cell has had.
The mutations are relative to the ancestral genome.
-
-
class
cellsystem.simulation.cells.
CellLine
(*args, genome=None, genome_alphabet=None, recycle_dead=True, **kwargs)[source]¶ Bases:
object
Handles the specimens of a specific cell lineage.
A cell lineage is a group of cells that have a common ancestor, we represent the common ancestor by it’s ancestral genome. This structure is in charge of holding this ancestral code and managing the cells creating new cells when needed and cleaning up the dead ones.
- Atributes:
- Ancestral genome: A string-like object.
- Cells: The cells inherited from this cell line.
- Alive/Dead cells.
- Current cell index: Each cell has a unique index. This is the
- index to place in the next cell to be born.
-
add_behaviors
(behaviors, weights=None)[source]¶ Add the behaviors defining the cells from this cell line.
Params:
- behaviors (list of callables):
- The list of actions that the cells in this lineage will be able to perform.
- weights (optional list of numeric values):
- The list of relative weights for selecting each action. The bigger the weight of an action relative to the weights of the others, the more likely is that that action will be selected by the cell at each step. default is all actions have the same weights.
Raises: ValueError
– If the weights are not of the same length as the behaviors.
-
handle_death
(dying)[source]¶ Process a dying cell.
This means removing from the alive cells and adding to the dead ones, maybe to recycle it when another is born.
-
sample
(all=False, n=1)[source]¶ Take a sample of alive cells.
Parameters: - all – If True, return all alive cells, else, return a sample of size n.
- n – The size of the sample. If 1, return the cell without a container.
-
total_cells
¶
-
cellsystem.simulation.cells.
behavior
(actionname, actionfn=None, probability=None, prepare=True)[source]¶ Assemble a cell behavior.
Adds logging and asociates a name and a probability function to the raw action function. Allows to specify if the logging of the action requires to prepare the log.
Can be used as a function decorator or as a normal function.
cellsystem.simulation.logging module¶
cellsystem.simulation.system module¶
System-related classes.
This module defines a general system that can be used as the base of a computation graph.
A system is composed of entities and interactions btw them, it coordinates all processes.
-
class
cellsystem.simulation.system.
Entity
[source]¶ Bases:
object
An entity is something that resides in the system.
It processes information according to it’s internal state and the information flowing through the links it shares with other entities.
- An entity registers the following methods:
- process(time)
-
class
cellsystem.simulation.system.
Interaction
(entities, effect)[source]¶ Bases:
object
A structure representing flow of information btw entities.
-
class
cellsystem.simulation.system.
Process
(entities, effects)¶ Bases:
tuple
-
effects
¶ Alias for field number 1
-
entities
¶ Alias for field number 0
-
-
class
cellsystem.simulation.system.
System
(*args, **kwargs)[source]¶ Bases:
object
The global system and event dispatcher.
Aware of the passage of time (steps). A system is composed of entities and interactions between them, at each time step, the system triggers the proceses associated with them.
-
add_entity
(entity, name, procesable=True, inithook=None)[source]¶ Add an entity to the graph.
If procesable, the entity.process(time) method is called on each time step.
Inithooks are callables called at initialization.
-
add_interaction_to
(container, effect, entitynames)[source]¶ Add an interaction btw named entities to a dict-like container.
-
cellsystem.simulation.world module¶
Classes associated with physical space where entities live and interact.
-
class
cellsystem.simulation.world.
Site
(world, coordinates)[source]¶ Bases:
object
A unit of space.
Cells inhabitate in these spaces and interact with their neighborhood.
- Is aware of:
- World: The world it forms a part of.
- Coordinates <i,j>: Coordinates in the matrix.
- Guests: <List>: The guests currently inhabiting this site.
-
coordinates
¶ Getter for the site’s coordinates.
-
class
cellsystem.simulation.world.
World
(shape=(10, 10), wrap=<function toroidal_wrap>)[source]¶ Bases:
object
The space in which cells inhabit.
It represents physical space and enforces rules and properties like distance and closeness.
- A world is aware of:
- Grid: The sites the action develops in.
- Neighborhood: How many and which sites may directly influence or
- be influenced by another.
-
middle
¶ Get the site at the middle of the world.
-
cellsystem.simulation.world.
toroidal_wrap
(grid, coord)[source]¶ Return the coordinates wrapped on the grid dimensions.
-
cellsystem.simulation.world.
wrap
(n, maxValue)[source]¶ Auxiliary function to wrap an integer on maxValue.
Examples
>>> # For positives: wrap(n, maxValue) = n % maxValue >>> [ wrap(i,3) for i in range(9) ] [0, 1, 2, 0, 1, 2, 0, 1, 2]
>>> # For negatives, the pattern is continued in a natural way >>> for i in range(-5, 5+1): print(f'{i} : {wrap(i, 3)}') ... -3 : 0 -2 : 1 -1 : 2 0 : 0 1 : 1 2 : 2
Module contents¶
-
class
cellsystem.simulation.
System
(*args, **kwargs)[source]¶ Bases:
object
The global system and event dispatcher.
Aware of the passage of time (steps). A system is composed of entities and interactions between them, at each time step, the system triggers the proceses associated with them.
-
add_entity
(entity, name, procesable=True, inithook=None)[source]¶ Add an entity to the graph.
If procesable, the entity.process(time) method is called on each time step.
Inithooks are callables called at initialization.
-
add_interaction_to
(container, effect, entitynames)[source]¶ Add an interaction btw named entities to a dict-like container.
-
-
class
cellsystem.simulation.
CellLine
(*args, genome=None, genome_alphabet=None, recycle_dead=True, **kwargs)[source]¶ Bases:
object
Handles the specimens of a specific cell lineage.
A cell lineage is a group of cells that have a common ancestor, we represent the common ancestor by it’s ancestral genome. This structure is in charge of holding this ancestral code and managing the cells creating new cells when needed and cleaning up the dead ones.
- Atributes:
- Ancestral genome: A string-like object.
- Cells: The cells inherited from this cell line.
- Alive/Dead cells.
- Current cell index: Each cell has a unique index. This is the
- index to place in the next cell to be born.
-
add_behaviors
(behaviors, weights=None)[source]¶ Add the behaviors defining the cells from this cell line.
Params:
- behaviors (list of callables):
- The list of actions that the cells in this lineage will be able to perform.
- weights (optional list of numeric values):
- The list of relative weights for selecting each action. The bigger the weight of an action relative to the weights of the others, the more likely is that that action will be selected by the cell at each step. default is all actions have the same weights.
Raises: ValueError
– If the weights are not of the same length as the behaviors.
-
handle_death
(dying)[source]¶ Process a dying cell.
This means removing from the alive cells and adding to the dead ones, maybe to recycle it when another is born.
-
sample
(all=False, n=1)[source]¶ Take a sample of alive cells.
Parameters: - all – If True, return all alive cells, else, return a sample of size n.
- n – The size of the sample. If 1, return the cell without a container.
-
total_cells
¶
-
class
cellsystem.simulation.
Action
(action, probability=None, name=None)[source]¶ Bases:
object
Objects of this class represent actions with an associated probability.
-
class
cellsystem.simulation.
World
(shape=(10, 10), wrap=<function toroidal_wrap>)[source]¶ Bases:
object
The space in which cells inhabit.
It represents physical space and enforces rules and properties like distance and closeness.
- A world is aware of:
- Grid: The sites the action develops in.
- Neighborhood: How many and which sites may directly influence or
- be influenced by another.
-
middle
¶ Get the site at the middle of the world.
-
cellsystem.simulation.
behavior
(actionname, actionfn=None, probability=None, prepare=True)[source]¶ Assemble a cell behavior.
Adds logging and asociates a name and a probability function to the raw action function. Allows to specify if the logging of the action requires to prepare the log.
Can be used as a function decorator or as a normal function.
Submodules¶
cellsystem.cellsystem module¶
The cell simulation with logging.
-
class
cellsystem.cellsystem.
CellSystem
(*args, grid_shape=(100, 100), init_genome=None, **kwargs)[source]¶ Bases:
cellsystem.simulation.system.System
A system simulating cell growth.
A cell system is a system subclass, with the automatic initialization of three main entities:
- Cells represented by a cell line.
- A ‘world’ representing the space that the cells inhabit, and;
- A ‘log’ that follows and makes a record of the cells’ actions.
Each part can be accessed by
system['cells']
,system['world']
andsystem['log']
respectively.
-
class
cellsystem.cellsystem.
SimpleCells
(*args, genome_alphabet=None, **kwargs)[source]¶ Bases:
cellsystem.simulation.cells.CellLine
A cell line representing simple cells with default behaviors.
- A cell from this line performs:
- Cell division,
- Cell death,
- Cell migration,
- Cell genome mutation.
-
add_cell_to
(site)[source]¶ Add a new, initialized cell to the given site.
Return the added cell to the caller.
-
static
division
(cell, preserve_father=False)[source]¶ Cell division.
Get a new daughter of this cell and place it in a nearby neighboring site.
Module contents¶
-
class
cellsystem.
CellSystem
(*args, grid_shape=(100, 100), init_genome=None, **kwargs)[source]¶ Bases:
cellsystem.simulation.system.System
A system simulating cell growth.
A cell system is a system subclass, with the automatic initialization of three main entities:
- Cells represented by a cell line.
- A ‘world’ representing the space that the cells inhabit, and;
- A ‘log’ that follows and makes a record of the cells’ actions.
Each part can be accessed by
system['cells']
,system['world']
andsystem['log']
respectively.
CellSystem¶
An agent-based framework for the simulation of biological cell systems.
This was created to simulate cancer growth, taking into account nutrients and cell migration while allowing to track mutations, cell division and cell position history to study tumour phylogeny reconstruction algorithms.


Example¶
A use case integrated in the repository:
>>> from cellsystem import *
# The cell system will simulate cell growth
# while tracking the steps in that process.
>>> system = CellSystem(grid_shape=(100, 100))
# Initialize the first cell
# in the middle of the grid
>>> system.seed()
New cell 0 added @ (50, 50)
# Take 35 steps forward in time
>>> system.run(steps=30)
Cell no. 0 mutating @ site (50, 50) (father None)
Initial mutations: []
Initial genome: AAAAAAAAAA
Final mutations: [(4, 'G')]
Final genome: AAAAGAAAAA
Cell no. 0 dividing @ (50, 50)
New cells: 1 @ (49, 50) and 2 @ (50, 51)
Cell no. 2 dividing @ (50, 51)
New cells: 3 @ (51, 52) and 4 @ (51, 52)
Cell no. 4 mutating @ site (51, 52) (father 2)
Initial mutations: [(4, 'G')]
Initial genome: AAAAGAAAAA
Final mutations: [(4, 'G'), (7, 'A')]
Final genome: AAAAGAAAAA
Cell no. 1 death @ site (49, 50) (father None)
Cell no. 3 death @ site (51, 52) (father 2)
Cell no. 4 mutating @ site (51, 52) (father 2)
Initial mutations: [(4, 'G'), (7, 'A')]
Initial genome: AAAAGAAAAA
Final mutations: [(4, 'G'), (7, 'A'), (2, 'T')]
Final genome: AATAGAAAAA
Cell no. 4 migrating from site (51, 52) (father 2)
New site: (50, 52)
...
...
...
# Prepare to explore the simulation logs
>>> history = system['log']
# First, let's see the cells' evolution in time and space!
>>> history.worldlines().show()
# Remove the cells that died somewhere along the way
>>> history.worldlines(prune_death=True).show()


>>> tree_style = {'show_leaf_name' : True,
... 'mode' : 'c', # Circular
... 'arc_start' : -135, # Degrees
... 'arc_span' : 270 } # Degrees also
# Lookup the tree formed by cellular division
>>> history.ancestry().show(styling=tree_style)
# Now, remove cells that are no longer alive
>>> history.ancestry(prune_death=True).show(styling=tree_style)


# Now, check out the tree formed by the mutations
>>> history.mutations().show(styling=tree_style)
# Remove genomes with no living representatives.
>>> history.mutations(prune_death=True).show(styling=tree_style)


For more examples and usage, please refer to the [Wiki](wikigoeshere.com).
Meta¶
Author: Ad115 - Github – a.garcia230395@gmail.com
Distributed under the MIT license. See LICENSE for more information.
Warning: The project is still in alpha stage, so the API is just stabilizing and may change in the near future. This also means that if you want to contribute, now is the right moment to make important change suggestions ;D
Contributing¶
- Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
- Fork the repository on GitHub to start making your changes to a feature branch, derived from the master branch.
- Write a test which shows that the bug was fixed or that the feature works as expected.
- Send a pull request and bug the maintainer until it gets merged and published.