def polarity_process(sim_save_dir, sheet, polarity=1., perturbation=-1): """ Initiate simulation before running according to parameters. Parameters ---------- sim_save_dir : directory where saving simulation sheet : contracts : contractility rate of apoptotic_pattern : default None. If is None, create an apoptotic pattern according to the specific pattern. Else must be a list of face indices. """ # Define solver solver = QSSolver(with_t1=False, with_t3=False, with_collisions=False) # Define polarity define_polarity(sheet, polarity, 1) geom.normalize_weights(sheet) res = solver.find_energy_min(sheet, geom, model, options={"gtol": 1e-8}) if res.success is False: raise ('Stop because solver didn' 't succeed', res) sheet_ = run_sim(sim_save_dir, sheet, polarity, perturbation) return sheet_
def test_get_force_inference(): # INIT TISSUE sheet = Sheet.planar_sheet_2d('jam', 10, 10, 1, 1, noise=0) PlanarGeometry.update_all(sheet) model = model_factory([ effectors.FaceAreaElasticity, ], effectors.FaceAreaElasticity) sheet.remove(sheet.cut_out([[0, 10], [0, 10]])) sheet.sanitize(trim_borders=True) PlanarGeometry.scale(sheet, sheet.face_df.area.mean()**-0.5, ['x', 'y']) PlanarGeometry.center(sheet) PlanarGeometry.update_all(sheet) sheet.reset_index() sheet.reset_topo() sheet.face_df['area_elasticity'] = 1 sheet.face_df['prefered_area'] = 1 solver = QSSolver(with_t1=False, with_t3=False, with_collisions=False) res = solver.find_energy_min(sheet, PlanarGeometry, model, options={"gtol": 1e-8}) sheet.vert_df.y *= 0.5 res = solver.find_energy_min(sheet, PlanarGeometry, model, options={"gtol": 1e-8}) sheet.get_force_inference(column='tension', free_border_edges=True) sheet = sheet.extract_bounding_box(x_boundary=[-2, 2], y_boundary=[-1, 1]) sheet.edge_df['angle'] = ( np.arctan2(sheet.edge_df["dx"], sheet.edge_df["dy"]) * 180 / np.pi) sheet.edge_df['angle'] = sheet.edge_df['angle'].apply(lambda x: 180 + x if x < 0 else x) sheet.edge_df['angle'] = sheet.edge_df['angle'].apply(lambda x: 180 - x if x > 90 else x) for index, edge in sheet.edge_df[sheet.edge_df.angle > 45].iterrows(): assert (edge.tension > 1.5) for index, edge in sheet.edge_df[sheet.edge_df.angle < 45].iterrows(): assert (edge.tension < 1.5)
def test_relaxation_convergance(): # Here we relax a pre-counstructed periodic tissue object to its "periodic equilibrium" configuration # this tissue object that is loaded is far away from equilibrium 6x6 is the "periodic" equilibrium dsets = hdf5.load_datasets(Path(stores.stores_dir) / "planar_periodic8x8.hf5") specs = config.geometry.planar_sheet() specs["settings"]["boundaries"] = {"x": [-0.1, 8.1], "y": [-0.1, 8.1]} initial_box_size = 8.2 sheet = Sheet("periodic", dsets, specs) coords = ["x", "y"] draw_specs = config.draw.sheet_spec() PlanarGeometry.update_all(sheet) solver = QSSolver(with_collisions=False, with_t1=True, with_t3=False) nondim_specs = config.dynamics.quasistatic_plane_spec() dim_model_specs = model.dimensionalize(nondim_specs) sheet.update_specs(dim_model_specs, reset=True) # epsilon is deviation of boundary between iterations epsilon = 1.0 # max_dev is the max epsilon allowed for configuration to be in equilibrium max_dev = 0.001 # i counts the number of solver iterations i = 0 # loop ends if box size variation between iterations drops 10^-3 # loaded tissue is far away from periodic equilibrium L=8 and equilibrium is reached around 6.06 while np.abs(epsilon) > max_dev: i += 1 if i == 1: previous_box_size = 0 else: previous_box_size = solution_result["x"][-1] solution_result = solver.find_energy_min( sheet, PlanarGeometry, model, periodic=True ) epsilon = solution_result["x"][-1] - previous_box_size # print(epsilon) final_box_size = ( sheet.settings["boundaries"]["x"][1] - sheet.settings["boundaries"]["x"][0] ) print("number of iterations " + str(i)) print("final box size " + str(final_box_size)) assert 6.06 - 0.1 < final_box_size < 6.06 + 0.1
def get_initial_follicle(specs, recreate=False, Nc=200): """Retrieves or recreates a spherical epithelium""" if recreate: ## Lloy_relax=True takes time but should give more spherical epithelium follicle = spherical_monolayer(9.0, 12.0, Nc, apical="in", Lloyd_relax=True) geom.update_all(follicle) geom.scale(follicle, follicle.cell_df.vol.mean() ** (-1 / 3), list("xyz")) geom.update_all(follicle) else: follicle = Monolayer("follicle", hdf5.load_datasets("initial_follicle.hf5")) follicle.settings["lumen_side"] = "apical" geom.update_all(follicle) follicle.update_specs(specs, reset=True) follicle.cell_df["id"] = follicle.cell_df.index wgeom = WAMonolayerGeometry model = model_factory( [ effectors.LumenVolumeElasticity, WeightedCellAreaElasticity, effectors.CellVolumeElasticity, ] ) print("Finding static equilibrium") follicle.face_df.loc[follicle.apical_faces, "weight"] = specs["settings"][ "apical_weight" ] wgeom.update_all(follicle) solver = QSSolver() res = solver.find_energy_min(follicle, wgeom, model) return follicle, model
SIM_DIR = Path('') today = datetime.date.today().strftime('%Y%m%d') sim_save_dir = SIM_DIR / f'{today}-variability' try: os.mkdir(sim_save_dir) except FileExistsError: pass from joblib import Parallel, delayed import multiprocessing from datetime import datetime solver = QSSolver(with_t1=False, with_t3=False, with_collisions=False) model = model_factory([ effectors.BarrierElasticity, effectors.RadialTension, effectors.PerimeterElasticity, effectors.FaceAreaElasticity, effectors.LumenVolumeElasticity, ], effectors.FaceAreaElasticity) apopto_pattern_kwargs = {'t': 0., 'dt': 1., 'time_of_last_apoptosis': 30.} # apoptose apoptosis_settings = { "critical_area_pulling": 10, "critical_area": 0.5, "contract_rate": 1.08,
def run_sim( sim_save_dir, _sheet, polarity, perturbation=-1, stop=150., iteration=0, ): # Define solver solver = QSSolver(with_t1=False, with_t3=False, with_collisions=False) filename = '{}_polarity{}_perturbation.hf5'.format(polarity, perturbation) try: os.mkdir(sim_save_dir) except IOError: pass # without copy, dataframe is on read only... sheet = _sheet.copy() sheet.face_df['is_mesoderm'] = 0 if perturbation != -1: for p in perturbation: sheet.face_df.loc[int(p), 'is_mesoderm'] = 1 define_polarity(sheet, 1, polarity) geom.normalize_weights(sheet) # Add some information to the sheet sheet.face_df['id'] = sheet.face_df.index.values # Initiate history history = HistoryHdf5(sheet, extra_cols={ "face": sheet.face_df.columns, "edge": list(sheet.edge_df.columns), "vert": list(sheet.vert_df.columns) }, hf5file=os.path.join(sim_save_dir, filename)) # Initiate manager manager = EventManager('face') # save settings pd.Series(sheet.settings).to_csv( os.path.join(sim_save_dir, (filename[:-4] + '_settings.csv'))) manager.append(reconnect, **sheet.settings['rosette_kwargs']) manager.append(apoptosis_patterning, **sheet.settings['apopto_pattern_kwargs']) t = 0. stop = 150. # Run simulation while t < stop: if t == 5: for i in sheet.face_df[sheet.face_df.is_mesoderm == 1].index: delamination_kwargs = sheet.settings[ 'delaminate_setting'].copy() delamination_kwargs.update({ "face_id": i, }) manager.append(delamination, **delamination_kwargs) # Reset radial tension at each time step sheet.vert_df.radial_tension = 0. manager.execute(sheet) res = solver.find_energy_min(sheet, geom, model, options={"gtol": 1e-8}) if res.success is False: raise ('Stop because solver didn' 't succeed at time t ' + str(t), res) # add noise on vertex position to avoid local minimal. sheet.vert_df[['x', 'y']] += np.random.normal(scale=1e-3, size=(sheet.Nv, 2)) geom.update_all(sheet) history.record(time_stamp=float(t)) manager.update() t += 1. return sheet