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_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_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 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] != TissueTypes.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 test_iron_uptake(populated_fungus: FungusCellList, iron): iron_min = 5 iron_max = 100 iron_absorb = 0.5 assert iron[5, 5, 5] == 10 populated_fungus.iron_uptake(iron, iron_max, iron_min, iron_absorb) for cell in populated_fungus.cell_data: assert cell['iron'] == 5
def populated_fungus(fungus_list: FungusCellList): points = [] for i in range(10, 60, 10): points.append(Point(x=i, y=i, z=i)) for point in points: fungus_list.append( FungusCellData.create_cell( point=point, status=FungusCellData.Status.GROWABLE, form=FungusCellData.Form.HYPHAE, iron=0, mobile=False, )) yield fungus_list
def test_sporeless30(macrophage_list: MacrophageCellList, grid: RectangularGrid, fungus_list: FungusCellList): # should release all conidia point = Point(x=35, y=35, z=35) for _ in range(0, 30): macrophage_list.append(MacrophageCellData.create_cell(point=point)) fungus_list.append( FungusCellData.create_cell(point=point, status=FungusCellData.Status.RESTING, form=FungusCellData.Form.HYPHAE)) macrophage_list.remove_if_sporeless(0.3) assert len(macrophage_list.alive()) < 30
def damage_hyphae(self, n_det, n_kill, time, health, grid, fungus: FungusCellList, iron): for i in self.alive(self.cell_data['granule_count'] > 0): cell = self[i] vox = grid.get_voxel(cell['point']) # Moore neighborhood, but order partially randomized. Closest to furthest order, but # the order of any set of points of equal distance is random neighborhood = list( itertools.product(tuple(range(-1 * n_det, n_det + 1)), repeat=3)) shuffle(neighborhood) neighborhood = sorted(neighborhood, key=lambda v: v[0]**2 + v[1]**2 + v[2]**2) for dx, dy, dz in neighborhood: zi = vox.z + dz yj = vox.y + dy xk = vox.x + dx if grid.is_valid_voxel(Voxel(x=xk, y=yj, z=zi)): index_arr = fungus.get_cells_in_voxel( Voxel(x=xk, y=yj, z=zi)) if len(index_arr) > 0: iron[zi, yj, xk] = 0 for index in index_arr: if (fungus[index]['form'] == FungusCellData.Form.HYPHAE and cell['granule_count'] > 0): fungus[index]['health'] -= health * (time / n_kill) cell['granule_count'] -= 1 cell[ 'status'] = NeutrophilCellData.Status.GRANULATING elif cell['granule_count'] == 0: cell[ 'status'] = NeutrophilCellData.Status.NONGRANULATING break
def internalize_conidia(self, e_det, max_spores, p_in, grid, spores: FungusCellList): for i in self.alive(): cell = self[i] vox = grid.get_voxel(cell['point']) # Moore neighborhood, but order partially randomized. Closest to furthest order, but # the order of any set of points of equal distance is random neighborhood = list( itertools.product(tuple(range(-1 * e_det, e_det + 1)), repeat=3)) shuffle(neighborhood) neighborhood = sorted(neighborhood, key=lambda v: v[0]**2 + v[1]**2 + v[2]**2) for dx, dy, dz in neighborhood: zi = vox.z + dz yj = vox.y + dy xk = vox.x + dx if grid.is_valid_voxel(Voxel(x=xk, y=yj, z=zi)): index_arr = spores.get_cells_in_voxel( Voxel(x=xk, y=yj, z=zi)) for index in index_arr: if (spores[index]['form'] == FungusCellData.Form.CONIDIA and not spores[index]['internalized'] and p_in > rg.random()): spores[index]['internalized'] = True if self.append_to_phagosome(i, index, max_spores): spores[index]['mobile'] = False else: spores[index]['internalized'] = False
def produce_cytokines(self, m_det, m_n, grid, fungus: FungusCellList, cyto): for i in self.alive(): vox = grid.get_voxel(self[i]['point']) hyphae_count = 0 # Moore neighborhood neighborhood = tuple( itertools.product(tuple(range(-1 * m_det, m_det + 1)), repeat=3)) for dx, dy, dz in neighborhood: zi = vox.z + dz yj = vox.y + dy xk = vox.x + dx if grid.is_valid_voxel(Voxel(x=xk, y=yj, z=zi)): index_arr = fungus.get_cells_in_voxel( Voxel(x=xk, y=yj, z=zi)) for index in index_arr: if fungus[index]['form'] == FungusCellData.Form.HYPHAE: hyphae_count += 1 cyto[vox.z, vox.y, vox.x] = cyto[vox.z, vox.y, vox.x] + m_n * hyphae_count
def test_sporeless1(macrophage_list: MacrophageCellList, grid: RectangularGrid, fungus_list: FungusCellList): # should release all conidia 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)) if len( fungus_list.alive(fungus_list.cell_data['form'] == FungusCellData.Form.CONIDIA)) == 0: macrophage_list.remove_if_sporeless(0.1) assert not macrophage_list.cell_data[0]['dead'] macrophage_list.remove_if_sporeless(0.1) assert macrophage_list.cell_data[0]['dead']
def test_kill_macrophage(macrophage_list: MacrophageCellList, grid: RectangularGrid, fungus_list: FungusCellList): # should release all conidia 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)) macrophage_list.internalize_conidia(1, 50, 1, grid, fungus_list) assert fungus_list.cell_data['internalized'][0] # simulate death macrophage_list.clear_all_phagosome(0, fungus_list) assert not fungus_list.cell_data['internalized'][0] assert macrophage_list.len_phagosome(0) == 0
def test_damage_conidia(macrophage_list: MacrophageCellList, grid: RectangularGrid, fungus_list: FungusCellList): kill = 2 t = 1 health = 100 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)) macrophage_list.internalize_conidia(1, 50, 1, grid, fungus_list) macrophage_list.damage_conidia(kill, t, health, fungus_list) assert fungus_list.cell_data['health'][0] == 50 macrophage_list.damage_conidia(kill, t, health, fungus_list) assert fungus_list.cell_data['health'][0] == 0
def test_internalize_and_move( macrophage_list: MacrophageCellList, grid: RectangularGrid, fungus_list: FungusCellList, cyto, tissue, ): 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)) macrophage_list.internalize_conidia(1, 50, 1, grid, fungus_list) assert fungus_list.cell_data['internalized'][0] assert fungus_list.cell_data['internalized'][1] assert macrophage_list.len_phagosome(0) == 2 rec_r = 10 cell = macrophage_list[0] vox = grid.get_voxel(cell['point']) assert vox.z == 3 and vox.y == 3 and vox.x == 3 assert cyto.all() == 0 cyto[4, 3, 3] = 10 macrophage_list.move(rec_r, grid, cyto, tissue, fungus_list) vox = grid.get_voxel(cell['point']) assert vox.z == 4 and vox.y == 3 and vox.x == 3 for f in fungus_list: vox = grid.get_voxel(f['point']) assert vox.z == 4 and vox.y == 3 and vox.x == 3
def test_update( 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, ) ) neutrophil_list.damage_hyphae(n_det, n_kill, t, health, grid, fungus_list, iron) assert fungus_list[0]['health'] == 50 assert fungus_list[1]['health'] == 50 assert neutrophil_list[0]['granule_count'] == 0 assert neutrophil_list[0]['status'] == NeutrophilCellData.Status.GRANULATING neutrophil_list.update() assert neutrophil_list[0]['status'] == NeutrophilCellData.Status.NONGRANULATING
def test_internalize_conidia_none( populated_macrophage: MacrophageCellList, grid: RectangularGrid, populated_fungus: FungusCellList, ): m_det = 0 cell = populated_macrophage[0] vox = grid.get_voxel(cell['point']) assert len(populated_fungus.get_cells_in_voxel(vox)) == 1 populated_macrophage.internalize_conidia(m_det, 50, 1, grid, populated_fungus) assert populated_macrophage.len_phagosome(0) == 0 for v in cell['phagosome']: assert v == -1
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 fungus_list(grid: RectangularGrid): fungus = FungusCellList(grid=grid) yield fungus
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