def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.molecules import MoleculesState ros: ROSState = state.ros molecules: MoleculesState = state.molecules # TODO: code below adds zero, omitting until we have a non-trivial model # elif type(interactable) is Macrophage: # assert isinstance(interactable, Macrophage) # macrophage: Macrophage = interactable # # if macrophage.status == Macrophage.ACTIVE: # self.increase(0, x, y, z) # return True # Degrade ROS (does not degrade) (obsolete, will be reintroduced later) # Diffusion of ros ros.grid[:] = apply_diffusion( variable=ros.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.macrophage import MacrophageState from nlisim.modules.neutrophil import NeutrophilState from nlisim.modules.phagocyte import PhagocyteStatus from nlisim.modules.pneumocyte import PneumocyteState il6: IL6State = state.il6 molecules: MoleculesState = state.molecules macrophage: MacrophageState = state.macrophage neutrophil: NeutrophilState = state.neutrophil pneumocyte: PneumocyteState = state.pneumocyte grid: RectangularGrid = state.grid # active Macrophages secrete il6 for macrophage_cell_index in macrophage.cells.alive(): macrophage_cell = macrophage.cells[macrophage_cell_index] if macrophage_cell['status'] == PhagocyteStatus.ACTIVE: macrophage_cell_voxel: Voxel = grid.get_voxel( macrophage_cell['point']) il6.grid[tuple(macrophage_cell_voxel )] += il6.macrophage_secretion_rate_unit_t # active Neutrophils secrete il6 for neutrophil_cell_index in neutrophil.cells.alive(): neutrophil_cell = neutrophil.cells[neutrophil_cell_index] if neutrophil_cell['status'] == PhagocyteStatus.ACTIVE: neutrophil_cell_voxel: Voxel = grid.get_voxel( neutrophil_cell['point']) il6.grid[tuple(neutrophil_cell_voxel )] += il6.neutrophil_secretion_rate_unit_t # active Pneumocytes secrete il6 for pneumocyte_cell_index in pneumocyte.cells.alive(): pneumocyte_cell = pneumocyte.cells[pneumocyte_cell_index] if pneumocyte_cell['status'] == PhagocyteStatus.ACTIVE: pneumocyte_cell_voxel: Voxel = grid.get_voxel( pneumocyte_cell['point']) il6.grid[tuple(pneumocyte_cell_voxel )] += il6.pneumocyte_secretion_rate_unit_t # Degrade IL6 il6.grid *= il6.half_life_multiplier il6.grid *= turnover_rate( x=np.ones(shape=il6.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 IL6 il6.grid[:] = apply_diffusion( variable=il6.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
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
def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.iron import IronState from nlisim.modules.tafc import TAFCState estb: EstBState = state.estb iron: IronState = state.iron tafc: TAFCState = state.tafc molecules: MoleculesState = state.molecules voxel_volume = state.voxel_volume # contribute our iron buffer to the iron pool iron.grid += estb.iron_buffer estb.iron_buffer[:] = 0.0 # interact with TAFC v1 = michaelian_kinetics( substrate=tafc.grid["TAFC"], enzyme=estb.grid, k_m=estb.k_m, k_cat=estb.k_cat, h=self.time_step / 60, # units: (min/step) / (min/hour) voxel_volume=voxel_volume, ) v2 = michaelian_kinetics( substrate=tafc.grid["TAFCBI"], enzyme=estb.grid, k_m=estb.k_m, k_cat=estb.k_cat, h=self.time_step / 60, # units: (min/step) / (min/hour) voxel_volume=voxel_volume, ) tafc.grid["TAFC"] -= v1 tafc.grid["TAFCBI"] -= v2 estb.iron_buffer += v2 # set equal to zero previously # Degrade EstB estb.grid *= estb.half_life_multiplier estb.grid *= turnover_rate( x=estb.grid, x_system=estb.system_amount_per_voxel, base_turnover_rate=molecules.turnover_rate, rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t, ) # Diffusion of EstB estb.grid[:] = apply_diffusion( variable=estb.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
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.pneumocyte import PneumocyteCellData, PneumocyteState mip1b: MIP1BState = state.mip1b molecules: MoleculesState = state.molecules pneumocyte: PneumocyteState = state.pneumocyte macrophage: MacrophageState = state.macrophage grid: RectangularGrid = state.grid # 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']) mip1b.grid[tuple(pneumocyte_cell_voxel )] += mip1b.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']) mip1b.grid[tuple(macrophage_cell_voxel )] += mip1b.macrophage_secretion_rate_unit_t # Degrade MIP1B mip1b.grid *= mip1b.half_life_multiplier mip1b.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 MIP1b mip1b.grid[:] = apply_diffusion( variable=mip1b.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
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
def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.afumigatus import ( AfumigatusCellData, AfumigatusCellStatus, AfumigatusState, ) hemoglobin: HemoglobinState = state.hemoglobin molecules: MoleculesState = state.molecules afumigatus: AfumigatusState = state.afumigatus grid: RectangularGrid = state.grid # afumigatus uptakes iron from hemoglobin for afumigatus_cell_index in afumigatus.cells.alive(): afumigatus_cell: AfumigatusCellData = afumigatus.cells[ afumigatus_cell_index] if afumigatus_cell['status'] in { AfumigatusCellStatus.HYPHAE, AfumigatusCellStatus.GERM_TUBE, }: afumigatus_cell_voxel: Voxel = grid.get_voxel( afumigatus_cell['point']) fungal_absorbed_hemoglobin = ( hemoglobin.uptake_rate * hemoglobin.grid[tuple(afumigatus_cell_voxel)]) hemoglobin.grid[tuple( afumigatus_cell_voxel)] -= fungal_absorbed_hemoglobin afumigatus_cell['iron_pool'] += 4 * fungal_absorbed_hemoglobin # Degrade Hemoglobin hemoglobin.grid *= turnover_rate( x=hemoglobin.grid, x_system=0.0, base_turnover_rate=molecules.turnover_rate, rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t, ) # Diffusion of Hemoglobin hemoglobin.grid[:] = apply_diffusion( variable=hemoglobin.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
def advance(self, state: State, previous_time: float) -> State: """Advances the state by a single time step.""" from nlisim.modules.tnfa import TNFaState anti_tnf_a: AntiTNFaState = state.antitnfa molecules: MoleculesState = state.molecules voxel_volume = state.voxel_volume tnf_a: TNFaState = state.tnfa # AntiTNFa / TNFa reaction reacted_quantity = michaelian_kinetics( substrate=anti_tnf_a.grid, enzyme=tnf_a.grid, k_m=anti_tnf_a.k_m, h=anti_tnf_a. react_time_unit, # TODO: understand why units are seconds here k_cat=1.0, # default TODO use k_cat to reparameterize into hours voxel_volume=voxel_volume, ) reacted_quantity = np.min( [reacted_quantity, anti_tnf_a.grid, tnf_a.grid], axis=0) anti_tnf_a.grid[:] = np.maximum(0.0, anti_tnf_a.grid - reacted_quantity) tnf_a.grid[:] = np.maximum(0.0, tnf_a.grid - reacted_quantity) # Degradation of AntiTNFa anti_tnf_a.system_amount_per_voxel *= anti_tnf_a.half_life_multiplier anti_tnf_a.grid *= turnover_rate( x=anti_tnf_a.grid, x_system=anti_tnf_a.system_amount_per_voxel, base_turnover_rate=molecules.turnover_rate, rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t, ) # Diffusion of AntiTNFa anti_tnf_a.grid[:] = apply_diffusion( variable=anti_tnf_a.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.afumigatus import ( AfumigatusCellData, AfumigatusCellStatus, AfumigatusState, ) hemolysin: HemolysinState = state.hemolysin molecules: MoleculesState = state.molecules afumigatus: AfumigatusState = state.afumigatus grid: RectangularGrid = state.grid # fungus releases hemolysin for afumigatus_cell_index in afumigatus.cells.alive(): afumigatus_cell: AfumigatusCellData = afumigatus.cells[ afumigatus_cell_index] if afumigatus_cell['status'] == AfumigatusCellStatus.HYPHAE: afumigatus_cell_voxel: Voxel = grid.get_voxel( afumigatus_cell['point']) hemolysin.grid[tuple( afumigatus_cell_voxel)] += hemolysin.hemolysin_qtty # Degrade Hemolysin hemolysin.grid *= turnover_rate( x=hemolysin.grid, x_system=0.0, base_turnover_rate=molecules.turnover_rate, rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t, ) # Diffusion of Hemolysin hemolysin.grid[:] = apply_diffusion( variable=hemolysin.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.hemoglobin import HemoglobinState hemopexin: HemopexinState = state.hemopexin hemoglobin: HemoglobinState = state.hemoglobin molecules: MoleculesState = state.molecules voxel_volume: float = state.voxel_volume # units: L # Hemopexin / Hemoglobin reaction reacted_quantity = michaelian_kinetics( substrate=hemopexin.grid, enzyme=hemoglobin.grid, k_m=hemopexin.k_m, h=self.time_step / 60, # units: (min/step) / (min/hour) k_cat=hemopexin.k_cat, voxel_volume=voxel_volume, ) reacted_quantity = np.min([reacted_quantity, hemopexin.grid, hemoglobin.grid], axis=0) hemopexin.grid[:] = np.maximum(0.0, hemopexin.grid - reacted_quantity) hemoglobin.grid[:] = np.maximum(0.0, hemoglobin.grid - reacted_quantity) # Degrade Hemopexin hemopexin.grid *= hemopexin.half_life_multiplier hemopexin.grid *= turnover_rate( x=hemopexin.grid, x_system=hemopexin.system_amount_per_voxel, base_turnover_rate=molecules.turnover_rate, rel_cyt_bind_unit_t=molecules.rel_cyt_bind_unit_t, ) # Diffusion of Hemolysin hemopexin.grid[:] = apply_diffusion( variable=hemopexin.grid, laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
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
def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.afumigatus import ( AfumigatusCellData, AfumigatusCellState, AfumigatusCellStatus, AfumigatusState, NetworkSpecies, ) from nlisim.modules.iron import IronState from nlisim.modules.transferrin import TransferrinState tafc: TAFCState = state.tafc transferrin: TransferrinState = state.transferrin iron: IronState = state.iron molecules: MoleculesState = state.molecules afumigatus: AfumigatusState = state.afumigatus grid: RectangularGrid = state.grid voxel_volume: float = state.voxel_volume # units: L # interaction with transferrin # - calculate iron transfer from transferrin+[1,2]Fe to TAFC dfe2_dt = michaelian_kinetics( substrate=transferrin.grid["TfFe2"], enzyme=tafc.grid["TAFC"], k_m=tafc.k_m_tf_tafc, h=self.time_step / 60, # units: (min/step) / (min/hour) = hours/step k_cat=1.0, # default voxel_volume=voxel_volume, ) dfe_dt = michaelian_kinetics( substrate=transferrin.grid["TfFe"], enzyme=tafc.grid["TAFC"], k_m=tafc.k_m_tf_tafc, h=self.time_step / 60, # units: (min/step) / (min/hour) k_cat=1.0, # default voxel_volume=voxel_volume, ) # - enforce bounds from TAFC quantity total_change = dfe2_dt + dfe_dt rel = tafc.grid['TAFC'] / (total_change + EPSILON) # enforce bounds and zero out problem divides rel[total_change == 0] = 0.0 rel[:] = np.maximum(np.minimum(rel, 1.0), 0.0) dfe2_dt = dfe2_dt * rel dfe_dt = dfe_dt * rel # transferrin+2Fe loses an iron, becomes transferrin+Fe transferrin.grid['TfFe2'] -= dfe2_dt transferrin.grid['TfFe'] += dfe2_dt # transferrin+Fe loses an iron, becomes transferrin transferrin.grid['TfFe'] -= dfe_dt transferrin.grid['Tf'] += dfe_dt # iron from transferrin becomes bound to TAFC (TAFC->TAFCBI) tafc.grid['TAFC'] -= dfe2_dt + dfe_dt tafc.grid['TAFCBI'] += dfe2_dt + dfe_dt # interaction with iron, all available iron is bound to TAFC potential_reactive_quantity = np.minimum(iron.grid, tafc.grid['TAFC']) tafc.grid['TAFC'] -= potential_reactive_quantity tafc.grid['TAFCBI'] += potential_reactive_quantity iron.grid -= potential_reactive_quantity # interaction with fungus for afumigatus_cell_index in afumigatus.cells.alive(): afumigatus_cell: AfumigatusCellData = afumigatus.cells[ afumigatus_cell_index] if afumigatus_cell['state'] != AfumigatusCellState.FREE: continue afumigatus_cell_voxel: Voxel = grid.get_voxel( afumigatus_cell['point']) afumigatus_bool_net: np.ndarray = afumigatus_cell[ 'boolean_network'] # uptake iron from TAFCBI if afumigatus_bool_net[NetworkSpecies.MirB] & afumigatus_bool_net[ NetworkSpecies.EstB]: quantity = (tafc.grid['TAFCBI'][tuple(afumigatus_cell_voxel)] * tafc.tafcbi_uptake_rate_unit_t) tafc.grid['TAFCBI'][tuple(afumigatus_cell_voxel)] -= quantity afumigatus_cell['iron_pool'] += quantity # secrete TAFC if afumigatus_bool_net[ NetworkSpecies.TAFC] and afumigatus_cell['status'] in { AfumigatusCellStatus.SWELLING_CONIDIA, AfumigatusCellStatus.HYPHAE, AfumigatusCellStatus.GERM_TUBE, }: tafc.grid['TAFC'][ tuple(afumigatus_cell_voxel )] += tafc.afumigatus_secretion_rate_unit_t # Degrade TAFC trnvr_rt = 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, ) tafc.grid['TAFC'] *= trnvr_rt tafc.grid['TAFCBI'] *= trnvr_rt # Diffusion of TAFC for component in {'TAFC', 'TAFCBI'}: tafc.grid[component][:] = apply_diffusion( variable=tafc.grid[component], laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
def advance(self, state: State, previous_time: float) -> State: """Advance the state by a single time step.""" from nlisim.modules.iron import IronState from nlisim.modules.macrophage import MacrophageCellData, MacrophageState from nlisim.modules.molecules import MoleculesState from nlisim.modules.neutrophil import NeutrophilCellData, NeutrophilState from nlisim.modules.phagocyte import PhagocyteState, PhagocyteStatus from nlisim.modules.transferrin import TransferrinState lactoferrin: LactoferrinState = state.lactoferrin transferrin: TransferrinState = state.transferrin iron: IronState = state.iron molecules: MoleculesState = state.molecules macrophage: MacrophageState = state.macrophage neutrophil: NeutrophilState = state.neutrophil grid: RectangularGrid = state.grid voxel_volume = state.voxel_volume # macrophages uptake iron from lactoferrin live_macrophages = macrophage.cells.alive() rg.shuffle(live_macrophages) for macrophage_cell_index in live_macrophages: macrophage_cell: MacrophageCellData = macrophage.cells[ macrophage_cell_index] macrophage_cell_voxel: Voxel = grid.get_voxel( macrophage_cell['point']) uptake_proportion = np.minimum(lactoferrin.ma_iron_import_rate, 1.0) qtty_fe2 = (lactoferrin.grid['LactoferrinFe2'][tuple( macrophage_cell_voxel)] * uptake_proportion) qtty_fe = ( lactoferrin.grid['LactoferrinFe'][tuple(macrophage_cell_voxel)] * uptake_proportion) lactoferrin.grid['LactoferrinFe2'][tuple( macrophage_cell_voxel)] -= qtty_fe2 lactoferrin.grid['LactoferrinFe'][tuple( macrophage_cell_voxel)] -= qtty_fe macrophage_cell['iron_pool'] += 2 * qtty_fe2 + qtty_fe # active and interacting neutrophils secrete lactoferrin for neutrophil_cell_index in neutrophil.cells.alive(): neutrophil_cell: NeutrophilCellData = neutrophil.cells[ neutrophil_cell_index] if (neutrophil_cell['status'] != PhagocyteStatus.ACTIVE or neutrophil_cell['state'] != PhagocyteState.INTERACTING): continue neutrophil_cell_voxel: Voxel = grid.get_voxel( neutrophil_cell['point']) lactoferrin.grid['Lactoferrin'][ tuple(neutrophil_cell_voxel )] += lactoferrin.neutrophil_secretion_rate_unit_t # interaction with transferrin # - calculate iron transfer from transferrin+[1,2]Fe to lactoferrin dfe2_dt = michaelian_kinetics( substrate=transferrin.grid['TfFe2'], enzyme=lactoferrin.grid["Lactoferrin"], k_m=lactoferrin.k_m_tf_lac, h=self.time_step / 60, # units: (min/step) / (min/hour) k_cat=1.0, voxel_volume=voxel_volume, ) dfe_dt = michaelian_kinetics( substrate=transferrin.grid['TfFe'], enzyme=lactoferrin.grid['Lactoferrin'], k_m=lactoferrin.k_m_tf_lac, h=self.time_step / 60, # units: (min/step) / (min/hour) k_cat=1.0, voxel_volume=voxel_volume, ) # - enforce bounds from lactoferrin quantity dfex_dt = dfe2_dt + dfe_dt mask = dfex_dt > lactoferrin.grid['Lactoferrin'] rel = lactoferrin.grid['Lactoferrin'] / (dfex_dt + EPSILON) # enforce bounds rel[dfex_dt == 0] = 0.0 rel[:] = np.maximum(np.minimum(rel, 1.0), 0.0) dfe2_dt[mask] = (dfe2_dt * rel)[mask] dfe_dt[mask] = (dfe_dt * rel)[mask] # - calculate iron transfer from transferrin+[1,2]Fe to lactoferrin+Fe dfe2_dt_fe = michaelian_kinetics( substrate=transferrin.grid['TfFe2'], enzyme=lactoferrin.grid['LactoferrinFe'], k_m=lactoferrin.k_m_tf_lac, h=self.time_step / 60, # units: (min/step) / (min/hour) k_cat=1.0, voxel_volume=voxel_volume, ) dfe_dt_fe = michaelian_kinetics( substrate=transferrin.grid['TfFe'], enzyme=lactoferrin.grid['LactoferrinFe'], k_m=lactoferrin.k_m_tf_lac, h=self.time_step / 60, # units: (min/step) / (min/hour) k_cat=1.0, voxel_volume=voxel_volume, ) # - enforce bounds from lactoferrin+Fe quantity dfex_dt_fe = dfe2_dt_fe + dfe_dt_fe mask = dfex_dt_fe > lactoferrin.grid['LactoferrinFe'] rel = lactoferrin.grid['LactoferrinFe'] / (dfe2_dt_fe + dfe_dt_fe + EPSILON) # enforce bounds rel[dfex_dt_fe == 0] = 0.0 np.minimum(rel, 1.0, out=rel) np.maximum(rel, 0.0, out=rel) dfe2_dt_fe[mask] = (dfe2_dt_fe * rel)[mask] dfe_dt_fe[mask] = (dfe_dt_fe * rel)[mask] # transferrin+2Fe loses an iron, becomes transferrin+Fe transferrin.grid['TfFe2'] -= dfe2_dt + dfe2_dt_fe transferrin.grid['TfFe'] += dfe2_dt + dfe2_dt_fe # transferrin+Fe loses an iron, becomes transferrin transferrin.grid['TfFe'] -= dfe_dt + dfe_dt_fe transferrin.grid['Tf'] += dfe_dt + dfe_dt_fe # lactoferrin gains an iron, becomes lactoferrin+Fe lactoferrin.grid['Lactoferrin'] -= dfe2_dt + dfe_dt lactoferrin.grid['LactoferrinFe'] += dfe2_dt + dfe_dt # lactoferrin+Fe gains an iron, becomes lactoferrin+2Fe lactoferrin.grid['LactoferrinFe'] -= dfe2_dt_fe + dfe_dt_fe lactoferrin.grid['LactoferrinFe2'] += dfe2_dt_fe + dfe_dt_fe # interaction with iron lactoferrin_fe_capacity = (2 * lactoferrin.grid["Lactoferrin"] + lactoferrin.grid["LactoferrinFe"]) potential_reactive_quantity = np.minimum(iron.grid, lactoferrin_fe_capacity) rel_tf_fe = iron_tf_reaction( iron=potential_reactive_quantity, tf=lactoferrin.grid["Lactoferrin"], tf_fe=lactoferrin.grid["LactoferrinFe"], p1=lactoferrin.p1, p2=lactoferrin.p2, p3=lactoferrin.p3, ) tffe_qtty = rel_tf_fe * potential_reactive_quantity tffe2_qtty = (potential_reactive_quantity - tffe_qtty) / 2 lactoferrin.grid['Lactoferrin'] -= tffe_qtty + tffe2_qtty lactoferrin.grid['LactoferrinFe'] += tffe_qtty lactoferrin.grid['LactoferrinFe2'] += tffe2_qtty iron.grid -= potential_reactive_quantity # Degrade Lactoferrin # Note: ideally, this would be a constant computed in initialize, but we would have to # know that "molecules" is initialized first trnvr_rt = 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, ) lactoferrin.grid['Lactoferrin'] *= trnvr_rt lactoferrin.grid['LactoferrinFe'] *= trnvr_rt lactoferrin.grid['LactoferrinFe2'] *= trnvr_rt # Diffusion of lactoferrin for component in {'Lactoferrin', 'LactoferrinFe', 'LactoferrinFe2'}: lactoferrin.grid[component][:] = apply_diffusion( variable=lactoferrin.grid[component], laplacian=molecules.laplacian, diffusivity=molecules.diffusion_constant, dt=self.time_step, ) return state
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
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