Пример #1
0
    def single_step_move(self, state: State, cell: PhagocyteCellData,
                         cell_index: int, cell_list: CellList) -> None:
        """
        Move the phagocyte one 1 µm, probabilistically.

        depending on single_step_probabilistic_drift

        Parameters
        ----------
        state : State
            the global simulation state
        cell : PhagocyteCellData
            the cell to move
        cell_index : int
            index of cell in cell_list
        cell_list : CellList
            the CellList for the cell-type (macrophage/neutrophil/etc) of cell


        Returns
        -------
        nothing
        """
        grid: RectangularGrid = state.grid

        # At this moment, there is no inter-voxel geometry.
        cell_voxel: Voxel = grid.get_voxel(cell['point'])
        new_point: Point = self.single_step_probabilistic_drift(
            state, cell, cell_voxel)
        cell['point'] = new_point
        cell_list.update_voxel_index([cell_index])
Пример #2
0
def test_filter_out_dead(grid: RectangularGrid):
    cells = CellList(grid=grid)
    cells.extend([CellData.create_cell(dead=bool(i % 2)) for i in range(10)])

    assert_array_equal(cells.alive(), [0, 2, 4, 6, 8])
    assert_array_equal(cells.alive([1, 2, 3, 6]), [2, 6])

    mask = np.arange(10) < 5
    assert_array_equal(cells.alive(mask), [0, 2, 4])
Пример #3
0
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'])
Пример #4
0
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])
Пример #5
0
def convert_cells_to_vtk(cells: CellList) -> vtkPolyData:
    cell_data: CellData = cells.cell_data
    live_cells = cells.alive()
    cell_data = cell_data[live_cells]

    fields = dict(cell_data.dtype.fields)  # type: ignore
    fields.pop('point')

    points = vtkPoints()
    poly = vtkPolyData()
    poly.SetPoints(points)

    if not len(cell_data):
        return poly

    # vtk uses coordinate ordering x, y, z while we use z, y, x.
    points.SetData(numpy_to_vtk(np.flip(cell_data['point'], axis=1)))
    point_data = poly.GetPointData()

    for field, (dtype, *_) in fields.items():
        data = cell_data[field]

        # numpy_to_vtk doesn't handle bool for some reason
        if dtype == np.dtype('bool'):
            data = data.astype(np.dtype('uint8'))

        # noinspection PyBroadException
        try:
            scalar = numpy_to_vtk(data)
        except Exception:
            print(f'Unhandled data type in field {field}')
            continue

        scalar.SetName(field)
        point_data.AddArray(scalar)

    return poly
Пример #6
0
def test_out_of_memory_error(grid: RectangularGrid, cell: CellData):
    cell_list = CellList(grid=grid, max_cells=1)
    cell_list.append(cell)

    with raises(Exception):
        cell_list.append(cell)
Пример #7
0
def test_serialize(cell_list: CellList, hdf5_group: Group):
    cell_list_group = cell_list.save(hdf5_group, 'test', {})
    assert cell_list_group['cell_data'].shape == (len(cell_list), )
    assert cell_list_group['cell_data'].dtype == cell_list.cell_data.dtype
Пример #8
0
def cell_list(grid: RectangularGrid, point: Point):
    cells = CellList.create_from_seed(grid=grid, point=point)
    yield cells
Пример #9
0
def interact_with_aspergillus(
    *,
    phagocyte_cell: PhagocyteCellData,
    phagocyte_cell_index: int,
    phagocyte_cells: CellList,
    aspergillus_cell: 'AfumigatusCellData',
    aspergillus_cell_index: int,
    phagocyte: PhagocyteModuleState,
    phagocytize: bool = False,
) -> None:
    """
    Possibly have a phagocyte phagocytize a fungal cell.

    Parameters
    ----------
    phagocyte_cell : PhagocyteCellData
    phagocyte_cell_index: int
    aspergillus_cell : AfumigatusCellData
    aspergillus_cell_index : int
    phagocyte : PhagocyteState
    phagocytize : bool
    """
    from nlisim.modules.afumigatus import AfumigatusCellState, AfumigatusCellStatus

    # We cannot internalize an already internalized fungal cell
    if aspergillus_cell['state'] != AfumigatusCellState.FREE:
        return

    # internalize conidia
    if phagocytize or aspergillus_cell['status'] in {
            AfumigatusCellStatus.RESTING_CONIDIA,
            AfumigatusCellStatus.SWELLING_CONIDIA,
            AfumigatusCellStatus.STERILE_CONIDIA,
    }:
        if phagocyte_cell['status'] not in {
                PhagocyteStatus.NECROTIC,
                PhagocyteStatus.APOPTOTIC,
                PhagocyteStatus.DEAD,
        }:
            # check to see if we have room before we add in another cell to the phagosome
            num_cells_in_phagosome = np.sum(phagocyte_cell['phagosome'] >= 0)
            if num_cells_in_phagosome < phagocyte.max_conidia:
                aspergillus_cell['state'] = AfumigatusCellState.INTERNALIZING
                # place the fungal cell in the phagosome,
                # sorting makes sure that an 'empty' i.e. -1 slot is first
                phagocyte_cell['phagosome'].sort()
                phagocyte_cell['phagosome'][0] = aspergillus_cell_index
                # move the phagocyte to the location of the aspergillus
                phagocyte_cell['point'] = aspergillus_cell['point']
                phagocyte_cells.update_voxel_index([phagocyte_cell_index])

    # All phagocytes are activated by their interaction, except with resting conidia
    if aspergillus_cell['status'] == AfumigatusCellStatus.RESTING_CONIDIA:
        return
    phagocyte_cell['state'] = PhagocyteStatus.INTERACTING
    if phagocyte_cell['status'] != PhagocyteStatus.ACTIVE:
        # non-active phagocytes begin the activation stage
        if phagocyte_cell['status'] != PhagocyteStatus.ACTIVATING:
            # reset the counter, first time only
            phagocyte_cell['status_iteration'] = 0
        phagocyte_cell['status'] = PhagocyteStatus.ACTIVATING
    else:
        # active phagocytes are kept active by resetting their iteration counter
        phagocyte_cell['status_iteration'] = 0