Ejemplo n.º 1
0
    def advance(self, state: State, previous_time: float) -> State:
        """Advance the state by a single time step."""
        from nlisim.modules.macrophage import MacrophageState

        hepcidin: HepcidinState = state.hepcidin
        macrophage: MacrophageState = state.macrophage
        voxel_volume: float = state.voxel_volume

        # interaction with macrophages
        activated_voxels = zip(*np.where(
            activation_function(
                x=hepcidin.grid,
                k_d=hepcidin.k_d,
                h=self.time_step / 60,  # units: (min/step) / (min/hour)
                volume=voxel_volume,
                b=1,
            ) > rg.random(size=hepcidin.grid.shape)))
        for z, y, x in activated_voxels:
            for macrophage_cell_index in macrophage.cells.get_cells_in_voxel(
                    Voxel(x=x, y=y, z=z)):
                macrophage_cell = macrophage.cells[macrophage_cell_index]
                macrophage_cell['fpn'] = False
                macrophage_cell['fpn_iteration'] = 0

        # Degrading Hepcidin is done by the "liver"

        # hepcidin does not diffuse

        return state
Ejemplo n.º 2
0
    def advance(self, state: State, previous_time: float) -> State:
        """Advance the state by a single time step."""
        from nlisim.modules.macrophage import MacrophageCellData, MacrophageState
        from nlisim.modules.phagocyte import PhagocyteState, PhagocyteStatus

        il10: IL10State = state.il10
        macrophage: MacrophageState = state.macrophage
        molecules: MoleculesState = state.molecules
        voxel_volume: float = state.voxel_volume
        grid: RectangularGrid = state.grid

        # active Macrophages secrete il10 and non-dead macrophages can become inactivated by il10
        for macrophage_cell_index in macrophage.cells.alive():
            macrophage_cell: MacrophageCellData = macrophage.cells[
                macrophage_cell_index]
            macrophage_cell_voxel: Voxel = grid.get_voxel(
                macrophage_cell['point'])

            if (macrophage_cell['status'] == PhagocyteStatus.ACTIVE and
                    macrophage_cell['state'] == PhagocyteState.INTERACTING):
                il10.grid[tuple(macrophage_cell_voxel
                                )] += il10.macrophage_secretion_rate_unit_t

            if macrophage_cell['status'] not in {
                    PhagocyteStatus.DEAD,
                    PhagocyteStatus.APOPTOTIC,
                    PhagocyteStatus.NECROTIC,
            } and (activation_function(
                    x=il10.grid[tuple(macrophage_cell_voxel)],
                    k_d=il10.k_d,
                    h=self.time_step / 60,  # units: (min/step) / (min/hour)
                    volume=voxel_volume,
                    b=1,
            ) > rg.uniform()):
                # inactive cells stay inactive, others become inactivating
                if macrophage_cell['status'] != PhagocyteStatus.INACTIVE:
                    macrophage_cell['status'] = PhagocyteStatus.INACTIVATING
                macrophage_cell['status_iteration'] = 0

        # Degrade IL10
        il10.grid *= il10.half_life_multiplier
        il10.grid *= turnover_rate(
            x=np.ones(shape=il10.grid.shape, dtype=np.float64),
            x_system=0.0,
            base_turnover_rate=molecules.turnover_rate,
            rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t,
        )

        # Diffusion of IL10
        il10.grid[:] = apply_diffusion(
            variable=il10.grid,
            laplacian=molecules.laplacian,
            diffusivity=molecules.diffusion_constant,
            dt=self.time_step,
        )

        return state
