def test_simulate(): dim = 1 cbm_solver = cbmos.CBModel(ff.Cubic(), scpi.solve_ivp, dim) cell_list = [cl.Cell(0, [0]), cl.Cell(1, [1.0], 0.0, True)] cell_list[1].division_time = 1.05 # make sure not to divide at t_data N = 100 t_data = np.linspace(0, 10, N) # stay away from 24 hours t_data_sol, history = cbm_solver.simulate(cell_list, t_data, {}, {}, raw_t=False) assert len(history) == N assert t_data_sol.tolist() == t_data.tolist() assert len(history[10]) == 2 assert np.isclose(abs(history[10][0].position - history[10][1].position), 1) assert len(history[-1]) == 3 scells = sorted(history[-1], key=lambda c: c.position) assert np.isclose(abs(scells[0].position - scells[1].position), 1, atol=1e-03) assert np.isclose(abs(scells[1].position - scells[2].position), 1, atol=1e-03)
def test_no_division_skipped(): dim = 1 cbm_solver = cbmos.CBModel(ff.Linear(), scpi.solve_ivp, dim) cell_list = [ cl.Cell(0, [0], proliferating=True), cl.Cell(1, [1.0], 0.0, True) ] cell_list[0].division_time = 1.0 cell_list[1].division_time = 1.0 t_data = np.linspace(0, 30, 101) _, history = cbm_solver.simulate(cell_list, t_data, {}, {}, raw_t=False) eq = [ hq.heappop(cbm_solver._queue._events) for i in range(len(cbm_solver._queue._events)) ] assert eq == sorted(eq) assert len(eq) == len(history[-1]) - 1 for t, cells in zip(t_data, history): for c in cells: assert c.birthtime <= t assert c.division_time > t
def test_event_at_t_data(): dim = 1 cbm_solver = cbmos.CBModel(ff.Linear(), scpi.solve_ivp, dim) cell_list = [ cl.Cell(0, [0], proliferating=True), cl.Cell(1, [1.0], 0.0, True) ] cell_list[0].division_time = 1.0 cell_list[1].division_time = 1.0 t_data = np.linspace(0, 10, 101) _, history = cbm_solver.simulate(cell_list, t_data, {}, {}, raw_t=False) assert len(history) == len(t_data)
def test_push(): cell = cl.Cell(0, [0, 0]) queue = eventqueue.EventQueue([]) queue.push(1, cell) assert len(queue._events) == 1 assert (1, cell) == queue._events[0] cell2 = cl.Cell(1, [0.25, 0.25]) queue.push(2, cell2) assert len(queue._events) == 2 assert queue._events[0][0] <= queue._events[1][0]
def test_cell_list_order(): # 2D honeycomb mesh n_x = 5 n_y = 5 xcrds = [(2 * i + (j % 2)) * 0.5 for j in range(n_y) for i in range(n_x)] ycrds = [np.sqrt(3) * j * 0.5 for j in range(n_y) for i in range(n_x)] # make cell_list for the sheet sheet = [ cl.Cell(i, [x, y], -6.0, True, lambda t: 6 + t) for i, x, y in zip(range(n_x * n_y), xcrds, ycrds) ] # delete cells to make it circular del sheet[24] del sheet[20] del sheet[19] del sheet[9] del sheet[4] del sheet[0] solver = cbmos.CBModel(ff.Cubic(), ef.solve_ivp, 2) dt = 0.01 t_data = np.arange(0, 3, dt) _, history = solver.simulate(sheet, t_data, {"mu": 6.91}, {'dt': dt}, seed=17) history = history[1:] # delete initial data because that's less cells ids = [cell.ID for cell in history[0]] assert np.all([ids == [cell.ID for cell in clt] for clt in history[1:]])
def test_cell_list_copied(): dim = 1 cbm_solver_one = cbmos.CBModel(ff.Linear(), scpi.solve_ivp, dim) cbm_solver_two = cbmos.CBModel(ff.Linear(), scpi.solve_ivp, dim) cell_list = [ cl.Cell(0, [0], proliferating=True), cl.Cell(1, [0.3], proliferating=True) ] t_data = np.linspace(0, 1, 101) _, history_one = cbm_solver_one.simulate(cell_list, t_data, {}, {}) _, history_two = cbm_solver_two.simulate(cell_list, t_data, {}, {}) assert history_two[0][0].position == np.array([0]) assert history_two[0][1].position == np.array([0.3])
def test_sparse_tdata(): dim = 3 solver_cubic = cbmos.CBModel(ff.Cubic(), ef.solve_ivp, dim) ancestor = [cl.Cell(0, np.zeros((dim, )), -5, True)] dt = 0.1 t_f = 50 t_data = np.linspace(0, t_f, 2) _, tumor_cubic = solver_cubic.simulate(ancestor, t_data, {"mu": 6.91}, {"dt": dt})
def test_cell_dimension_exception(): dim = 3 cbm_solver = cbmos.CBModel(ff.Logarithmic(), ef.solve_ivp, dim) cell_list = [cl.Cell(0, [0, 0], proliferating=True)] t_data = np.linspace(0, 100, 10) with pytest.raises(AssertionError): cbm_solver.simulate(cell_list, t_data, {}, {})
def test_tdata_raw(): n = 100 s = 1.0 # rest length tf = 1.0 # final time rA = 1.5 # maximum interaction distance params_cubic = {"mu": 6.91, "s": s, "rA": rA} solver_ef = cbmos.CBModel(ff.Cubic(), ef.solve_ivp, 1) t_data = np.linspace(0, 1, n) cell_list = [ cl.Cell(0, [0], proliferating=False), cl.Cell(1, [0.3], proliferating=False) ] t_data_sol, sols = solver_ef.simulate(cell_list, t_data, params_cubic, {'dt': 0.03}, raw_t=True) assert len(t_data_sol) == len(sols)
def test_tdata(): n = 100 s = 1.0 # rest length tf = 1.0 # final time rA = 1.5 # maximum interaction distance params_cubic = {"mu": 6.91, "s": s, "rA": rA} solver_ef = cbmos.CBModel(ff.Cubic(), ef.solve_ivp, 1) t_data = np.linspace(0, 1, n) cell_list = [ cl.Cell(0, [0], proliferating=False), cl.Cell(1, [0.3], proliferating=False) ] _, sols = solver_ef.simulate(cell_list, t_data, params_cubic, {'dt': 0.03}, raw_t=False) y = np.array( [np.squeeze([clt[0].position, clt[1].position]) for clt in sols]) assert y.shape == (n, 2)
def test_tdata_raw_division(): n = 100 s = 1.0 # rest length tf = 1.0 # final time rA = 1.5 # maximum interaction distance params_cubic = {"mu": 6.91, "s": s, "rA": rA} solver_ef = cbmos.CBModel(ff.Cubic(), ef.solve_ivp, 1) t_data = np.linspace(0, 50, n) cell_list = [ cl.Cell(0, [0], proliferating=True), cl.Cell(1, [0.3], proliferating=True) ] t_data_sol, sols = solver_ef.simulate(cell_list, t_data, params_cubic, {'dt': 0.03}, raw_t=True) assert len(sols[-1]) > len(cell_list) # Make sure some cells multiplied assert len(t_data_sol) == len(sols) assert all([t[0] < t[1] for t in zip(t_data_sol, t_data_sol[1:])])
def test_update_positions(): dim = 3 cbm_solver = cbmos.CBModel(ff.Linear(), ef.solve_ivp, dim) cell_list = [cl.Cell(i, [0, 0, i]) for i in range(5)] for i, cell in enumerate(cell_list): cell.division_time = cell.ID cbm_solver.cell_list = cell_list new_positions = [[0, i, i] for i in range(5)] cbm_solver._update_positions(new_positions) for i, cell in enumerate(cbm_solver.cell_list): print(cell.position) assert cell.position.tolist() == [0, i, i]
def test_seed(): dim = 3 cbm_solver = cbmos.CBModel(ff.Logarithmic(), ef.solve_ivp, dim) cell_list = [cl.Cell(0, [0, 0, 0], proliferating=True)] t_data = np.linspace(0, 100, 10) histories = [ cbm_solver.simulate(cell_list, t_data, {}, {}, seed=seed)[1] for seed in [0, 0, 1, None, None] ] for cells in zip(*[history[-1] for history in histories]): assert cells[0].position.tolist() == cells[1].position.tolist() assert cells[0].position.tolist() != cells[2].position.tolist() assert cells[3].position.tolist() != cells[4].position.tolist()
def test_min_event_resolution(): dim = 1 cbm_solver = cbmos.CBModel(ff.Linear(), scpi.solve_ivp, dim) cell_list = [ cl.Cell(0, [0], proliferating=True), cl.Cell(1, [1.0], 0.0, True) ] cell_list[0].division_time = 0.25 cell_list[1].division_time = 0.25 t_data = [0, 0.4, 0.6, 1] _, history = cbm_solver.simulate( cell_list, t_data, {}, {}, raw_t=False, min_event_resolution=0.5, ) assert len(history[0]) == 2 assert len(history[1]) == 2 assert len(history[2]) == 4 assert len(history[3]) == 4
def test_constructor(): cells = [cl.Cell(i, [0, 0, i]) for i in range(5)] for i, cell in enumerate(cells): cell.division_time = cell.ID event_list = [(i, cells[i]) for i in reversed(range(5))] queue = eventqueue.EventQueue(event_list) assert len(queue._events) == 5 for i in range(5): t, cell = queue.pop() assert t == i assert len(cell) == 1 assert cell[0].ID == i
def test_parameters(): ID = 17 position = [17.4] birthtime = 0.45 proliferating = True division_time_generator = lambda t: 3 parent_ID = 5 cell = cl.Cell(ID, position, birthtime, proliferating, division_time_generator, None, parent_ID) assert cell.ID == ID assert cell.position == position assert cell.birthtime == birthtime assert cell.proliferating == proliferating assert cell.division_time == division_time_generator(birthtime) assert cell.parent_ID == parent_ID
def test_cell_birth(caplog): logger = logging.getLogger() logs = io.StringIO() logger.addHandler(logging.StreamHandler(logs)) caplog.set_level(logging.DEBUG) dim = 2 cbm_solver = cbmos.CBModel(ff.Cubic(), ef.solve_ivp, dim) cell_list = [ cl.Cell(0, [0, 0], -5.5, True, division_time_generator=lambda t: 6 + t) ] t_data = np.linspace(0, 1, 10) cbm_solver.simulate(cell_list, t_data, {}, {}) division_times = logs.getvalue() assert parse.search("Division event: t={:f}", division_times)[0] == 0.5
def test_seed_division_time(caplog): logger = logging.getLogger() logs = io.StringIO() logger.addHandler(logging.StreamHandler(logs)) caplog.set_level(logging.DEBUG) dim = 3 cbm_solver = cbmos.CBModel(ff.Logarithmic(), ef.solve_ivp, dim) cell_list = [cl.Cell(0, [0, 0, 0], proliferating=True)] t_data = np.linspace(0, 100, 10) history = [ cbm_solver.simulate(cell_list, t_data, {}, {}, seed=seed)[1] for seed in [0, 0, 1] ] division_times = logs.getvalue().split("Starting new simulation\n")[1:] assert division_times[0] == division_times[1] assert division_times[0] != division_times[2]
def test_apply_division(): from cbmos.cbmodel._eventqueue import EventQueue dim = 3 cbm_solver = cbmos.CBModel(ff.Linear(), ef.solve_ivp, dim) cell_list = [cl.Cell(i, [0, 0, i], proliferating=True) for i in range(5)] for i, cell in enumerate(cell_list): cell.division_time = cell.ID cbm_solver.cell_list = cell_list cbm_solver.next_cell_index = 5 cbm_solver._queue = EventQueue([]) cbm_solver._apply_division(cell_list[0], 1) assert len(cbm_solver.cell_list) == 6 assert cbm_solver.cell_list[5].ID == 5 assert cbm_solver.next_cell_index == 6 assert cell_list[0].division_time != 0 assert np.isclose( np.linalg.norm(cell_list[0].position - cell_list[5].position), cbm_solver.separation)