Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

v1.1.0: support for cell signaling, gene circuits, and unit tests #42

Merged
merged 2 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Goo is a Python-based Blender extension for modeling biological cells, tissues, and embryos

Goo is a modeling environment for creating physics based simulations of biological cells, tissues, and whole embryos. Goo contains built-in models for basic cell properties such as growth, division, and adhesion. Goo creates realistic models of cells in 3D based on surface meshes enclosing compresible fluid. Goo is meant to fill a void in currently available models such as vertex and particle based models which are too simplified to capture essential featuers of cells, are often 2D, and can be difficult for new users to use.
Goo is a modeling environment for creating physics based simulations of biological cells, tissues, and whole embryos. Goo contains built-in models for basic cell properties such as growth, division, adhesion, signaling and transduction. Goo creates realistic models of cells in 3D based on surface meshes enclosing compresible fluid. Goo is meant to fill a void in currently available models such as vertex and particle based models which are too simplified to capture essential featuers of cells, are often 2D, and can be difficult for new users to use.

Goo is built on top of Blender. Blender is a truly amazing open source computer graphics project for generating animations. Goo provides a library of helper functions in Python for creating cells with user defined properties that are used inside the scripting environment and GUI of Blender. Physics and rendering are handled by Blender. In combination Goo and Blender allow cell-based simulations to be interacted with via Python scripts and through a GUI.

Expand Down
4 changes: 3 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

# Blender python interpreter
BL_PYTHON_PATH = (
"/Applications/Blender.app/Contents/Resources/4.0/python/bin/python3.10"
"/Applications/Blender-4.0.app/Contents/Resources/4.0/python/bin/python3.10"
)

sys.path.insert(0, os.path.abspath("../../scripts/modules"))
Expand Down Expand Up @@ -69,3 +69,5 @@

highlight_language = "python"
pygments_style = "emacs" # Or choose any other style you prefer

autodoc_mock_imports = ["bpy", "bmesh", "mathutils"]
46 changes: 25 additions & 21 deletions docs/source/developer_guide/developers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,28 @@ Installing new packages
-----------------------

1. Activate the virtual environment created during installation and install desired packages:
.. code-block:: bash

.blender_env\\Scripts\\activate
pip install <package>
.. code-block:: bash

.blender_env\\Scripts\\activate
pip install <package>

2. Update the `hook/modules` folder:
macOS:

.. code-block:: bash
macOS:

.. code-block:: bash

make update_modules

make update_modules
Windows:

Windows:
.. code-block:: bash

.. code-block:: bash
rmdir /S /Q hook
mkdir hook\\scripts\\modules
xcopy .blender_venv\\lib\\python3.10\\site-packages\\* hook\\scripts\\modules /E /H /I

rmdir /S /Q hook
mkdir hook\\scripts\\modules
xcopy .blender_venv\\lib\\python3.10\\site-packages\\* hook\\scripts\\modules /E /H /I


Testing your code
--------------------
Expand All @@ -49,23 +51,25 @@ We developed a suite of tests to ensure the correct functioning of the codebase.
2. A suite of test cases can be found inside the `/tests` folder.

3. To run the suite of tests, open a terminal in VSCode and run the following command from the codebase root directory. Make sure to replace the path to the Blender executable with the correct path on your system.
macOS:

macOS:

.. code-block:: bash
.. code-block:: bash

make test
make test

or

.. code-block:: bash
or

/Applications/Blender-4.0.app/Contents/MacOS/Blender --background --python-expr "import pytest; pytest.main(['-v', './tests'])"
.. code-block:: bash

Windows:
/Applications/Blender-4.0.app/Contents/MacOS/Blender --background --python-expr "import pytest; pytest.main(['-v', './tests'])"

.. code-block:: bash
Windows:

.. code-block:: bash

"C:\Program Files\Blender Foundation\Blender 3.0\blender.exe" --background --python-expr "import pytest; pytest.main(['-v', './tests'])"
"C:\Program Files\Blender Foundation\Blender 4.0\blender.exe" --background --python-expr "import pytest; pytest.main(['-v', './tests'])"

4. All tests should pass before submitting a pull request.

Expand Down
Binary file added docs/source/examples/1_growing_doublets.mp4
Binary file not shown.
37 changes: 37 additions & 0 deletions docs/source/examples/1_growing_doublets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from importlib import reload
import goo

reload(goo)
goo.reset_modules()
goo.reset_scene()

cellsA = goo.CellType("A", target_volume=60, pattern="simple")
cellsB = goo.CellType("B", target_volume=60, pattern="simple")
cellsC = goo.CellType("C", target_volume=60, pattern="simple")

cellsA.homo_adhesion_strength = 1
cellsA.stiffness = 1 # ratio = 1
cellsB.homo_adhesion_strength = 500
cellsB.stiffness = 1 # ratio = 500
cellsC.homo_adhesion_strength = 2000
cellsC.stiffness = 1 # ratio = 2000

cellsA.create_cell("A1", (-20, +1.75, 0), color=(1, 1, 0), size=1.6)
cellsA.create_cell("A2", (-20, -1.75, 0), color=(1, 1, 0), size=1.6)

cellsB.create_cell("B1", (0, +1.75, 0), color=(0, 1, 1), size=1.6)
cellsB.create_cell("B2", (0, -1.75, 0), color=(0, 1, 1), size=1.6)