Ejemplo n.º 3
0
    def single_step_probabilistic_drift(self, state: State,
                                        cell: PhagocyteCellData,
                                        voxel: Voxel) -> Point:
        """
        Calculate a 1µm movement of a neutrophil

        Parameters
        ----------
        state : State
            global simulation state
        cell : NeutrophilCellData
            a neutrophil cell
        voxel : Voxel
            current voxel position of the neutrophil

        Returns
        -------
        Point
            the new position of the neutrophil
        """
        # neutrophils are attracted by MIP2

        neutrophil: NeutrophilState = state.neutrophil
        mip2: MIP2State = state.mip2
        grid: RectangularGrid = state.grid
        lung_tissue: np.ndarray = state.lung_tissue
        voxel_volume: float = state.voxel_volume

        # neutrophil has a non-zero probability of moving into non-air voxels
        nearby_voxels: Tuple[Voxel,
                             ...] = tuple(grid.get_adjacent_voxels(voxel))
        weights = np.array(
            [
                0.0 if lung_tissue[tuple(vxl)] == TissueType.AIR else
                activation_function(
                    x=mip2.grid[tuple(vxl)],
                    k_d=mip2.k_d,
                    h=self.time_step / 60,  # units: (min/step) / (min/hour)
                    volume=voxel_volume,
                    b=1,
                ) + neutrophil.drift_bias for vxl in nearby_voxels
            ],
            dtype=np.float64,
        )

        voxel_movement_direction: Voxel = choose_voxel_by_prob(
            voxels=nearby_voxels, default_value=voxel, weights=weights)

        # get normalized direction vector
        dp_dt: np.ndarray = grid.get_voxel_center(
            voxel_movement_direction) - grid.get_voxel_center(voxel)
        norm = np.linalg.norm(dp_dt)
        if norm > 0.0:
            dp_dt /= norm

        return cell['point'] + dp_dt
Ejemplo n.º 4
0
    def advance(self, state: State, previous_time: float) -> State:
        """Advance the state by a single time step."""
        from nlisim.modules.neutrophil import NeutrophilCellData, NeutrophilState
        from nlisim.modules.phagocyte import PhagocyteStatus

        il8: IL8State = state.il8
        molecules: MoleculesState = state.molecules
        neutrophil: NeutrophilState = state.neutrophil
        voxel_volume: float = state.voxel_volume
        grid: RectangularGrid = state.grid

        # IL8 activates neutrophils
        for neutrophil_cell_index in neutrophil.cells.alive():
            neutrophil_cell: NeutrophilCellData = neutrophil.cells[
                neutrophil_cell_index]
            if neutrophil_cell['status'] in {
                    PhagocyteStatus.RESTING or PhagocyteStatus.ACTIVE
            }:
                neutrophil_cell_voxel: Voxel = grid.get_voxel(
                    neutrophil_cell['point'])
                if (activation_function(
                        x=il8.grid[tuple(neutrophil_cell_voxel)],
                        k_d=il8.k_d,
                        h=self.time_step /
                        60,  # units: (min/step) / (min/hour)
                        volume=voxel_volume,
                        b=1,
                ) > rg.uniform()):
                    neutrophil_cell['status'] = PhagocyteStatus.ACTIVE
                    neutrophil_cell['status_iteration'] = 0

        # Degrade IL8
        il8.grid *= il8.half_life_multiplier
        il8.grid *= turnover_rate(
            x=np.ones(shape=il8.grid.shape, dtype=np.float64),
            x_system=0.0,
            base_turnover_rate=molecules.turnover_rate,
            rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t,
        )

        # Diffusion of IL8
        il8.grid[:] = apply_diffusion(
            variable=il8.grid,
            laplacian=molecules.laplacian,
            diffusivity=molecules.diffusion_constant,
            dt=self.time_step,
        )

        return state
