Module nlisim.modules.tafc
Expand source code
from typing import Any, Dict
import attr
import numpy as np
from nlisim.coordinates import Voxel
from nlisim.diffusion import apply_diffusion
from nlisim.grid import RectangularGrid
from nlisim.module import ModuleModel, ModuleState
from nlisim.modules.molecules import MoleculesState
from nlisim.state import State
from nlisim.util import EPSILON, michaelian_kinetics, turnover_rate
def molecule_grid_factory(self: 'TAFCState') -> np.ndarray:
# note the expansion to another axis to account for 0 or 1 bound Fe's.
return np.zeros(
shape=self.global_state.grid.shape, dtype=[('TAFC', np.float64), ('TAFCBI', np.float64)]
)
@attr.s(kw_only=True, repr=False)
class TAFCState(ModuleState):
grid: np.ndarray = attr.ib(
default=attr.Factory(molecule_grid_factory, takes_self=True)
) # units: atto-mols
k_m_tf_tafc: float # units: aM
tafcbi_uptake_rate: float # units: L * cell^-1 * h^-1
tafcbi_uptake_rate_unit_t: float # units: proportion * cell^-1 * step^-1
afumigatus_secretion_rate: float # units: atto-mol * cell^-1 * h^-1
afumigatus_secretion_rate_unit_t: float # units: atto-mol * cell^-1 * step^-1
class TAFC(ModuleModel):
# noinspection SpellCheckingInspection
"""TAFC: (T)ri(A)cetyl(F)usarinine C"""
name = 'tafc'
StateClass = TAFCState
def initialize(self, state: State) -> State:
tafc: TAFCState = state.tafc
voxel_volume: float = state.voxel_volume
# config file values
tafc.k_m_tf_tafc = self.config.getfloat('k_m_tf_tafc') # units: aM
tafc.afumigatus_secretion_rate = self.config.getfloat(
'afumigatus_secretion_rate'
) # units: atto-mol * cell^-1 * h^-1
tafc.tafcbi_uptake_rate = self.config.getfloat(
'tafcbi_uptake_rate'
) # units: L * cell^-1 * h^-1
# computed values
tafc.afumigatus_secretion_rate_unit_t = tafc.afumigatus_secretion_rate * (
self.time_step / 60
) # units: (atto-mol * cell^-1 * h^-1) * (min/step) / (min/hour)
tafc.tafcbi_uptake_rate_unit_t = (
tafc.tafcbi_uptake_rate
/ voxel_volume
* (self.time_step / 60)
# units: (L * cell^-1 * h^-1) / L * (min/step) / (min/hour)
# = proportion * cell^-1 * step^-1
)
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 summary_stats(self, state: State) -> Dict[str, Any]:
tafc: TAFCState = state.tafc
voxel_volume = state.voxel_volume
concentration_no_fe = np.mean(tafc.grid['TAFC']) / voxel_volume
concentration_fe = np.mean(tafc.grid['TAFCBI']) / voxel_volume
concentration = concentration_no_fe + concentration_fe
return {
'concentration (nM)': float(concentration / 1e9),
'concentration TAFC (nM)': float(concentration_no_fe / 1e9),
'concentration TAFCBI (nM)': float(concentration_fe / 1e9),
}
def visualization_data(self, state: State):
tafc: TAFCState = state.tafc
return 'molecule', tafc.grid
Functions
def molecule_grid_factory(self: TAFCState) ‑> numpy.ndarray
-
Expand source code
def molecule_grid_factory(self: 'TAFCState') -> np.ndarray: # note the expansion to another axis to account for 0 or 1 bound Fe's. return np.zeros( shape=self.global_state.grid.shape, dtype=[('TAFC', np.float64), ('TAFCBI', np.float64)] )
Classes
class TAFC (config: SimulationConfig)
-
TAFC: (T)ri(A)cetyl(F)usarinine C
Expand source code
class TAFC(ModuleModel): # noinspection SpellCheckingInspection """TAFC: (T)ri(A)cetyl(F)usarinine C""" name = 'tafc' StateClass = TAFCState def initialize(self, state: State) -> State: tafc: TAFCState = state.tafc voxel_volume: float = state.voxel_volume # config file values tafc.k_m_tf_tafc = self.config.getfloat('k_m_tf_tafc') # units: aM tafc.afumigatus_secretion_rate = self.config.getfloat( 'afumigatus_secretion_rate' ) # units: atto-mol * cell^-1 * h^-1 tafc.tafcbi_uptake_rate = self.config.getfloat( 'tafcbi_uptake_rate' ) # units: L * cell^-1 * h^-1 # computed values tafc.afumigatus_secretion_rate_unit_t = tafc.afumigatus_secretion_rate * ( self.time_step / 60 ) # units: (atto-mol * cell^-1 * h^-1) * (min/step) / (min/hour) tafc.tafcbi_uptake_rate_unit_t = ( tafc.tafcbi_uptake_rate / voxel_volume * (self.time_step / 60) # units: (L * cell^-1 * h^-1) / L * (min/step) / (min/hour) # = proportion * cell^-1 * step^-1 ) 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 summary_stats(self, state: State) -> Dict[str, Any]: tafc: TAFCState = state.tafc voxel_volume = state.voxel_volume concentration_no_fe = np.mean(tafc.grid['TAFC']) / voxel_volume concentration_fe = np.mean(tafc.grid['TAFCBI']) / voxel_volume concentration = concentration_no_fe + concentration_fe return { 'concentration (nM)': float(concentration / 1e9), 'concentration TAFC (nM)': float(concentration_no_fe / 1e9), 'concentration TAFCBI (nM)': float(concentration_fe / 1e9), } def visualization_data(self, state: State): tafc: TAFCState = state.tafc return 'molecule', tafc.grid
Ancestors
Methods
def advance(self, state: State, previous_time: float) ‑> State
-
Advance the state by a single time step.
Expand source code
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
Inherited members
class TAFCState (*, global_state: State, grid: numpy.ndarray = NOTHING)
-
Base type intended to store the state for simulation modules.
This class contains serialization support for basic types (float, int, str, bool) and numpy arrays of those types. Modules containing more complicated state must override the serialization mechanism with custom behavior.
Method generated by attrs for class TAFCState.
Expand source code
class TAFCState(ModuleState): grid: np.ndarray = attr.ib( default=attr.Factory(molecule_grid_factory, takes_self=True) ) # units: atto-mols k_m_tf_tafc: float # units: aM tafcbi_uptake_rate: float # units: L * cell^-1 * h^-1 tafcbi_uptake_rate_unit_t: float # units: proportion * cell^-1 * step^-1 afumigatus_secretion_rate: float # units: atto-mol * cell^-1 * h^-1 afumigatus_secretion_rate_unit_t: float # units: atto-mol * cell^-1 * step^-1
Ancestors
Class variables
var afumigatus_secretion_rate : float
var afumigatus_secretion_rate_unit_t : float
var grid : numpy.ndarray
var k_m_tf_tafc : float
var tafcbi_uptake_rate : float
var tafcbi_uptake_rate_unit_t : float
Inherited members