cellsC.create_cell("C1", (20, +1.75, 0), color=(1, 0, 1), size=1.6)
cellsC.create_cell("C2", (20, -1.75, 0), color=(1, 0, 1), size=1.6)

sim = goo.Simulator([cellsA, cellsB, cellsC], time=180, physics_dt=1)
sim.setup_world(seed=2024)
sim.add_handlers(
[
goo.GrowthPIDHandler(), # in um3
goo.RecenterHandler(),
goo.SizeDivisionHandler(goo.BisectDivisionLogic, mu=50, sigma=1), # in um3
goo.RandomMotionHandler(goo.ForceDist.GAUSSIAN, strength=500),
]
)
37 changes: 0 additions & 37 deletions docs/source/examples/2_randomly_moving_doublets.py

This file was deleted.

25 changes: 25 additions & 0 deletions docs/source/examples/2_volume_dividing_cells.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from importlib import reload
import goo


reload(goo)
goo.reset_modules()
goo.reset_scene()

# Defining cells
celltype = goo.CellType("A", target_volume=70, pattern="simple")
celltype.homo_adhesion_strength = 2000

cell1 = celltype.create_cell(name="cell1", loc=(1.5, 0, 0), color=(0, 1, 1))
cell1.stiffness = 2
cell1.pressure = 5

sim = goo.Simulator([celltype], time=200, physics_dt=1)
sim.setup_world(seed=2025)
sim.add_handlers(
[
goo.GrowthPIDHandler(), # in um3
goo.RecenterHandler(),
goo.SizeDivisionHandler(goo.BisectDivisionLogic, mu=40, sigma=1), # in um3
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ def check_min_distance(new_point, points, min_distance):
# Create cells within the sphere with minimum distance constraint
num_cells = 6 # Number of cells
radius = 15 # Sphere radius
min_distance = 3 # Minimum distance between cells
min_distance = 3 # Mnimum distance between cells

goo.create_boundary((0, 0, 0), size=radius * 1.2)
goo.create_boundary((0, 0, 0), size=radius)

cellsA = goo.SimpleType("A")
cellsA.homo_adhesion_strength = 500
cellsA = goo.CellType("A", target_volume=100, pattern="simple")
cellsA.homo_adhesion_strength = 150
cellsA.motion_strength = 1500
cells = []

while len(cells) < num_cells:
Expand All @@ -45,17 +46,17 @@ def check_min_distance(new_point, points, min_distance):
cells.append(new_point)
cell_name = f"cell_A{len(cells)}"
color = tuple(np.random.random_sample(3))
cell = cellsA.create_cell(cell_name, new_point, color=color)
cell = cellsA.create_cell(cell_name, new_point, color=color, size=1.5)
cell.stiffness = 1
cell.pressure = 5

sim = goo.Simulator([cellsA], time=500, physics_dt=1)
sim.setup_world()
sim.toggle_gravity(True)
sim = goo.Simulator([cellsA], time=300, physics_dt=1)
sim.setup_world(seed=2024)
sim.add_handlers(
[
goo.GrowthPIDHandler(target_volume=50),
goo.GrowthPIDHandler(),
goo.RecenterHandler(),
goo.RandomMotionHandler(distribution=goo.ForceDist.CONSTANT, max_strength=2500),
goo.SizeDivisionHandler(goo.BisectDivisionLogic, mu=105, sigma=1),
goo.RandomMotionHandler(distribution=goo.ForceDist.UNIFORM),
]
)
Binary file not shown.
25 changes: 0 additions & 25 deletions docs/source/examples/3_volume_dividing_cells.py

This file was deleted.

44 changes: 44 additions & 0 deletions docs/source/examples/4_blinking_cells.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from importlib import reload
import goo
from goo.gene import *
from goo.division import *
from goo.handler import *

reload(goo)
goo.reset_modules()
goo.reset_scene()

celltype = goo.CellType("cellA", pattern="simple", target_volume=70)
celltype.homo_adhesion_strength = 500
cell = celltype.create_cell(name="cell1", loc=(0, 0, 0), color=(0, 0, 0))
cell.stiffness = 5

# Defining genes
x = Gene("x")
y = Gene("y")
z = Gene("z")

network1 = GeneRegulatoryNetwork()
network1.load_circuits(
DegFirstOrder(x, 0.1),
DegFirstOrder(y, 0.1),
DegFirstOrder(z, 0.1),
ProdRepression(y, x, kcat=0.4, n=3),
ProdRepression(z, y, kcat=0.4, n=3),
ProdRepression(x, z, kcat=0.4, n=3),
)
cell.grn = network1
cell.metabolites = {x: 2, y: 0.1, z: 0.1}

sim = goo.Simulator(celltypes=[celltype], time=200, physics_dt=1)
sim.setup_world(seed=2025)
sim.add_handlers(
[
goo.GrowthPIDHandler(),
goo.SizeDivisionHandler(goo.BisectDivisionLogic, mu=60, sigma=2),
goo.RecenterHandler(),
goo.RemeshHandler(),
goo.NetworkHandler(),
goo.ColorizeHandler(goo.Colorizer.GENE, x, range=(1, 2)),
]
)
Binary file not shown.
Loading
Loading