Ejemplo n.º 5
0
    def advance(self, state: State, previous_time: float):
        erythrocyte: ErythrocyteState = state.erythrocyte
        molecules: MoleculesState = state.molecules
        hemoglobin: HemoglobinState = state.hemoglobin
        hemolysin: HemolysinState = state.hemolysin
        macrophage: MacrophageState = state.macrophage
        afumigatus: AfumigatusState = state.afumigatus
        grid: RectangularGrid = state.grid
        voxel_volume: float = state.voxel_volume

        shape = erythrocyte.cells['count'].shape

        # erythrocytes replenish themselves
        avg_number_of_new_erythrocytes = (1 - molecules.turnover_rate) * (
            1 - erythrocyte.cells['count'] / erythrocyte.max_erythrocyte_voxel)
        mask = avg_number_of_new_erythrocytes > 0
        erythrocyte.cells['count'][mask] += np.random.poisson(
            avg_number_of_new_erythrocytes[mask],
            avg_number_of_new_erythrocytes[mask].shape)

        # ---------- interactions

        # uptake hemoglobin
        erythrocyte.cells['hemoglobin'] += hemoglobin.grid
        hemoglobin.grid.fill(0.0)

        # interact with hemolysin. pop goes the blood cell
        # TODO: avg? variable name improvement?
        avg_lysed_erythrocytes = erythrocyte.cells[
            'count'] * activation_function(
                x=hemolysin.grid,
                k_d=erythrocyte.kd_hemo,
                h=self.time_step / 60,  # units: (min/step) / (min/hour)
                volume=voxel_volume,
                b=1,
            )
        number_lysed = np.minimum(
            np.random.poisson(avg_lysed_erythrocytes, shape),
            erythrocyte.cells['count'])
        erythrocyte.cells[
            'hemoglobin'] += number_lysed * erythrocyte.hemoglobin_quantity
        erythrocyte.cells['count'] -= number_lysed

        # interact with Macrophage
        erythrocytes_to_hemorrhage = erythrocyte.cells[
            'hemorrhage'] * np.random.poisson(
                erythrocyte.pr_macrophage_phagocytize_erythrocyte *
                erythrocyte.cells['count'], shape)

        for z, y, x in zip(*np.where(erythrocytes_to_hemorrhage > 0)):
            local_macrophages = macrophage.cells.get_cells_in_voxel(
                Voxel(x=x, y=y, z=z))
            num_local_macrophages = len(local_macrophages)
            for macrophage_index in local_macrophages:
                macrophage_cell = macrophage.cells[macrophage_index]
                if macrophage_cell['dead']:
                    continue
                macrophage_cell['iron_pool'] += (
                    4  # number of iron atoms in hemoglobin
                    * erythrocyte.hemoglobin_quantity *
                    erythrocytes_to_hemorrhage[z, y, x] /
                    num_local_macrophages)
        erythrocyte.cells['count'] -= erythrocytes_to_hemorrhage

        # interact with fungus
        for fungal_cell_index in afumigatus.cells.alive():
            fungal_cell = afumigatus.cells[fungal_cell_index]
            if fungal_cell['status'] == AfumigatusCellStatus.HYPHAE:
                fungal_voxel: Voxel = grid.get_voxel(fungal_cell['point'])
                erythrocyte.cells['hemorrhage'][tuple(fungal_voxel)] = True

        return state
