def test_absorb_cytokines(macrophage_list: MacrophageCellList, cyto, grid: RectangularGrid): cyto[1, 2, 3] = 64 macrophage_list.append( MacrophageCellData.create_cell(point=Point(x=grid.x[3], y=grid.y[2], z=grid.z[1]), )) assert len(macrophage_list) == 1 assert cyto[1, 2, 3] == 64 m_abs = 0.5 macrophage_list.absorb_cytokines(m_abs, cyto, grid) assert cyto[1, 2, 3] == 32 macrophage_list.absorb_cytokines(m_abs, cyto, grid) assert cyto[1, 2, 3] == 16 macrophage_list.append( MacrophageCellData.create_cell(point=Point(x=grid.x[3], y=grid.y[2], z=grid.z[1]), )) macrophage_list.absorb_cytokines(m_abs, cyto, grid) assert cyto[1, 2, 3] == 4
def test_absorb_cytokines(neutrophil_list: NeutrophilCellList, cyto, grid: RectangularGrid): cyto[1, 2, 3] = 64 neutrophil_list.append( NeutrophilCellData.create_cell( point=Point(x=grid.x[3], y=grid.y[2], z=grid.z[1]), status=NeutrophilCellData.Status.NONGRANULATING, granule_count=5, ) ) assert len(neutrophil_list) == 1 assert cyto[1, 2, 3] == 64 n_abs = 0.5 neutrophil_list.absorb_cytokines(n_abs, cyto, grid) assert cyto[1, 2, 3] == 32 neutrophil_list.absorb_cytokines(n_abs, cyto, grid) assert cyto[1, 2, 3] == 16 neutrophil_list.append( NeutrophilCellData.create_cell( point=Point(x=grid.x[3], y=grid.y[2], z=grid.z[1]), status=NeutrophilCellData.Status.NONGRANULATING, granule_count=5, ) ) neutrophil_list.absorb_cytokines(n_abs, cyto, grid) assert cyto[1, 2, 3] == 4
def move(self, rec_r, grid, cyto, tissue, fungus: FungusCellList): for cell_index in self.alive(): cell = self[cell_index] cell_voxel = grid.get_voxel(cell['point']) valid_voxel_offsets = [] above_threshold_voxel_offsets = [] # iterate over nearby voxels, recording the cytokine levels for dx, dy, dz in itertools.product((-1, 0, 1), repeat=3): zi = cell_voxel.z + dz yj = cell_voxel.y + dy xk = cell_voxel.x + dx if grid.is_valid_voxel(Voxel(x=xk, y=yj, z=zi)): if tissue[zi, yj, xk] != TissueType.AIR.value: valid_voxel_offsets.append((dx, dy, dz)) if cyto[zi, yj, xk] >= rec_r: above_threshold_voxel_offsets.append( (cyto[zi, yj, xk], (dx, dy, dz))) # pick a target for the move if len(above_threshold_voxel_offsets) > 0: # shuffle + sort (with _only_ 0-key, not lexicographic as tuples) ensures # randomization when there are equal top cytokine levels # note that numpy's shuffle will complain about ragged arrays shuffle(above_threshold_voxel_offsets) above_threshold_voxel_offsets = sorted( above_threshold_voxel_offsets, key=lambda x: x[0], reverse=True) _, target_voxel_offset = above_threshold_voxel_offsets[0] elif len(valid_voxel_offsets) > 0: target_voxel_offset = choice(valid_voxel_offsets) else: raise AssertionError( 'This cell has no valid voxel to move to, including the one that it is in!' ) # Some nonsense here, b/c jump is happening at the voxel level, not the point level starting_cell_point = Point(x=cell['point'][2], y=cell['point'][1], z=cell['point'][0]) starting_cell_voxel = grid.get_voxel(starting_cell_point) ending_cell_voxel = grid.get_voxel( Point( x=grid.x[cell_voxel.x + target_voxel_offset[0]], y=grid.y[cell_voxel.y + target_voxel_offset[1]], z=grid.z[cell_voxel.z + target_voxel_offset[2]], )) ending_cell_point = (starting_cell_point + grid.get_voxel_center(ending_cell_voxel) - grid.get_voxel_center(starting_cell_voxel)) cell['point'] = ending_cell_point self.update_voxel_index([cell_index]) for i in range(0, self.len_phagosome(cell_index)): f_index = cell['phagosome'][i] fungus[f_index]['point'] = ending_cell_point fungus.update_voxel_index([f_index])
def move(self, rec_r, grid, cyto, tissue): for cell_index in self.alive( self.cell_data['status'] == NeutrophilCellData.Status.NONGRANULATING ): # TODO: Algorithm S3.17 says "if degranulating nearby hyphae, do not move" but do # we have the "nearby hyphae" part of this condition? cell = self[cell_index] cell_voxel = grid.get_voxel(cell['point']) valid_voxel_offsets = [] above_threshold_voxel_offsets = [] # iterate over nearby voxels, recording the cytokine levels for dx, dy, dz in itertools.product((-1, 0, 1), repeat=3): zi = cell_voxel.z + dz yj = cell_voxel.y + dy xk = cell_voxel.x + dx if grid.is_valid_voxel(Voxel(x=xk, y=yj, z=zi)): if tissue[zi, yj, xk] != TissueType.AIR.value: valid_voxel_offsets.append((dx, dy, dz)) if cyto[zi, yj, xk] >= rec_r: above_threshold_voxel_offsets.append((cyto[zi, yj, xk], (dx, dy, dz))) # pick a target for the move if len(above_threshold_voxel_offsets) > 0: # shuffle + sort (with _only_ 0-key, not lexicographic as tuples) ensures # randomization when there are equal top cytokine levels # note that numpy's shuffle will complain about ragged arrays shuffle(above_threshold_voxel_offsets) above_threshold_voxel_offsets = sorted( above_threshold_voxel_offsets, key=lambda x: x[0], reverse=True ) _, target_voxel_offset = above_threshold_voxel_offsets[0] elif len(valid_voxel_offsets) > 0: target_voxel_offset = choice(valid_voxel_offsets) else: raise AssertionError( 'This cell has no valid voxel to move to, including the one that it is in!' ) # Some nonsense here, b/c jump is happening at the voxel level, not the point level starting_cell_point = Point(x=cell['point'][2], y=cell['point'][1], z=cell['point'][0]) starting_cell_voxel = grid.get_voxel(starting_cell_point) ending_cell_voxel = grid.get_voxel( Point( x=grid.x[cell_voxel.x + target_voxel_offset[0]], y=grid.y[cell_voxel.y + target_voxel_offset[1]], z=grid.z[cell_voxel.z + target_voxel_offset[2]], ) ) ending_cell_point = ( starting_cell_point + grid.get_voxel_center(ending_cell_voxel) - grid.get_voxel_center(starting_cell_voxel) ) cell['point'] = ending_cell_point self.update_voxel_index([cell_index])
def test_spawn_spores(populated_fungus): points = np.zeros((2, 3)) points[0] = Point(x=5, y=5, z=5) points[1] = Point(x=3, y=3, z=3) populated_fungus.spawn_spores(points) cells = populated_fungus.cell_data assert len(cells) == 7 assert (cells['status'][5:] == FungusCellData.Status.RESTING).all() assert (cells['form'][5:] == FungusCellData.Form.CONIDIA).all()
def get_voxels_in_range(self, point: Point, distance: float) -> Iterator[Tuple[Voxel, float]]: """Return an iterator of voxels within a given distance of a point. The values returned by the iterator are tuples of `(Voxel, distance)` pairs. For example, voxel, distance = next(self.get_voxels_in_range(point, 1)) where `distance` is the distance from `point` to the center of `voxel`. Note: no guarantee is given to the order over which the voxels are iterated. Parameters ---------- point : simulation.coordinates.Point The center point distance : float Return all voxels with centers less than the distance from the center point """ # Get a hyper-square containing a superset of what we want. This # restricts the set of points that we need to explicitly compute. dp = Point(x=distance, y=distance, z=distance) z0, y0, x0 = point - dp z1, y1, x1 = point + dp x0 = max(x0, self.x[0]) x1 = min(x1, self.x[-1]) y0 = max(y0, self.y[0]) y1 = min(y1, self.y[-1]) z0 = max(z0, self.z[0]) z1 = min(z1, self.z[-1]) # get voxel indices of the lower left and upper right corners k0, j0, i0 = self.get_voxel(Point(x=x0, y=y0, z=z0)) k1, j1, i1 = self.get_voxel(Point(x=x1, y=y1, z=z1)) # get a distance matrix over all voxels in the candidate range z, y, x = self.meshgrid dx = x[k0:k1 + 1, j0:j1 + 1, i0:i1 + 1] - point.x dy = y[k0:k1 + 1, j0:j1 + 1, i0:i1 + 1] - point.y dz = z[k0:k1 + 1, j0:j1 + 1, i0:i1 + 1] - point.z distances = np.sqrt(dx * dx + dy * dy + dz * dz) # iterate over all voxels and yield those in range for k in range(distances.shape[0]): for j in range(distances.shape[1]): for i in range(distances.shape[2]): d = distances[k, j, i] if d <= distance: yield Voxel(x=(i + i0), y=(j + j0), z=(k + k0)), d
def test_get_neighboring_cells(grid: RectangularGrid): point = Point(x=4.5, y=4.5, z=4.5) raw_cells = [CellData.create_cell(point=point) for _ in range(5)] raw_cells[1]['point'] = Point(x=-1, y=4.5, z=4.5) raw_cells[4]['point'] = Point(x=4.5, y=4.5, z=-1) cells = CellList(grid=grid) cells.extend(raw_cells) assert_array_equal(cells.get_neighboring_cells(cells[0]), [0, 2, 3]) assert_array_equal(cells.get_cells_in_voxel(Voxel(x=0, y=0, z=0)), [0, 2, 3])
def test_produce_cytokines_n( macrophage_list: MacrophageCellList, grid: RectangularGrid, populated_fungus: FungusCellList, cyto, ): m_n = 10 macrophage_list.append( MacrophageCellData.create_cell(point=Point(x=grid.x[3], y=grid.y[3], z=grid.z[3]), )) vox = grid.get_voxel(macrophage_list[0]['point']) assert vox.z == 3 and vox.y == 3 and vox.x == 3 for cell in populated_fungus.cell_data: vox = grid.get_voxel(cell['point']) assert vox.z in [1, 2, 3, 4, 5] and vox.y in [1, 2, 3, 4, 5] and vox.x in [ 1, 2, 3, 4, 5 ] # 1 m_det = 1 assert cyto[3, 3, 3] == 0 macrophage_list.produce_cytokines(m_det, m_n, grid, populated_fungus, cyto) assert cyto[3, 3, 3] == 30 # 2 m_det = 2 cyto[3, 3, 3] = 0 macrophage_list.produce_cytokines(m_det, m_n, grid, populated_fungus, cyto) assert cyto[3, 3, 3] == 50
def create_macrophage(*, state: State, x: float, y: float, z: float, **kwargs) -> None: """ Create a new macrophage cell Parameters ---------- state : State global simulation state x : float y : float z : float coordinates of created macrophage kwargs parameters for macrophage, will give Returns ------- nothing """ macrophage: MacrophageState = state.macrophage # use default value of iron pool if not present iron_pool = kwargs.get('iron_pool', macrophage.ma_internal_iron) kwargs.pop('iron_pool', None) macrophage.cells.append( MacrophageCellData.create_cell( point=Point(x=x, y=y, z=z), iron_pool=iron_pool, **kwargs, ))
def recruit_new(self, rec_rate_ph, rec_r, granule_count, neutropenic, time, grid, tissue, cyto): num_reps = 0 if not neutropenic: num_reps = rec_rate_ph # number of neutrophils recruited per time step elif neutropenic and 48 <= time <= 96: # TODO: relate 3 to Algorithm S3.14 and rec_rate_ph or introduce neutropenic parameter # In S3.14: num_reps = 6 and int( (time-48)/ 8), both are 1/3 values here num_reps = int((time - 48) / 8) * 3 if num_reps <= 0: return cyto_index = np.argwhere(np.logical_and(tissue == TissueType.BLOOD.value, cyto >= rec_r)) if len(cyto_index) <= 0: # nowhere to place cells return for _ in range(num_reps): ii = rg.integers(cyto_index.shape[0]) point = Point( x=grid.x[cyto_index[ii, 2]], y=grid.y[cyto_index[ii, 1]], z=grid.z[cyto_index[ii, 0]], ) self.append( NeutrophilCellData.create_cell( point=point, status=NeutrophilCellData.Status.NONGRANULATING, granule_count=granule_count, ) )
def test_internalize_conidia_0(macrophage_list: MacrophageCellList, grid: RectangularGrid, fungus_list: FungusCellList): m_det = 0 point = Point(x=35, y=35, z=35) macrophage_list.append(MacrophageCellData.create_cell(point=point)) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) vox = grid.get_voxel(macrophage_list[0]['point']) assert len(fungus_list.get_cells_in_voxel(vox)) == 1 f_index = fungus_list.get_cells_in_voxel(vox) # 0 assert f_index == 0 fungus_list[f_index]['form'] = FungusCellData.Form.CONIDIA fungus_list[f_index]['status'] = FungusCellData.Status.RESTING macrophage_list.internalize_conidia(m_det, 50, 1, grid, fungus_list) assert grid.get_voxel(fungus_list[f_index]['point']) == vox assert fungus_list.cell_data['internalized'][f_index] assert macrophage_list.len_phagosome(0) == 1
def test_produce_cytokines_0( neutrophil_list: NeutrophilCellList, grid: RectangularGrid, populated_fungus: FungusCellList, cyto, ): n_det = 0 n_n = 10 assert cyto[3, 3, 3] == 0 neutrophil_list.append( NeutrophilCellData.create_cell( point=Point(x=grid.x[3], y=grid.y[3], z=grid.z[3]), status=NeutrophilCellData.Status.NONGRANULATING, granule_count=5, ) ) vox = grid.get_voxel(neutrophil_list[0]['point']) assert vox.z == 3 and vox.y == 3 and vox.x == 3 neutrophil_list.produce_cytokines(n_det, n_n, grid, populated_fungus, cyto) assert cyto[3, 3, 3] == 10
def recruit_new(self, rec_rate_ph, rec_r, p_rec_r, tissue, grid, cyto): num_reps = rec_rate_ph # maximum number of macrophages recruited per time step cyto_index = np.argwhere( np.logical_and(tissue == TissueType.BLOOD.value, cyto >= rec_r)) if len(cyto_index) == 0: # nowhere to place cells return for _ in range(num_reps): if p_rec_r > rg.random(): ii = rg.integers(cyto_index.shape[0]) point = Point( x=grid.x[cyto_index[ii, 2]], y=grid.y[cyto_index[ii, 1]], z=grid.z[cyto_index[ii, 0]], ) # Do we really want these things to always be in the exact center of the voxel? # No we do not. Should not have any effect on model, but maybe some on # visualization. perturbation = rg.multivariate_normal(mean=[0.0, 0.0, 0.0], cov=[[0.25, 0.0, 0.0], [0.0, 0.25, 0.0], [0.0, 0.0, 0.25]]) perturbation_magnitude = np.linalg.norm(perturbation) perturbation /= max(1.0, perturbation_magnitude) point += perturbation self.append(MacrophageCellData.create_cell(point=point))
def initialize(self, state: State): epithelium: EpitheliumState = state.epithelium grid: RectangularGrid = state.grid tissue = state.geometry.lung_tissue epithelium.init_health = self.config.getfloat('init_health') epithelium.e_kill = self.config.getfloat('e_kill') epithelium.cyto_rate = self.config.getfloat('cyto_rate') epithelium.s_det = self.config.getint('s_det') epithelium.h_det = self.config.getint('h_det') epithelium.time_e = self.config.getfloat('time_e') epithelium.max_conidia_in_phag = self.config.getint( 'max_conidia_in_phag') epithelium.cells = EpitheliumCellList(grid=grid) epithelium.p_internalization = self.config.getfloat( 'p_internalization') indices = np.argwhere(tissue == TissueTypes.EPITHELIUM.value) for i in range(0, len(indices)): x = grid.x[indices[i][2]] y = grid.y[indices[i][1]] z = grid.z[indices[i][0]] point = Point(x=x, y=y, z=z) epithelium.cells.append( EpitheliumCellData.create_cell(point=point, )) return state
def test_damage_hyphae_conidia( neutrophil_list: NeutrophilCellList, grid: RectangularGrid, fungus_list: FungusCellList, iron ): n_det = 1 n_kill = 2 t = 1 health = 100 point = Point(x=35, y=35, z=35) neutrophil_list.append( NeutrophilCellData.create_cell( point=point, status=NeutrophilCellData.Status.NONGRANULATING, granule_count=5 ) ) # conidia fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING) ) neutrophil_list.damage_hyphae(n_det, n_kill, t, health, grid, fungus_list, iron) assert fungus_list[0]['health'] == 100 assert neutrophil_list[0]['granule_count'] == 5 assert neutrophil_list[0]['status'] == NeutrophilCellData.Status.NONGRANULATING
def test_damage_hyphae_0( neutrophil_list: NeutrophilCellList, grid: RectangularGrid, fungus_list: FungusCellList, iron ): n_det = 0 n_kill = 2 t = 1 health = 100 point = Point(x=35, y=35, z=35) neutrophil_list.append( NeutrophilCellData.create_cell( point=point, status=NeutrophilCellData.Status.NONGRANULATING, granule_count=5 ) ) # hyphae fungus_list.append( FungusCellData.create_cell( point=point, status=FungusCellData.Status.RESTING, form=FungusCellData.Form.HYPHAE ) ) neutrophil_list.damage_hyphae(n_det, n_kill, t, health, grid, fungus_list, iron) assert fungus_list[0]['health'] == 50 assert neutrophil_list[0]['granule_count'] == 4 assert neutrophil_list[0]['status'] == NeutrophilCellData.Status.GRANULATING vox = grid.get_voxel(neutrophil_list[0]['point']) assert iron[vox.z, vox.y, vox.x] == 0
def test_produce_cytokines_n( neutrophil_list: NeutrophilCellList, grid: RectangularGrid, populated_fungus: FungusCellList, cyto, ): n_n = 10 neutrophil_list.append( NeutrophilCellData.create_cell( point=Point(x=grid.x[3], y=grid.y[3], z=grid.z[3]), status=NeutrophilCellData.Status.NONGRANULATING, granule_count=5, ) ) vox = grid.get_voxel(neutrophil_list[0]['point']) assert vox.z == 3 and vox.y == 3 and vox.x == 3 for cell in populated_fungus.cell_data: vox = grid.get_voxel(cell['point']) assert vox.z in [1, 2, 3, 4, 5] and vox.y in [1, 2, 3, 4, 5] and vox.x in [1, 2, 3, 4, 5] # 1 n_det = 1 assert cyto[3, 3, 3] == 0 neutrophil_list.produce_cytokines(n_det, n_n, grid, populated_fungus, cyto) assert cyto[3, 3, 3] == 30 # 2 n_det = 2 cyto[3, 3, 3] = 0 neutrophil_list.produce_cytokines(n_det, n_n, grid, populated_fungus, cyto) assert cyto[3, 3, 3] == 50
def create_neutrophil(state: State, x: float, y: float, z: float, **kwargs) -> None: """ Create a new neutrophil cell Parameters ---------- state : State global simulation state x : float y : float z : float coordinates of created neutrophil kwargs parameters for neutrophil, will give Returns ------- nothing """ neutrophil: NeutrophilState = state.neutrophil # use default value of iron pool if not present iron_pool = kwargs.get('iron_pool', 0.0) kwargs.pop('iron_pool', None) neutrophil.cells.append( NeutrophilCellData.create_cell(point=Point(x=x, y=y, z=z), iron_pool=iron_pool, **kwargs))
def initialize_spores(self, tissue: np.ndarray, init_num: int): """Initialize spores on epithelium cells.""" grid = self.grid if init_num > 0: points = np.zeros((init_num, 3)) indices = np.argwhere(tissue == TissueTypes.EPITHELIUM.value) if len(indices) > 0: rg.shuffle(indices) for i in range(init_num): # putting in some protection for the occasional time that we place the cell on # the boundary of the voxel-space if indices[i][2] == grid.xv.shape[0] - 1: x = grid.xv[indices[i][2]] else: x = rg.uniform(grid.xv[indices[i][2]], grid.xv[indices[i][2] + 1]) if indices[i][1] == grid.yv.shape[0] - 1: y = grid.yv[indices[i][1]] else: y = rg.uniform(grid.yv[indices[i][1]], grid.yv[indices[i][1] + 1]) if indices[i][0] == grid.zv.shape[0] - 1: z = grid.zv[indices[i][0]] else: z = rg.uniform(grid.zv[indices[i][0]], grid.zv[indices[i][0] + 1]) point = Point(x=x, y=y, z=z) points[i] = point self.spawn_spores(points)
def test_kill_epithelium_n(epithelium_list: EpitheliumCellList, grid: RectangularGrid, fungus_list: FungusCellList): # should release all conidia point = Point(x=35, y=35, z=35) epithelium_list.append(EpitheliumCellData.create_cell(point=point)) for _ in range(0, 10): fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) epithelium_list.internalize_conidia(0, 10, 1, grid, fungus_list) epithelium_list.die_by_germination(fungus_list) for i in range(0, 10): assert fungus_list.cell_data['internalized'][i] assert epithelium_list.len_phagosome(0) == 10 fungus_list.cell_data['status'][6] = FungusCellData.Status.GERMINATED epithelium_list.die_by_germination(fungus_list) for i in range(0, 10): assert not fungus_list.cell_data['internalized'][i] assert epithelium_list.len_phagosome(0) == 0
def __init__(self, center: np.ndarray, direction: np.ndarray, radius: float, length: float, type: str): self.center = Point(x=center[0], y=center[1], z=center[2]) self.direction = np.asarray(direction) self.radius = radius self.length = length self.type = type
def test_produce_cytokines_2( epithelium_list: EpitheliumCellList, grid: RectangularGrid, fungus_list: FungusCellList, m_cyto, n_cyto, ): s_det = 1 h_det = 2 cyto_rate = 10 assert m_cyto[3, 3, 3] == 0 assert n_cyto[3, 3, 3] == 0 point = Point(x=35, y=35, z=35) epithelium_list.append(EpitheliumCellData.create_cell(point=point)) spoint = Point(x=15, y=35, z=35) fungus_list.append( FungusCellData.create_cell( point=spoint, status=FungusCellData.Status.SWOLLEN, form=FungusCellData.Form.CONIDIA, iron=0, mobile=False, )) epithelium_list.cytokine_update(s_det, h_det, cyto_rate, m_cyto, n_cyto, fungus_list, grid) assert m_cyto[3, 3, 3] == 0 assert n_cyto[3, 3, 3] == 0 fungus_list.append( FungusCellData.create_cell( point=spoint, status=FungusCellData.Status.GROWABLE, form=FungusCellData.Form.HYPHAE, iron=0, mobile=False, )) epithelium_list.cytokine_update(s_det, h_det, cyto_rate, m_cyto, n_cyto, fungus_list, grid) assert m_cyto[3, 3, 3] == 0 assert n_cyto[3, 3, 3] == 10
def populated_epithelium(epithelium_list: EpitheliumCellList, grid: RectangularGrid): epithelium_list.append( EpitheliumCellData.create_cell(point=Point(x=grid.x[3], y=grid.y[3], z=grid.z[3]), )) yield epithelium_list
def populated_macrophage(macrophage_list: MacrophageCellList, grid: RectangularGrid): macrophage_list.append( MacrophageCellData.create_cell(point=Point(x=grid.x[3], y=grid.y[3], z=grid.z[3]), )) yield macrophage_list
def populated_neutrophil(neutrophil_list: NeutrophilCellList, grid: RectangularGrid): neutrophil_list.append( NeutrophilCellData.create_cell( point=Point(x=grid.x[3], y=grid.y[3], z=grid.z[3]), status=NeutrophilCellData.Status.NONGRANULATING, granule_count=5, ) ) yield neutrophil_list
def test_damage_hyphae_granuleless( neutrophil_list: NeutrophilCellList, grid: RectangularGrid, fungus_list: FungusCellList, iron ): n_det = 1 n_kill = 2 t = 1 health = 100 point = Point(x=35, y=35, z=35) neutrophil_list.append( NeutrophilCellData.create_cell( point=point, status=NeutrophilCellData.Status.NONGRANULATING, granule_count=2 ) ) fungus_list.append( FungusCellData.create_cell( point=point, status=FungusCellData.Status.RESTING, form=FungusCellData.Form.HYPHAE ) ) fungus_list.append( FungusCellData.create_cell( point=Point(x=45, y=35, z=35), status=FungusCellData.Status.RESTING, form=FungusCellData.Form.HYPHAE, ) ) fungus_list.append( FungusCellData.create_cell( point=Point(x=25, y=35, z=35), status=FungusCellData.Status.RESTING, form=FungusCellData.Form.HYPHAE, ) ) neutrophil_list.damage_hyphae(n_det, n_kill, t, health, grid, fungus_list, iron) assert fungus_list[0]['health'] == 50 # one should be 50, the other 100. It doesn't matter which is which assert fungus_list[1]['health'] == 100 or fungus_list[2]['health'] == 100 assert fungus_list[1]['health'] == 50 or fungus_list[2]['health'] == 50 assert neutrophil_list[0]['granule_count'] == 0 assert neutrophil_list[0]['status'] == NeutrophilCellData.Status.NONGRANULATING
def test_internalize_conidia_n(macrophage_list: MacrophageCellList, grid: RectangularGrid, fungus_list: FungusCellList): point = Point(x=35, y=35, z=35) macrophage_list.append(MacrophageCellData.create_cell(point=point)) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) point = Point(x=45, y=35, z=35) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) point = Point(x=55, y=35, z=35) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING)) # internalize some not all macrophage_list.internalize_conidia(1, 50, 1, grid, fungus_list) assert fungus_list.cell_data['internalized'][0] assert fungus_list.cell_data['internalized'][2] assert macrophage_list.len_phagosome(0) == 4 # internalize all macrophage_list.internalize_conidia(2, 50, 1, grid, fungus_list) assert fungus_list.cell_data['internalized'][5] assert macrophage_list.len_phagosome(0) == 6
def test_move_cell(grid: RectangularGrid): point = Point(x=4.5, y=4.5, z=4.5) raw_cells = [CellData.create_cell(point=point) for _ in range(5)] raw_cells[1]['point'] = Point(x=-1, y=4.5, z=4.5) raw_cells[4]['point'] = Point(x=4.5, y=4.5, z=-1) cells = CellList(grid=grid) cells.extend(raw_cells) cells[0]['point'] = Point(x=50, y=50, z=50) # updating an incorrect index will not update the cell at index 0 cells.update_voxel_index([1, 3]) assert_array_equal(cells.get_neighboring_cells(cells[2]), [0, 2, 3]) assert cells._reverse_voxel_index[0] == grid.get_voxel(point) # this should correctly update the voxel index cells.update_voxel_index([0]) assert_array_equal(cells.get_neighboring_cells(cells[0]), [0]) assert cells._reverse_voxel_index[0] == grid.get_voxel(cells[0]['point'])
def initialize(self, state: State): pneumocyte: PneumocyteState = state.pneumocyte voxel_volume: float = state.voxel_volume time_step_size: float = self.time_step lung_tissue: np.ndarray = state.lung_tissue pneumocyte.max_conidia = self.config.getint( 'max_conidia') # units: conidia pneumocyte.time_to_rest = self.config.getint( 'time_to_rest') # units: hours pneumocyte.time_to_change_state = self.config.getint( 'time_to_change_state') # units: hours pneumocyte.p_tnf_qtty = self.config.getfloat( 'p_tnf_qtty') # units: atto-mol * cell^-1 * h^-1 pneumocyte.pr_p_int_param = self.config.getfloat('pr_p_int_param') # computed values pneumocyte.iter_to_rest = int( pneumocyte.time_to_rest * (60 / self.time_step)) # units: hours * (min/hour) / (min/step) = step pneumocyte.iter_to_change_state = int( pneumocyte.time_to_change_state * (60 / self.time_step)) # units: hours * (min/hour) / (min/step) = step pneumocyte.pr_p_int = -math.expm1( -time_step_size / 60 / (voxel_volume * pneumocyte.pr_p_int_param)) # units: probability # initialize cells, placing one per epithelial voxel dz_field: np.ndarray = state.grid.delta(axis=0) dy_field: np.ndarray = state.grid.delta(axis=1) dx_field: np.ndarray = state.grid.delta(axis=2) epithelial_voxels = list( zip(*np.where(lung_tissue == TissueType.EPITHELIUM))) rg.shuffle(epithelial_voxels) for vox_z, vox_y, vox_x in epithelial_voxels[:self.config. getint('count')]: # the x,y,z coordinates are in the centers of the grids z = state.grid.z[vox_z] y = state.grid.y[vox_y] x = state.grid.x[vox_x] dz = dz_field[vox_z, vox_y, vox_x] dy = dy_field[vox_z, vox_y, vox_x] dx = dx_field[vox_z, vox_y, vox_x] pneumocyte.cells.append( PneumocyteCellData.create_cell(point=Point( x=x + rg.uniform(-dx / 2, dx / 2), y=y + rg.uniform(-dy / 2, dy / 2), z=z + rg.uniform(-dz / 2, dz / 2), ))) return state
def create_cell_tuple(cls, *, point: Point = None, dead: bool = False): """Create a tuple of fields attached to a single cell. The base class version of this method returns the fields associated with just the bare cell. Subclasses that append additional attributes onto the cell must override this method to append their own fields to this tuple. Care must be taken to ensure that the order of the tuple is identical to the order of the fields listed in `cls.dtype`. """ if point is None: point = Point() return (point, dead)