MorphoNet

Tutorial 3: Simulation in MorphoNet

This tutorial shows, step by step, how to create a simple simulation in python using MorphoNet as a viewer.

Requirements

For this tutorial, you need python 3.x and the API of morphonet. You can easly install it using pip install morphonet

The API has some dependecies scipy , numpy, scikit-image, vtk

For our simulation we use this librairy Traer Physics but we redevelop it in python. You can download it here

Simulation Definition

The objective here is just to show you how to use MorphoNet as a 4D Interactive viewer. For that we use a simple simulation example where sphere divide !

We first import classical librarie, define some basic functions and read a sphere as an obj file

In [ ]:
import sys,os
import numpy as np
import math
sys.path.append('traer') #The traer.zip path
from ParticleSystem import ParticleSystem

def volume(radius):
    return 4.0/3.0*math.pi*math.pow(radius,3)
def radius(vol):
    return math.pow(vol/(math.pi*(4.0/3.0)),1.0/3.0)

with open("sphere.obj",'r') as f:
    obj = f.read()

We create a class for a cell and for the simulated embyro

In [ ]:
id_cell=0 #Global Id Cell
class Cell():
    def __init__(self,radius,life,coord): # CONSTRUCTATORRRR
        global id_cell
        self.id=id_cell
        id_cell+=1
        self.radius=radius
        self.p=physics.makeParticle(1.0,coord[0], coord[1], coord[2])
        self.cell_life=life
        self.life=life

    def center(self):
        return [self.p.position.x,self.p.position.y,self.p.position.z]
    


class Embryo():
    def __init__(self,cell_radius=100,cell_life=50,step_physics=1,maxTime=500,plotTime=10): # CONSTRUCTATORRRR
        self.cells=[]
        self.cell_life=cell_life
        c=Cell(cell_radius,cell_life,[0,0,0])
        self.cells.append(c)
        self.step_physics=step_physics
        self.maxTime=maxTime
        self.t=0
        self.plotTime=plotTime
        self.lineage="#Lineage Simulated\n"
        self.lineage+="type:time\n"


    def live(self):
        while self.t<self.maxTime:
            if self.t%self.plotTime==0:
                self.plot()
            physics.tick(self.step_physics)

            if len(self.cells)<1000:
                self.isDivide()
           
            if len(self.cells)>1:
                print('-> at '+str(self.t)+ ", " +str(len(self.cells))+ " cells ->  Average forces "+str(physics.tension()))
            else:
                print('-> at '+str(self.t)+ "-> no springs")
            self.t+=1
        print("Done !")

    def getTime(self):
        return int(self.t/self.plotTime) #Time of plot

    def plot(self):
        tp=self.getTime()
        obj="#Test Primitives\n"
        for c in self.cells:
            obj+="p "+str(tp)+","+str(c.id)+" sphere ("+str(c.p.position.x)+","+str(c.p.position.y)+","+str(c.p.position.z)+") "+str(c.radius)+" (1,1,1,1) \n"
        mp.plotAt(tp,obj)

    def plot_lineage(self):
        f=open('lineage.txt',"w");f.write(self.lineage);f.close()
        mp.plot_infos("Lineage",self.lineage)

    def divide(self,c,aug_life=5):#Create a new Cell after Division
        c.radius=radius(volume(c.radius)/2)
        sister=Cell(c.radius,c.cell_life+np.random.randint(aug_life),c.center()+np.random.rand(3))
        s=physics.makeSpring(c.p,sister.p, 0.04, 0.1,c.radius+sister.radius) #0.05,0.1
        c.life=c.cell_life+np.random.randint(aug_life)
        self.cells.append(sister)
        return sister

    def isDivide(self):
        tp=self.getTime()
        for c in self.cells:
            self.lineage+=str(tp)+","+str(c.id)+":"+str(tp+1)+","+str(c.id)+"\n"
            if c.life<=0:
                newcell=self.divide(c)
                self.lineage+=str(tp)+","+str(c.id)+":"+str(tp+1)+","+str(newcell.id)+"\n"
            c.life-=1

We import morphonet API and run the simulation

In [ ]:
import morphonet
mp=morphonet.Plot()
mp.addPrimitive("sphere",obj) #We define our sphere as a primitive

physics = ParticleSystem()
e=Embryo(maxTime=500,plotTime=10)
e.live()
e.plot_lineage()

And now we can directly visualize the simulation in the browser and play with it