Ejemplo n.º 6
0
    def advance(self, state: State, previous_time: float) -> State:
        """Advance the state by a single time step."""
        from nlisim.modules.macrophage import MacrophageCellData, MacrophageState
        from nlisim.modules.neutrophil import NeutrophilCellData, NeutrophilState
        from nlisim.modules.phagocyte import PhagocyteStatus
        from nlisim.modules.pneumocyte import PneumocyteCellData, PneumocyteState

        mip2: MIP2State = state.mip2
        molecules: MoleculesState = state.molecules
        neutrophil: NeutrophilState = state.neutrophil
        pneumocyte: PneumocyteState = state.pneumocyte
        macrophage: MacrophageState = state.macrophage
        grid: RectangularGrid = state.grid
        voxel_volume = state.voxel_volume

        # interact with neutrophils
        neutrophil_activation: np.ndarray = activation_function(
            x=mip2.grid,
            k_d=mip2.k_d,
            h=self.time_step / 60,  # units: (min/step) / (min/hour)
            volume=voxel_volume,
            b=1,
        )
        for neutrophil_cell_index in neutrophil.cells.alive():
            neutrophil_cell: NeutrophilCellData = neutrophil.cells[neutrophil_cell_index]
            neutrophil_cell_voxel: Voxel = grid.get_voxel(neutrophil_cell['point'])

            if (
                neutrophil_cell['status'] == PhagocyteStatus.RESTING
                and neutrophil_activation[tuple(neutrophil_cell_voxel)] > rg.uniform()
            ):
                neutrophil_cell['status'] = PhagocyteStatus.ACTIVATING
                neutrophil_cell['status_iteration'] = 0
            elif neutrophil_cell['tnfa']:
                mip2.grid[tuple(neutrophil_cell_voxel)] += mip2.neutrophil_secretion_rate_unit_t
                if neutrophil_activation[tuple(neutrophil_cell_voxel)] > rg.uniform():
                    neutrophil_cell['status_iteration'] = 0

        # interact with pneumocytes
        for pneumocyte_cell_index in pneumocyte.cells.alive():
            pneumocyte_cell: PneumocyteCellData = pneumocyte.cells[pneumocyte_cell_index]

            if pneumocyte_cell['tnfa']:
                pneumocyte_cell_voxel: Voxel = grid.get_voxel(pneumocyte_cell['point'])
                mip2.grid[tuple(pneumocyte_cell_voxel)] += mip2.pneumocyte_secretion_rate_unit_t

        # interact with macrophages
        for macrophage_cell_index in macrophage.cells.alive():
            macrophage_cell: MacrophageCellData = macrophage.cells[macrophage_cell_index]

            if macrophage_cell['tnfa']:
                macrophage_cell_voxel: Voxel = grid.get_voxel(macrophage_cell['point'])
                mip2.grid[tuple(macrophage_cell_voxel)] += mip2.macrophage_secretion_rate_unit_t

        # Degrade MIP2
        mip2.grid *= mip2.half_life_multiplier
        mip2.grid *= turnover_rate(
            x=np.array(1.0, dtype=np.float64),
            x_system=0.0,
            base_turnover_rate=molecules.turnover_rate,
            rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t,
        )

        # Diffusion of MIP2
        mip2.grid[:] = apply_diffusion(
            variable=mip2.grid,
            laplacian=molecules.laplacian,
            diffusivity=molecules.diffusion_constant,
            dt=self.time_step,
        )

        return state
Ejemplo n.º 7
0
    def single_step_probabilistic_drift(self, state: State,
                                        cell: PhagocyteCellData,
                                        voxel: Voxel) -> Point:
        """
        Calculate a 1µm movement of a macrophage

        Parameters
        ----------
        state : State
            global simulation state
        cell : MacrophageCellData
            a macrophage cell
        voxel : Voxel
            current voxel position of the macrophage

        Returns
        -------
        Point
            the new position of the macrophage
        """
        # macrophages are attracted by MIP1b
        from nlisim.modules.mip1b import MIP1BState
        from nlisim.util import TissueType, activation_function

        macrophage: MacrophageState = state.macrophage
        mip1b: MIP1BState = state.mip1b
        grid: RectangularGrid = state.grid
        lung_tissue: np.ndarray = state.lung_tissue
        voxel_volume: float = state.voxel_volume

        # compute chemokine influence on velocity, with some randomness.
        # macrophage has a non-zero probability of moving into non-air voxels.
        # if not any of these, stay in place. This could happen if e.g. you are
        # somehow stranded in air.
        nearby_voxels: Tuple[Voxel, ...] = tuple(
            grid.get_adjacent_voxels(voxel, corners=True))
        weights = np.array(
            [
                0.0 if lung_tissue[tuple(vxl)] == TissueType.AIR else
                activation_function(
                    x=mip1b.grid[tuple(vxl)],
                    k_d=mip1b.k_d,
                    h=self.time_step / 60,  # units: (min/step) / (min/hour)
                    volume=voxel_volume,
                    b=1,
                ) + macrophage.drift_bias for vxl in nearby_voxels
            ],
            dtype=np.float64,
        )

        voxel_movement_direction: Voxel = choose_voxel_by_prob(
            voxels=nearby_voxels, default_value=voxel, weights=weights)

        # get normalized direction vector
        dp_dt: np.ndarray = grid.get_voxel_center(
            voxel_movement_direction) - grid.get_voxel_center(voxel)
        norm = np.linalg.norm(dp_dt)
        if norm > 0.0:
            dp_dt /= norm

        # average and re-normalize with existing velocity
        dp_dt += cell['velocity']
        norm = np.linalg.norm(dp_dt)
        if norm > 0.0:
            dp_dt /= norm

        # we need to determine if this movement will put us into an air voxel. This can happen
        # when pushed there by momentum. If that happens, we stay in place and zero out the
        # momentum. Otherwise, velocity is updated to dp/dt and movement is as expected.
        new_position = cell['point'] + dp_dt
        new_voxel: Voxel = grid.get_voxel(new_position)
        if state.lung_tissue[tuple(new_voxel)] == TissueType.AIR:
            cell['velocity'][:] = np.zeros(3, dtype=np.float64)
            return cell['point']
        else:
            cell['velocity'][:] = dp_dt
            return new_position
