def default_transport_config(): config = get_glc_lct_config() txp_config = { 'time_step': TIMESTEP, 'kinetic_parameters': { 'EX_glc__D_e': { ('internal', 'EIIglc'): { ('external', 'glc__D_e'): 2e-1, # k_m for external [glc__D_e] } }, 'EX_lcts_e': { ('internal', 'LacY'): { ('external', 'lcts_e'): 1e-1, } } } } deep_merge(config, txp_config) return config
class ChemotaxisMaster(Generator): defaults = { 'dimensions_path': ('dimensions', ), 'fields_path': ('fields', ), 'boundary_path': ('boundary', ), 'transport': get_glc_lct_config(), 'metabolism': metabolism_timestep_config(10), 'transcription': get_flagella_expression_config({})['transcription'], 'translation': get_flagella_expression_config({})['translation'], 'degradation': get_flagella_expression_config({})['degradation'], 'complexation': get_flagella_expression_config({})['complexation'], 'receptor': { 'ligand': 'MeAsp' }, 'flagella': { 'n_flagella': 5 }, 'PMF': {}, 'division': {}, } def __init__(self, config=None): super(ChemotaxisMaster, self).__init__(config) def generate_processes(self, config): # Transport transport = ConvenienceKinetics(config.get('transport')) # Metabolism # add target fluxes from transport target_fluxes = transport.kinetic_rate_laws.reaction_ids config['metabolism']['constrained_reaction_ids'] = target_fluxes metabolism = Metabolism(config['metabolism']) # flagella expression transcription = Transcription(config['transcription']) translation = Translation(config['translation']) degradation = RnaDegradation(config['degradation']) complexation = Complexation(config['complexation']) # chemotaxis -- flagella activity, receptor activity, and PMF receptor = ReceptorCluster(config['receptor']) flagella = FlagellaActivity(config['flagella']) PMF = MembranePotential(config['PMF']) # Division # get initial volume from metabolism if 'division' not in config: config['division'] = {} config['division']['initial_state'] = metabolism.initial_state division = DivisionVolume(config['division']) return { 'metabolism': metabolism, 'transport': transport, 'transcription': transcription, 'translation': translation, 'degradation': degradation, 'complexation': complexation, 'receptor': receptor, 'flagella': flagella, 'PMF': PMF, 'division': division, } def generate_topology(self, config): dimensions_path = config['dimensions_path'] fields_path = config['fields_path'] boundary_path = config['boundary_path'] external_path = boundary_path + ('external', ) return { 'transport': { 'internal': ('internal', ), 'external': external_path, 'fields': ('null', ), # metabolism's exchange is used 'fluxes': ('flux_bounds', ), 'global': boundary_path, 'dimensions': dimensions_path, }, 'metabolism': { 'internal': ('internal', ), 'external': external_path, 'reactions': ('reactions', ), 'fields': fields_path, 'flux_bounds': ('flux_bounds', ), 'global': boundary_path, 'dimensions': dimensions_path }, 'transcription': { 'chromosome': ('chromosome', ), 'molecules': ('internal', ), 'proteins': ('proteins', ), 'transcripts': ('transcripts', ), 'factors': ('concentrations', ), 'global': boundary_path, }, 'translation': { 'ribosomes': ('ribosomes', ), 'molecules': ('internal', ), 'transcripts': ('transcripts', ), 'proteins': ('proteins', ), 'concentrations': ('concentrations', ), 'global': boundary_path, }, 'degradation': { 'transcripts': ('transcripts', ), 'proteins': ('proteins', ), 'molecules': ('internal', ), 'global': boundary_path, }, 'complexation': { 'monomers': ('proteins', ), 'complexes': ('proteins', ), 'global': boundary_path, }, 'receptor': { 'external': external_path, 'internal': ('internal', ), }, 'flagella': { 'internal': ('internal', ), 'membrane': ('membrane', ), 'internal_counts': ('proteins', ), 'flagella': ('flagella', ), 'boundary': boundary_path, }, 'PMF': { 'external': external_path, 'membrane': ('membrane', ), 'internal': ('internal', ), }, 'division': { 'global': boundary_path, } }
class GrowthDivision(Generator): defaults = { 'boundary_path': ('boundary', ), 'agents_path': ( '..', '..', 'agents', ), 'transport': get_glc_lct_config(), 'daughter_path': tuple(), 'fields_path': ('fields', ), 'dimensions_path': ('dimensions', ), 'growth': {}, 'expression': get_toy_expression_config(), 'mass': {}, } def __init__(self, config): super(GrowthDivision, self).__init__(config) # transport configs boundary_path = self.config['boundary_path'] self.config['transport'] = self.config['transport'] self.config['transport']['global_deriver_config'] = { 'type': 'globals', 'source_port': 'global', 'derived_port': 'global', 'global_port': boundary_path, 'keys': [] } def generate_processes(self, config): daughter_path = config['daughter_path'] agent_id = config['agent_id'] growth = GrowthProtein(config['growth']) transport = ConvenienceKinetics(config['transport']) expression = MinimalExpression(config['expression']) mass_deriver = TreeMass(config['mass']) # configure division division_config = dict(config.get('division', {}), daughter_path=daughter_path, agent_id=agent_id, compartment=self) division = MetaDivision(division_config) return { 'transport': transport, 'growth': growth, 'expression': expression, 'mass_deriver': mass_deriver, 'division': division, } def generate_topology(self, config): boundary_path = config['boundary_path'] agents_path = config['agents_path'] external_path = boundary_path + ('external', ) fields_path = config['fields_path'] dimensions_path = config['dimensions_path'] return { 'transport': { 'internal': ('internal', ), 'external': external_path, 'fields': fields_path, 'fluxes': ('fluxes', ), 'global': boundary_path, 'dimensions': dimensions_path, }, 'growth': { 'internal': ('internal', ), 'global': boundary_path }, 'mass_deriver': { 'global': boundary_path }, 'division': { 'global': boundary_path, 'cells': agents_path }, 'expression': { 'internal': ('internal', ), 'external': external_path, 'concentrations': ('internal_concentrations', ), 'global': boundary_path }, }
class TransportMetabolism(Compartment): """ Transport/Metabolism Compartment, with ODE expression """ defaults = { 'boundary_path': ('boundary', ), 'agents_path': ('agents', ), 'daughter_path': tuple(), 'division': {} } default_config = { 'transport': get_glc_lct_config(), 'metabolism': default_metabolism_config(), 'expression': default_expression_config() } def __init__(self, config=None): if not config: config = self.default_config self.config = config self.boundary_path = config.get('boundary_path', self.defaults['boundary_path']) self.agents_path = config.get('agents_path', self.defaults['agents_path']) self.daughter_path = config.get('daughter_path', self.defaults['daughter_path']) def generate_processes(self, config): agent_id = config.get('agent_id', '0') # TODO -- configure the agent_id # Transport # load the kinetic parameters transport = ConvenienceKinetics(config.get('transport', {})) # Metabolism # get target fluxes from transport, and update constrained_reaction_ids metabolism_config = config.get('metabolism', {}) target_fluxes = transport.kinetic_rate_laws.reaction_ids metabolism_config.update({'constrained_reaction_ids': target_fluxes}) metabolism = Metabolism(metabolism_config) # Gene expression expression = ODE_expression(config.get('expression', {})) # Division division_config = dict(config.get('division', {}), daughter_path=self.daughter_path, agent_id=agent_id, compartment=self) # initial_mass = metabolism.initial_mass # division_config.update({'constrained_reaction_ids': target_fluxes}) # TODO -- configure metadivision division = MetaDivision(division_config) return { 'transport': transport, 'metabolism': metabolism, 'expression': expression, 'division': division } def generate_topology(self, config): exchange_path = self.boundary_path + ('exchange', ) external_path = self.boundary_path + ('external', ) return { 'transport': { 'internal': ('cytoplasm', ), 'external': external_path, 'exchange': ('null', ), # metabolism's exchange is used 'fluxes': ('flux_bounds', ), 'global': self.boundary_path, }, 'metabolism': { 'internal': ('cytoplasm', ), 'external': external_path, 'reactions': ('reactions', ), 'exchange': exchange_path, 'flux_bounds': ('flux_bounds', ), 'global': self.boundary_path, }, 'expression': { 'counts': ('cytoplasm_counts', ), 'internal': ('cytoplasm', ), 'external': external_path, 'global': self.boundary_path, }, 'division': { 'global': self.boundary_path, 'cells': self.agents_path, } }
class Master(Compartment): defaults = { 'global_path': ('global', ), 'external_path': ('external', ), 'config': { 'transport': get_glc_lct_config(), 'metabolism': default_metabolism_config() } } def __init__(self, config=None): if not config: config = {} self.config = deep_merge(self.defaults['config'], config) self.global_path = self.or_default(config, 'global_path') self.external_path = self.or_default(config, 'external_path') def generate_processes(self, config): # Transport transport_config = config.get('transport') transport = ConvenienceKinetics(transport_config) target_fluxes = transport.kinetic_rate_laws.reaction_ids # Metabolism # add target fluxes from transport metabolism_config = config.get('metabolism') metabolism_config.update({'constrained_reaction_ids': target_fluxes}) metabolism = Metabolism(metabolism_config) # Expression transcription_config = config.get('transcription', {}) translation_config = config.get('translation', {}) degradation_config = config.get('degradation', {}) transcription = Transcription(transcription_config) translation = Translation(translation_config) degradation = RnaDegradation(degradation_config) complexation = Complexation(config.get('complexation', {})) # Division # get initial volume from metabolism division_config = config.get('division', {}) division_config.update({'initial_state': metabolism.initial_state}) division = DivisionVolume(division_config) return { 'transport': transport, 'transcription': transcription, 'translation': translation, 'degradation': degradation, 'complexation': complexation, 'metabolism': metabolism, 'division': division } def generate_topology(self, config): return { 'transport': { 'internal': ('metabolites', ), 'external': self.external_path, 'exchange': ('null', ), # metabolism's exchange is used 'fluxes': ('flux_bounds', ), 'global': self.global_path }, 'metabolism': { 'internal': ('metabolites', ), 'external': self.external_path, 'reactions': ('reactions', ), 'exchange': ('exchange', ), 'flux_bounds': ('flux_bounds', ), 'global': self.global_path }, 'transcription': { 'chromosome': ('chromosome', ), 'molecules': ('metabolites', ), 'proteins': ('proteins', ), 'transcripts': ('transcripts', ), 'factors': ('concentrations', ), 'global': self.global_path }, 'translation': { 'ribosomes': ('ribosomes', ), 'molecules': ('metabolites', ), 'transcripts': ('transcripts', ), 'proteins': ('proteins', ), 'concentrations': ('concentrations', ), 'global': self.global_path }, 'degradation': { 'transcripts': ('transcripts', ), 'proteins': ('proteins', ), 'molecules': ('metabolites', ), 'global': self.global_path }, 'complexation': { 'monomers': ('proteins', ), 'complexes': ('proteins', ), 'global': self.global_path }, 'division': { 'global': self.global_path } }
class FlagellaExpressionMetabolism(Generator): name = 'flagella_expression_metabolism' defaults = get_flagella_expression_config({}) defaults.update({ 'boundary_path': ('boundary',), 'dimensions_path': ('dimensions',), 'agents_path': ('agents',), # ('..', '..', 'agents',), 'daughter_path': tuple(), 'transport': get_glc_lct_config(), 'metabolism': default_metabolism_config(), 'initial_mass': 0.0 * units.fg, 'time_step': COMPARTMENT_TIMESTEP, 'divide': True, }) def __init__(self, config=None): super(FlagellaExpressionMetabolism, self).__init__(config) if 'agent_id' not in self.config: self.config['agent_id'] = str(uuid.uuid1()) def generate_processes(self, config): daughter_path = config['daughter_path'] agent_id = config['agent_id'] # get the configs transcription_config = config['transcription'] translation_config = config['translation'] degradation_config = config['degradation'] complexation_config = config['complexation'] # update expression timestep transcription_config.update({'time_step': config['time_step']}) translation_config.update({'time_step': config['time_step']}) degradation_config.update({'time_step': config['time_step']}) complexation_config.update({'time_step': config['time_step']}) # make the expression processes transcription = Transcription(transcription_config) translation = Translation(translation_config) degradation = RnaDegradation(degradation_config) complexation = Complexation(complexation_config) mass_deriver = TreeMass(config.get('mass_deriver', { 'initial_mass': config['initial_mass']})) # Transport transport = ConvenienceKinetics(config['transport']) target_fluxes = transport.kinetic_rate_laws.reaction_ids # Metabolism # add target fluxes from transport metabolism_config = config.get('metabolism') metabolism_config.update({'constrained_reaction_ids': target_fluxes}) metabolism = Metabolism(metabolism_config) # Division condition division_condition = DivisionVolume({}) processes = { 'metabolism': metabolism, 'transport': transport, 'mass_deriver': mass_deriver, 'transcription': transcription, 'translation': translation, 'degradation': degradation, 'complexation': complexation, 'division': division_condition } # divide process set to true, add meta-division processes if config['divide']: meta_division_config = dict( {}, daughter_path=daughter_path, agent_id=agent_id, compartment=self) meta_division = MetaDivision(meta_division_config) processes['meta_division'] = meta_division return processes def generate_topology(self, config): boundary_path = config['boundary_path'] dimensions_path = config['dimensions_path'] agents_path = config['agents_path'] external_path = boundary_path + ('external',) topology = { 'mass_deriver': { 'global': boundary_path, }, 'transcription': { 'chromosome': ('chromosome',), 'molecules': ('molecules',), 'proteins': ('proteins',), 'transcripts': ('transcripts',), 'factors': ('concentrations',), 'global': boundary_path, }, 'translation': { 'ribosomes': ('ribosomes',), 'molecules': ('molecules',), 'transcripts': ('transcripts',), 'proteins': ('proteins',), 'concentrations': ('concentrations',), 'global': boundary_path, }, 'degradation': { 'transcripts': ('transcripts',), 'proteins': ('proteins',), 'molecules': ('molecules',), 'global': boundary_path, }, 'complexation': { 'monomers': ('proteins',), 'complexes': ('proteins',), 'global': boundary_path, }, 'transport': { 'internal': ('molecules',), 'external': external_path, 'fields': ('null',), # metabolism's exchange is used 'fluxes': ('flux_bounds',), 'global': boundary_path, 'dimensions': dimensions_path, }, 'metabolism': { 'internal': ('molecules',), 'external': external_path, 'fields': ('fields',), 'reactions': ('reactions',), 'flux_bounds': ('flux_bounds',), 'global': boundary_path, 'dimensions': dimensions_path, }, 'division': { 'global': boundary_path, }, } if config['divide']: topology.update({ 'meta_division': { 'global': boundary_path, 'cells': agents_path, }}) return topology
class GrowthDivision(Compartment): defaults = { 'boundary_path': ('boundary', ), 'agents_path': ( '..', '..', 'agents', ), 'transport': get_glc_lct_config(), 'daughter_path': tuple() } def __init__(self, config): self.config = copy.deepcopy(config) for key, value in self.defaults.items(): if key not in self.config: self.config[key] = value # paths self.boundary_path = config.get('boundary_path', self.defaults['boundary_path']) self.agents_path = config.get('agents_path', self.defaults['agents_path']) # self.daughter_path = config.get('daughter_path', self.defaults['daughter_path']) # # process configs self.config['transport'] = self.config.get('transport', self.defaults['transport']) self.config['transport']['global_deriver_config'] = { 'type': 'globals', 'source_port': 'global', 'derived_port': 'global', 'global_port': self.boundary_path, 'keys': [] } def generate_processes(self, config): daughter_path = config['daughter_path'] agent_id = config['agent_id'] division_config = dict(config.get('division', {}), daughter_path=daughter_path, agent_id=agent_id, compartment=self) growth = GrowthProtein(config.get('growth', {})) transport = ConvenienceKinetics(config.get('transport', {})) division = MetaDivision(division_config) expression = MinimalExpression(config.get('expression', {})) mass = TreeMass(config.get('mass', {})) return { 'transport': transport, 'growth': growth, 'expression': expression, 'division': division, 'mass': mass } def generate_topology(self, config): external_path = self.boundary_path + ('external', ) exchange_path = self.boundary_path + ('exchange', ) return { 'transport': { 'internal': ('internal', ), 'external': external_path, 'exchange': exchange_path, 'fluxes': ('fluxes', ), 'global': self.boundary_path }, 'growth': { 'internal': ('internal', ), 'global': self.boundary_path }, 'mass': { 'global': self.boundary_path }, 'division': { 'global': self.boundary_path, 'cells': self.agents_path }, 'expression': { 'internal': ('internal', ), 'external': external_path, 'concentrations': ('internal_concentrations', ), 'global': self.boundary_path } }