def basic_simulation(cells, force, dt=dt, T1_eps=0.04): while True: cells.mesh, number_T1 = cells.mesh.transition(T1_eps) F = force(cells) / viscosity expansion = 0.05 * np.average(F * cells.mesh.vertices, 1) * dt dv = dt * model.sum_vertices(cells.mesh.edges, F) cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion) yield cells
def simulation_with_division( cells, force, dt=dt, T1_eps=T1_eps, lifespan=100.0, rand=None): #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=Non properties = cells.properties properties[ 'parent'] = cells.mesh.face_ids #save the ids to control division parents-daugthers properties['ageingrate'] = np.random.normal( 1.0 / lifespan, 0.2 / lifespan, len(cells)) #degradation rate per each cell properties['ids_division'] = [ ] #save ids of the cell os the division when it's ready per each time step properties['force_x'] = [] properties['force_y'] = [] properties['T1_angle_pD'] = [] properties['Division_angle_pD'] = [] expansion = np.array([0.0, 0.0]) while True: #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis ready = np.where(~cells.empty() & (cells.mesh.area >= A_c) & (cells.properties['age'] >= (t_G1 + t_S + t_G2)))[0] if len( ready ): #these are the cells ready to undergo division at the current timestep properties['ageingrate'] = np.append( properties['ageingrate'], np.abs( np.random.normal(1.0 / lifespan, 0.2 / lifespan, 2 * len(ready)))) properties['age'] = np.append(properties['age'], np.zeros(2 * len(ready))) properties['parent'] = np.append( properties['parent'], np.repeat(properties['parent'][ready], 2)) # Daugthers and parent have the same ids properties['ids_division'] = ready edge_pairs = [ division_axis(cells.mesh, cell_id, rand) for cell_id in ready ] #New edges after division cells.mesh = cells.mesh.add_edges( edge_pairs) #Add new edges in the mesh for i in range(len(ready)): commun_edges = np.intersect1d( cells.mesh.length[np.where( cells.mesh.face_id_by_edge == (cells.mesh.n_face - 2 * (i + 1)))[0]], cells.mesh.length[np.where( cells.mesh.face_id_by_edge == (cells.mesh.n_face - 1 - 2 * i))[0]]) division_new_edge = np.where( cells.mesh.length == np.max(commun_edges))[0] properties['Division_angle_pD'] = np.append( properties['Division_angle_pD'], cells.mesh.edge_angle[division_new_edge][0]) properties['age'] = properties['age'] + dt * properties[ 'ageingrate'] #add time step depending of the degradation rate """Calculate z nuclei position (Apical-Basal movement), depending of the cell cycle phase time and age of the cell""" N_G1 = 1 - 1.0 / t_G1 * properties['age'] #nuclei position in G1 phase N_S = 0 N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S) ) #nuclei position in G2 and S phase properties['zposn'] = np.minimum( 1.0, np.maximum(N_G1, np.maximum(N_S, N_G2))) """Target area function depending age and z nuclei position""" properties['A0'] = (properties['age'] + 1.0) * 0.5 * (1.0 + properties['zposn']**2) #############BAETTI VID #ath BAETTI D VID cells.mesh, number_T1, d = cells.mesh.transition( T1_eps) #check edges verifing T1 transition if len(number_T1) > 0: for ii in number_T1: index = cells.mesh.face_id_by_edge[ii] properties['T1_angle_pD'] = np.append( properties['T1_angle_pD'], cells.mesh.edge_angle[ii]) F = force( cells ) / viscosity #force per each cell force= targetarea+Tension+perimeter+pressure_boundary #EG BAETTI VID len_modified = np.matrix.copy(cells.mesh.length) #len_modified[np.where((properties['parent_group'][cells.mesh.face_id_by_edge]==1) & np.logical_not(properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==0))]*=0.12 tens = (0.5 * cells.by_edge('Lambda', 'Lambda_boundary') / len_modified) * cells.mesh.edge_vect tens = tens - tens.take(cells.mesh.edges.prev, 1) F += tens dv = dt * model.sum_vertices( cells.mesh.edges, F) #movement of the vertices using eq: viscosity*dv/dt = F properties['force_x'] = F[0] * viscosity properties['force_y'] = F[1] * viscosity if hasattr(cells.mesh.geometry, 'width'): expansion[0] = expansion_constant * np.average( F[0] * cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2) if hasattr(cells.mesh.geometry, 'height'): #Cylinder mesh doesn't have 'height' argument expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / ( cells.mesh.geometry.height**2) cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion) yield cells
def simulation_with_division_clone_differenciation_3stripes( cells, force, dt=dt, T1_eps=T1_eps, lifespan=100.0, rand=None): #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=Non properties = cells.properties properties[ 'parent'] = cells.mesh.face_ids #save the ids to control division parents-daugthers properties['ageingrate'] = np.random.normal( 1.0 / lifespan, 0.2 / lifespan, len(cells)) #degradation rate per each cell #floor plate cells no = len( properties['ageingrate'][np.where(properties['parent_group'] == 3)]) properties['ageingrate'][np.where( properties['parent_group'] == 3)] = np.random.normal( 0.5 / lifespan, 0.1 / lifespan, no) properties['ids_division'] = [ ] #save ids of the cell os the division when it's ready per each time step properties['ids_division_1'] = [ ] #save ids of the cell os the division when it's ready per each time step and region properties['ids_division_02'] = [ ] #save ids of the cell os the division when it's ready per each time step and region properties['poisoned'] = np.zeros( len(cells)) ### to add diferenciation rate in PMN # properties['differentiation_rate']= np.zeros(len(cells),dtype=int) properties['force_x'] = [] properties['force_y'] = [] properties['T1_angle_pMN'] = [] properties['T1_angle_pD'] = [] properties['Division_angle_pMN'] = [] properties['Division_angle_pD'] = [] properties['deleted_edges'] = [] properties['edges_division'] = [] properties['T1_edge'] = [] expansion = np.array([0.0, 0.0]) while True: #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis ready = np.where( (~cells.empty() & (cells.mesh.area >= A_c) & (cells.properties['age'] >= (t_G1 + t_S + t_G2))) | (~cells.empty() & (cells.properties['parent_group'] == 3) & (cells.mesh.area >= 0.4) & (cells.properties['age'] >= (t_G1 + t_S + t_G2))))[0] if len( ready ): #these are the cells ready to undergo division at the current timestep #properties['ageingrate'] =np.append(properties['ageingrate'], np.repeat(properties['ageingrate'][ready],2)) properties['age'] = np.append(properties['age'], np.zeros(2 * len(ready))) properties['parent'] = np.append( properties['parent'], np.repeat(properties['parent'][ready], 2)) # Daugthers and parent have the same ids properties['ids_division'] = ready properties['parent_group'] = np.append( properties['parent_group'], np.repeat(properties['parent_group'][ready], 2)) #use to draw clones properties['poisoned'] = np.append( properties['poisoned'], np.zeros( 2 * len(ready))) ### to add diferenciation rate in PMN edge_pairs = [ division_axis(cells.mesh, cell_id, rand) for cell_id in ready ] #New edges after division properties['edges_division'].append(edge_pairs) cells.mesh = cells.mesh.add_edges( edge_pairs) #Add new edges in the mesh for i in range(len(ready)): commun_edges = np.intersect1d( cells.mesh.length[np.where( cells.mesh.face_id_by_edge == (cells.mesh.n_face - 2 * (i + 1)))[0]], cells.mesh.length[np.where( cells.mesh.face_id_by_edge == (cells.mesh.n_face - 1 - 2 * i))[0]]) division_new_edge = np.where( cells.mesh.length == np.max(commun_edges))[0] if properties['parent_group'][ready[i]] == 3: properties['ageingrate'] = np.append( properties['ageingrate'], np.abs( np.random.normal(1.0 / lifespan, 0.2 / lifespan, 2))) else: properties['ageingrate'] = np.append( properties['ageingrate'], np.abs( np.random.normal(1.0 / lifespan, 0.2 / lifespan, 2))) # print len(properties['ageingrate']) #if properties['parent_group'][cells.mesh.n_face-2*(i+1)]==1: # properties['Division_angle_pMN']= np.append(properties['Division_angle_pMN'],cells.mesh.edge_angle[division_new_edge][0]) #else: # properties['Division_angle_pD']= np.append(properties['Division_angle_pD'],cells.mesh.edge_angle[division_new_edge][0]) #for ids in ready: # if properties['parent_group'][ids]==1: # properties['ids_division_1'] = np.append(properties['ids_division_1'], ids) # else: # properties['ids_division_02'] = np.append(properties['ids_division_02'], ids) ###### Differentiation rate properties['differentiation_rate'] = time_hours * dt * (np.array([ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ]))[properties['parent_group']] #Used 0.02, 0.0002 & 1/13 properties['poisoned'] = properties['poisoned'] - ( properties['poisoned'] - 1) * (~(cells.empty()) & (rand.rand(len(cells)) < properties['differentiation_rate'])) properties['age'] = properties['age'] + dt * properties[ 'ageingrate'] #add time step depending of the degradation rate N_G1 = 1 - 1.0 / t_G1 * properties['age'] #nuclei position in G1 phase N_S = 0 N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S) ) #nuclei position in G2 and S phase properties['zposn'] = np.minimum( 1.0, np.maximum(N_G1, np.maximum(N_S, N_G2))) properties['zposn'][np.where(properties['parent_group'] == 3)] = 0 """Target area function depending age and z nuclei position""" properties['A0'] = (properties['age'] + 1.0) * 0.5 * ( 1.0 + properties['zposn']**2) * (1.0 - cells.properties['poisoned']) cells.mesh, number_T1, del_edges = cells.mesh.transition(T1_eps) properties['deleted_edges'].append(del_edges) #if len(number_T1)>0: # for ii in number_T1: # properties['T1_edge']=np.append(properties['T1_edge'], ii) # index = cells.mesh.face_id_by_edge[ii] #if properties['parent_group'][index]==1: # properties['T1_angle_pMN'] =np.append(properties['T1_angle_pMN'],cells.mesh.edge_angle[ii]) #else: # properties['T1_angle_pD'] =np.append(properties['T1_angle_pD'],cells.mesh.edge_angle[ii]) F = force( cells ) / viscosity #force per each cell force= targetarea+Tension+perimeter+pressure_boundary #ADDING THE FLOOR PLATE len_modified = np.matrix.copy(cells.mesh.length) #this next line can be use for modifying all edges at the boundary #len_modified[np.where( ((properties['parent_group'][cells.mesh.face_id_by_edge]==3) & np.logical_not(properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==3)) | ((properties['parent_group'][cells.mesh.face_id_by_edge]==2) & (properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==3)) | ((properties['parent_group'][cells.mesh.face_id_by_edge]==4) & (properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==3)) )]*=0.004 #modifying tension w.r.t. area for n in np.where( ((properties['parent_group'][cells.mesh.face_id_by_edge] == 3) & np.logical_not( properties['parent_group'][cells.mesh.face_id_by_edge[ cells.mesh.edges.reverse]] == 3)))[0]: if abs(cells.mesh.area[cells.mesh.face_id_by_edge[n]] - cells.mesh.area[cells.mesh.face_id_by_edge[ cells.mesh.edges.reverse[n]]]) > 0.4: len_modified[n] *= 0.002 tens = (0.5 * cells.by_edge('Lambda', 'Lambda_boundary') / len_modified) * cells.mesh.edge_vect tens = tens - tens.take(cells.mesh.edges.prev, 1) F += tens dv = dt * model.sum_vertices( cells.mesh.edges, F) #movement of the vertices using eq: viscosity*dv/dt = F #properties['force_x'] = F[0]*viscosity #properties['force_y'] = F[1]*viscosity if hasattr(cells.mesh.geometry, 'width'): expansion[0] = expansion_constant * np.average( F[0] * cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2) if hasattr(cells.mesh.geometry, 'height'): #Cylinder mesh doesn't have 'height' argument expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / ( cells.mesh.geometry.height**2) cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion) yield cells
def simulation_with_division_clone_whole_tissue_differenciation( cells, force, dt=dt, T1_eps=T1_eps, lifespan=100.0, rand=None ): #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=None properties = cells.properties properties[ 'parent'] = cells.mesh.face_ids #save the ids to control division parents-daugthers properties['ageingrate'] = np.random.normal( 1.0 / lifespan, 0.2 / lifespan, len(cells)) #degradation rate per each cell properties['ids_division'] = [ ] #save ids of the cell os the division when it's ready per each time step properties['ids_division_1'] = [ ] #save ids of the cell os the division when it's ready per each time step and region properties['ids_division_02'] = [ ] #save ids of the cell os the division when it's ready per each time step and region properties['poisoned'] = np.zeros( len(cells)) ### to add diferenciation rate in PMN # properties['differentiation_rate']= np.zeros(len(cells),dtype=int) properties['force_x'] = [] properties['force_y'] = [] properties['T1_angle_pMN'] = [] properties['T1_angle_pD'] = [] properties['Division_angle_pMN'] = [] properties['Division_angle_pD'] = [] properties['ids_removed'] = [] expansion = np.array([0.0, 0.0]) while True: #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis ready = np.where(~cells.empty() & (cells.mesh.area >= A_c) & (cells.properties['age'] >= (t_G1 + t_S + t_G2)))[0] if len( ready ): #these are the cells ready to undergo division at the current timestep properties['ageingrate'] = np.append( properties['ageingrate'], np.abs( np.random.normal(1.0 / lifespan, 0.2 / lifespan, 2.0 * len(ready)))) properties['age'] = np.append(properties['age'], np.zeros(2 * len(ready))) properties['parent'] = np.append( properties['parent'], np.repeat(properties['parent'][ready], 2)) # Daugthers and parent have the same ids properties['ids_division'] = ready properties['parent_group'] = np.append( properties['parent_group'], np.repeat(properties['parent_group'][ready], 2)) #use to draw clones properties['poisoned'] = np.append( properties['poisoned'], np.zeros( 2 * len(ready))) ### to add diferenciation rate in PMN # properties['differentiation_rate'] = np.append(properties['differentiation_rate'], diff_rate_hours*np.ones(2*len(ready))) edge_pairs = [ division_axis(cells.mesh, cell_id, rand) for cell_id in ready ] #New edges after division cells.mesh = cells.mesh.add_edges( edge_pairs) #Add new edges in the mesh for i in range(len(ready)): commun_edges = np.intersect1d( cells.mesh.length[np.where( cells.mesh.face_id_by_edge == (cells.mesh.n_face - 2 * (i + 1)))[0]], cells.mesh.length[np.where( cells.mesh.face_id_by_edge == (cells.mesh.n_face - 1 - 2 * i))[0]]) division_new_edge = np.where( cells.mesh.length == np.max(commun_edges))[0] if properties['parent_group'][cells.mesh.n_face - 2 * (i + 1)] == 1: properties['Division_angle_pMN'] = np.append( properties['Division_angle_pMN'], cells.mesh.edge_angle[division_new_edge][0]) else: #antes estaba mal y ponia pD!!!! las simulaciones guardadas estan mal properties['Division_angle_pMN'] = np.append( properties['Division_angle_pMN'], cells.mesh.edge_angle[division_new_edge][0]) for ids in ready: if properties['parent_group'][ids] == 1: properties['ids_division_1'] = np.append( properties['ids_division_1'], ids) else: #antes estaba mal y ponia 0_2!!!! las simulaciones guardadas estan mal properties['ids_division_1'] = np.append( properties['ids_division_1'], ids) ###### Defferentiation rate properties['differentiation_rate'] = time_hours * dt * (np.array([ 0.0, diff_rate_hours, 0.0, 0.0, 0.0, diff_rate_hours, 0.0 ]))[properties['parent_group']] #Used 0.02, 0.0002 & 1/13 properties['poisoned'] = properties['poisoned'] - ( properties['poisoned'] - 1) * (~(cells.empty()) & (rand.rand(len(cells)) < properties['differentiation_rate'])) properties['age'] = properties['age'] + dt * properties[ 'ageingrate'] #add time step depending of the degradation rate N_G1 = 1 - 1.0 / t_G1 * properties['age'] #nuclei position in G1 phase N_S = 0 N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S) ) #nuclei position in G2 and S phase properties['zposn'] = np.minimum( 1.0, np.maximum(N_G1, np.maximum(N_S, N_G2))) """Target area function depending age and z nuclei position""" properties['A0'] = (properties['age'] + 1.0) * 0.5 * ( 1.0 + properties['zposn']**2) * (1.0 - cells.properties['poisoned']) cells.mesh, number_T1, ids_removed = cells.mesh.transition(T1_eps) properties['ids_removed'].append(ids_removed) #####BAETTI VID if len(number_T1) > 0: for ii in number_T1: index = cells.mesh.face_id_by_edge[ii] if properties['parent_group'][index] == 1: properties['T1_angle_pMN'] = np.append( properties['T1_angle_pMN'], cells.mesh.edge_angle[ii]) else: #antes estaba mal y ponia pD!!!! las simulaciones guardadas estan mal properties['T1_angle_pMN'] = np.append( properties['T1_angle_pMN'], cells.mesh.edge_angle[ii]) F = force( cells ) / viscosity #force per each cell force= targetarea+Tension+perimeter+pressure_boundary dv = dt * model.sum_vertices( cells.mesh.edges, F) #movement of the vertices using eq: viscosity*dv/dt = F properties['force_x'] = F[0] * viscosity properties['force_y'] = F[1] * viscosity if hasattr(cells.mesh.geometry, 'width'): expansion[0] = expansion_constant * np.average( F[0] * cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2) if hasattr(cells.mesh.geometry, 'height'): #Cylinder mesh doesn't have 'height' argument expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / ( cells.mesh.geometry.height**2) cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion) yield cells
def simulation_with_division_clone_differentiation( cells, force, dt=dt, T1_eps=T1_eps, lifespan=100.0, rand=None): #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=Non properties = cells.properties properties[ 'parent'] = cells.mesh.face_ids #save the ids to control division parents-daugthers properties['ageingrate'] = np.random.normal( 1.0 / lifespan, 0.2 / lifespan, len(cells)) #degradation rate per each cell properties['ids_division'] = [ ] #save ids of the cell os the division when it's ready per each time step properties['poisoned'] = np.zeros( len(cells)) ### to add diferenciation rate in PMN expansion = np.array([0.0, 0.0]) while True: #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis ready = np.where(~cells.empty() & (cells.mesh.area >= A_c) & (cells.properties['age'] >= (t_G1 + t_S + t_G2)))[0] if len( ready ): #these are the cells ready to undergo division at the current timestep properties['ageingrate'] = np.append( properties['ageingrate'], np.abs( np.random.normal(1.0 / lifespan, 0.2 / lifespan, 2.0 * len(ready)))) properties['age'] = np.append(properties['age'], np.zeros(2 * len(ready))) properties['parent'] = np.append( properties['parent'], np.repeat(properties['parent'][ready], 2)) # Daugthers and parent have the same ids properties['ids_division'] = ready properties['parent_group'] = np.append( properties['parent_group'], np.repeat(properties['parent_group'][ready], 2)) #use to draw clones properties['poisoned'] = np.append( properties['poisoned'], np.zeros( 2 * len(ready))) ### to add diferenciation rate in PMN edge_pairs = [ division_axis(cells.mesh, cell_id, rand) for cell_id in ready ] #New edges after division cells.mesh = cells.mesh.add_edges( edge_pairs) #Add new edges in the mesh ###### Defferenciation rate properties['poisoned'] = properties['poisoned'] - ( properties['poisoned'] - 1) * (~(cells.empty()) & (rand.rand(len(cells)) < (dt * diff_rate_hours * time_hours))) properties['age'] = properties['age'] + dt * properties[ 'ageingrate'] #add time step depending of the degradation rate """Calculate z nuclei position (Apical-Basal movement), depending of the cell cycle phase time and age of the cell""" N_G1 = 1 - 1.0 / t_G1 * properties['age'] #nuclei position in G1 phase N_S = 0 N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S) ) #nuclei position in G2 and S phase properties['zposn'] = np.minimum( 1.0, np.maximum(N_G1, np.maximum(N_S, N_G2))) """Target area function depending age and z nuclei position""" properties['A0'] = (properties['age'] + 1.0) * 0.5 * ( 1.0 + properties['zposn']**2) * (1.0 - cells.properties['poisoned']) cells.mesh, number_T1 = cells.mesh.transition( T1_eps) #check edges verifing T1 transition F = force( cells ) / viscosity #force per each cell force= targetarea+Tension+perimeter+pressure_boundary dv = dt * model.sum_vertices( cells.mesh.edges, F) #movement of the vertices using eq: viscosity*dv/dt = F if hasattr(cells.mesh.geometry, 'width'): expansion[0] = expansion_constant * np.average( F[0] * cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2) if hasattr(cells.mesh.geometry, 'height'): #Cylinder mesh doesn't have 'height' argument expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / ( cells.mesh.geometry.height**2) cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion) yield cells