Ejemplo n.º 8
0
    def recruit_macrophages(self, state: State) -> None:
        """
        Recruit macrophages based on MIP1b activation

        Parameters
        ----------
        state : State
            global simulation state

        Returns
        -------
        nothing
        """
        from nlisim.modules.mip1b import MIP1BState
        from nlisim.util import TissueType, activation_function

        macrophage: MacrophageState = state.macrophage
        mip1b: MIP1BState = state.mip1b
        voxel_volume: float = state.voxel_volume
        space_volume: float = state.space_volume
        lung_tissue = state.lung_tissue

        # 1. compute number of macrophages to recruit
        num_live_macrophages = len(macrophage.cells.alive())
        avg = (macrophage.recruitment_rate * np.sum(mip1b.grid) *
               (1 - num_live_macrophages / macrophage.max_ma) /
               (mip1b.k_d * space_volume))
        number_to_recruit = max(
            np.random.poisson(avg) if avg > 0 else 0,
            macrophage.min_ma - num_live_macrophages)
        # 2. get voxels for new macrophages, based on activation
        if number_to_recruit > 0:
            activation_voxels = zip(*np.where(
                np.logical_and(
                    activation_function(
                        x=mip1b.grid,
                        k_d=mip1b.k_d,
                        h=self.time_step / 60,
                        volume=voxel_volume,
                        b=macrophage.rec_bias,
                    ) < rg.uniform(size=mip1b.grid.shape),
                    lung_tissue != TissueType.AIR,
                )))
            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)
            for coordinates in rg.choice(tuple(activation_voxels),
                                         size=number_to_recruit,
                                         replace=True):
                vox_z, vox_y, vox_x = coordinates
                # 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]
                self.create_macrophage(
                    state=state,
                    x=x + rg.uniform(-dx / 2, dx / 2),
                    y=y + rg.uniform(-dy / 2, dy / 2),
                    z=z + rg.uniform(-dz / 2, dz / 2),
                )
Ejemplo n.º 9
0
    def advance(self, state: State, previous_time: float) -> State:
        """Advance the state by a single time step."""
        from nlisim.modules.macrophage import MacrophageCellData, MacrophageState
        from nlisim.modules.neutrophil import NeutrophilCellData, NeutrophilState
        from nlisim.modules.phagocyte import PhagocyteStatus

        tnfa: TNFaState = state.tnfa
        molecules: MoleculesState = state.molecules
        macrophage: MacrophageState = state.macrophage
        neutrophil: NeutrophilState = state.neutrophil
        voxel_volume: float = state.voxel_volume
        grid: RectangularGrid = state.grid

        for macrophage_cell_index in macrophage.cells.alive():
            macrophage_cell: MacrophageCellData = macrophage.cells[macrophage_cell_index]
            macrophage_cell_voxel: Voxel = grid.get_voxel(macrophage_cell['point'])

            if macrophage_cell['status'] == PhagocyteStatus.ACTIVE:
                tnfa.grid[tuple(macrophage_cell_voxel)] += tnfa.macrophage_secretion_rate_unit_t

            if macrophage_cell['status'] in {PhagocyteStatus.RESTING, PhagocyteStatus.ACTIVE}:
                if (
                    activation_function(
                        x=tnfa.grid[tuple(macrophage_cell_voxel)],
                        k_d=tnfa.k_d,
                        h=self.time_step / 60,  # units: (min/step) / (min/hour)
                        volume=voxel_volume,
                        b=1,
                    )
                    > rg.uniform()
                ):
                    if macrophage_cell['status'] == PhagocyteStatus.RESTING:
                        macrophage_cell['status'] = PhagocyteStatus.ACTIVATING
                    else:
                        macrophage_cell['status'] = PhagocyteStatus.ACTIVE
                    # Note: multiple activations will reset the 'clock'
                    macrophage_cell['status_iteration'] = 0
                    macrophage_cell['tnfa'] = True

        for neutrophil_cell_index in neutrophil.cells.alive():
            neutrophil_cell: NeutrophilCellData = neutrophil.cells[neutrophil_cell_index]
            neutrophil_cell_voxel: Voxel = grid.get_voxel(neutrophil_cell['point'])

            if neutrophil_cell['status'] == PhagocyteStatus.ACTIVE:
                tnfa.grid[tuple(neutrophil_cell_voxel)] += tnfa.neutrophil_secretion_rate_unit_t

            if neutrophil_cell['status'] in {PhagocyteStatus.RESTING, PhagocyteStatus.ACTIVE}:
                if (
                    activation_function(
                        x=tnfa.grid[tuple(neutrophil_cell_voxel)],
                        k_d=tnfa.k_d,
                        h=self.time_step / 60,  # units: (min/step) / (min/hour)
                        volume=voxel_volume,
                        b=1,
                    )
                    > rg.uniform()
                ):
                    if neutrophil_cell['status'] == PhagocyteStatus.RESTING:
                        neutrophil_cell['status'] = PhagocyteStatus.ACTIVATING
                    else:
                        neutrophil_cell['status'] = PhagocyteStatus.ACTIVE
                    # Note: multiple activations will reset the 'clock'
                    neutrophil_cell['status_iteration'] = 0
                    neutrophil_cell['tnfa'] = True

        # Degrade TNFa
        tnfa.grid *= tnfa.half_life_multiplier
        tnfa.grid *= turnover_rate(
            x=np.array(1.0, dtype=np.float64),
            x_system=0.0,
            base_turnover_rate=molecules.turnover_rate,
            rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t,
        )

        # Diffusion of TNFa
        tnfa.grid[:] = apply_diffusion(
            variable=tnfa.grid,
            laplacian=molecules.laplacian,
            diffusivity=molecules.diffusion_constant,
            dt=self.time_step,
        )

        return state
Ejemplo n.º 10
0
    def advance(self, state: State, previous_time: float):
        """Advance the state by a single time step."""
        from nlisim.modules.afumigatus import (
            AfumigatusCellData,
            AfumigatusCellStatus,
            AfumigatusState,
        )

        # from nlisim.modules.il6 import IL6State
        # from nlisim.modules.il8 import IL8State
        from nlisim.modules.tnfa import TNFaState

        pneumocyte: PneumocyteState = state.pneumocyte
        afumigatus: AfumigatusState = state.afumigatus
        # il6: IL6State = getattr(state, 'il6', None)
        # il8: IL8State = getattr(state, 'il8', None)
        tnfa: TNFaState = state.tnfa
        grid: RectangularGrid = state.grid
        voxel_volume: float = state.voxel_volume

        for pneumocyte_cell_index in pneumocyte.cells.alive():
            pneumocyte_cell = pneumocyte.cells[pneumocyte_cell_index]
            pneumocyte_cell_voxel: Voxel = grid.get_voxel(
                pneumocyte_cell['point'])

            # self update
            if pneumocyte_cell['status'] == PhagocyteStatus.ACTIVE:
                if pneumocyte_cell[
                        'status_iteration'] >= pneumocyte.iter_to_rest:
                    pneumocyte_cell['status_iteration'] = 0
                    pneumocyte_cell['status'] = PhagocyteStatus.RESTING
                    pneumocyte_cell['tnfa'] = False
                else:
                    pneumocyte_cell['status_iteration'] += 1

            elif pneumocyte_cell['status'] == PhagocyteStatus.ACTIVATING:
                if pneumocyte_cell[
                        'status_iteration'] >= pneumocyte.iter_to_change_state:
                    pneumocyte_cell['status_iteration'] = 0
                    pneumocyte_cell['status'] = PhagocyteStatus.ACTIVE
                else:
                    pneumocyte_cell['status_iteration'] += 1

            # ----------- interactions

            # interact with fungus
            if pneumocyte_cell['status'] not in {
                    PhagocyteStatus.APOPTOTIC,
                    PhagocyteStatus.NECROTIC,
                    PhagocyteStatus.DEAD,
            }:
                local_aspergillus = afumigatus.cells.get_cells_in_voxel(
                    pneumocyte_cell_voxel)
                for aspergillus_index in local_aspergillus:
                    aspergillus_cell: AfumigatusCellData = afumigatus.cells[
                        aspergillus_index]

                    # skip resting conidia
                    if aspergillus_cell[
                            'status'] == AfumigatusCellStatus.RESTING_CONIDIA:
                        continue

                    if pneumocyte_cell['status'] != PhagocyteStatus.ACTIVE:
                        if rg.uniform() < pneumocyte.pr_p_int:
                            pneumocyte_cell[
                                'status'] = PhagocyteStatus.ACTIVATING
                    else:
                        # TODO: I don't get this, looks like it zeros out the iteration
                        #  when activating
                        pneumocyte_cell['status_iteration'] = 0

            # # secrete IL6
            # if il6 is not None and pneumocyte_cell['status'] == PhagocyteStatus.ACTIVE:
            #     il6.grid[tuple(pneumocyte_cell_voxel)] += pneumocyte.p_il6_qtty
            #
            # # secrete IL8
            # if il8 is not None and pneumocyte_cell['tnfa']:
            #     il8.grid[tuple(pneumocyte_cell_voxel)] += pneumocyte.p_il8_qtty

            # interact with TNFa
            if pneumocyte_cell['status'] == PhagocyteStatus.ACTIVE:
                if (activation_function(
                        x=tnfa.grid[tuple(pneumocyte_cell_voxel)],
                        k_d=tnfa.k_d,
                        h=self.time_step /
                        60,  # units: (min/step) / (min/hour)
                        volume=voxel_volume,
                        b=1,
                ) < rg.uniform()):
                    pneumocyte_cell['status_iteration'] = 0
                    pneumocyte_cell['tnfa'] = True

                # secrete TNFa
                tnfa.grid[tuple(
                    pneumocyte_cell_voxel)] += pneumocyte.p_tnf_qtty

        return state
Ejemplo n.º 11
0
    def advance(self, state: State, previous_time: float) -> State:
        """Advance the state by a single time step."""
        from nlisim.modules.macrophage import MacrophageCellData, MacrophageState
        from nlisim.modules.phagocyte import PhagocyteStatus

        tgfb: TGFBState = state.tgfb
        molecules: MoleculesState = state.molecules
        macrophage: MacrophageState = state.macrophage
        voxel_volume: float = state.voxel_volume
        grid: RectangularGrid = state.grid

        for macrophage_cell_index in macrophage.cells.alive():
            macrophage_cell: MacrophageCellData = macrophage.cells[
                macrophage_cell_index]
            macrophage_cell_voxel: Voxel = grid.get_voxel(
                macrophage_cell['point'])

            if macrophage_cell['status'] == PhagocyteStatus.INACTIVE:
                tgfb.grid[tuple(macrophage_cell_voxel
                                )] += tgfb.macrophage_secretion_rate_unit_t
                if (activation_function(
                        x=tgfb.grid[tuple(macrophage_cell_voxel)],
                        k_d=tgfb.k_d,
                        h=self.time_step /
                        60,  # units: (min/step) / (min/hour)
                        volume=voxel_volume,
                        b=1,
                ) > rg.uniform()):
                    macrophage_cell['status_iteration'] = 0

            elif macrophage_cell['status'] not in {
                    PhagocyteStatus.APOPTOTIC,
                    PhagocyteStatus.NECROTIC,
                    PhagocyteStatus.DEAD,
            }:
                if (activation_function(
                        x=tgfb.grid[tuple(macrophage_cell_voxel)],
                        k_d=tgfb.k_d,
                        h=self.time_step /
                        60,  # units: (min/step) / (min/hour)
                        volume=voxel_volume,
                        b=1,
                ) > rg.uniform()):
                    macrophage_cell['status'] = PhagocyteStatus.INACTIVATING
                    macrophage_cell[
                        'status_iteration'] = 0  # Previously, was no reset of the status iteration

        # Degrade TGFB
        tgfb.grid *= tgfb.half_life_multiplier
        tgfb.grid *= turnover_rate(
            x=np.array(1.0, dtype=np.float64),
            x_system=0.0,
            base_turnover_rate=molecules.turnover_rate,
            rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t,
        )

        # Diffusion of TGFB
        tgfb.grid[:] = apply_diffusion(
            variable=tgfb.grid,
            laplacian=molecules.laplacian,
            diffusivity=molecules.diffusion_constant,
            dt=self.time_step,
        )

        return state
Ejemplo n.º 12
0
    def recruit_neutrophils(self, state: State, space_volume: float,
                            voxel_volume: float) -> None:
        """
        Recruit neutrophils based on MIP2 activation

        Parameters
        ----------
        state : State
            global simulation state
        space_volume : float
        voxel_volume : float

        Returns
        -------
        nothing
        """
        from nlisim.modules.mip2 import MIP2State
        from nlisim.util import TissueType, activation_function

        neutrophil: NeutrophilState = state.neutrophil
        mip2: MIP2State = state.mip2
        lung_tissue = state.lung_tissue

        # 1. compute number of neutrophils to recruit
        num_live_neutrophils = len(neutrophil.cells.alive())
        avg = (neutrophil.recruitment_rate * neutrophil.n_frac *
               np.sum(mip2.grid) *
               (1 - num_live_neutrophils / neutrophil.max_neutrophils) /
               (mip2.k_d * space_volume))
        number_to_recruit = np.random.poisson(avg) if avg > 0 else 0
        if number_to_recruit <= 0:
            return
        # 2. get voxels for new macrophages, based on activation
        activation_voxels = tuple(
            zip(*np.where(
                np.logical_and(
                    activation_function(
                        x=mip2.grid,
                        k_d=mip2.k_d,
                        h=self.time_step /
                        60,  # units: (min/step) / (min/hour)
                        volume=voxel_volume,
                        b=neutrophil.rec_bias,
                    ) < rg.uniform(size=mip2.grid.shape),
                    lung_tissue != TissueType.AIR,
                ))))

        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)
        for coordinates in rg.choice(activation_voxels,
                                     size=number_to_recruit,
                                     replace=True):
            vox_z, vox_y, vox_x = coordinates
            # 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]
            self.create_neutrophil(
                state=state,
                x=x + rg.uniform(-dx / 2, dx / 2),
                y=y + rg.uniform(-dy / 2, dy / 2),
                z=z + rg.uniform(-dz / 2, dz / 2),
            )