def make_gamma_fun(kinetic_model): """ Return a function that calculates the thermodynamic displacement for all the reactions in a model :param kinetic_model: :return: """ reactions = kinetic_model.reactions.keys() all_parameters = [] for r in reactions: keq = r.parameters.k_equilibrium.symbol expr[r.id] = 1 / keq for v, s in r.reactant_stoichiometry.items(): expr[r.id] *= v**-s all_parameters.append(keq) all_parameters = iterable_to_tabdict(all_parameters, use_name=False) # Better since this is implemented now reactant_items = kinetic_model.reactants.items() variables = TabDict([(k, v.symbol) for k, v in reactant_items]) # Make vector function from expressions in this case all_expressions # are all the expressions indexed by the gamma_fun = GammaFunction(variables, expr, all_parameters) gamma_fun._parameter_values = { v: p.value for v, p in kinetic_model.parameters.items() } return gamma_fun
def __init__(self, name, model=None): #TODO Do we need additional info for the future? self.name = name #Parameters so far only volume but maybe others soon volume = Parameter(name='volume', model=model, value=None, suffix=name) cell_volume = Parameter(name='cell_volume', model=model, value=None, suffix=name) self.parameters = iterable_to_tabdict([volume, cell_volume])
def make_flux_fun(kinetic_model, sim_type): """ :param kinetic_model: :param sim_type: :return: """ all_data = get_expressions_from_model(kinetic_model, sim_type) # Get flux expressions _, all_expr, all_parameters = list(zip(*all_data)) reactions = kinetic_model.reactions.keys() # Flatten all the lists flatten_list = lambda this_list: [item for sublist in this_list \ for item in sublist] if sim_type == ELEMENTARY: expr = [[(r + '_' + er, ex) for er, ex in e.items()] for r, e in zip(reactions, all_expr)] expr = TabDict(flatten_list(expr)) else: expr = TabDict([(r, e) for r, e in zip(reactions, all_expr)]) all_parameters = flatten_list(all_parameters) all_parameters = list(set(all_parameters)) all_parameters = iterable_to_tabdict(all_parameters, use_name=False) # Better since this is implemented now reactant_items = kinetic_model.reactants.items() variables = TabDict([(k, v.symbol) for k, v in reactant_items]) # Make vector function from expressions in this case all_expressions # are all the expressions indexed by the flux_fun = FluxFunction(variables, expr, all_parameters) flux_fun._parameter_values = { v: p.value for v, p in kinetic_model.parameters.items() } return flux_fun
def __init__( self, models, biomass_reactions, biomass_scaling, boundary_conditions=None, extracellular_compartment='e', custom_variables=[], ): """ :param models: :param biomass_reactions: Dict, TabDict :param boundary_conditions: :param extracellular_compartment: """ # Medium of the reactor # Copy models, Generate unique model annotation and remove all boundary conditions models = [copy(m) for m in models] for the_model in models: the_model.boundary_conditions.clear() medium = [] for model in models: medium += get_medium( model, extracellular_compartment=extracellular_compartment) self.extracellular_compartment = extracellular_compartment self.medium = iterable_to_tabdict(medium) self.biomass_reactions = biomass_reactions self.biomass_scaling = biomass_scaling # biomass variables biomass_variables = [ Reactant('biomass_{}'.format(model.name), model=model) for model in models ] self.biomass_variables = iterable_to_tabdict(biomass_variables) #Generate unique model annotation and remove all boundary conditions for the_model in models: reactants = the_model.reactants for the_reactant in reactants.values(): if the_reactant.name not in self.medium: the_reactant.name = the_model.name + '_' + the_reactant.name the_reactant._generate_symbol() parameters = the_model.parameters for the_parameter in parameters.values(): the_parameter.name = the_model.name + '_' + the_parameter.name the_parameter._generate_symbol() for the_reaction in the_model.reactions.values(): the_reaction.name = the_model.name + '_' + the_reaction.name self.models = iterable_to_tabdict(models) self.boundary_conditions = iterable_to_tabdict(boundary_conditions) self.initial_conditions = iterable_to_tabdict([]) self._modified = True self.custom_variables = iterable_to_tabdict(custom_variables)
def make_reactor_ode_fun(reactor, sim_type, pool=None, add_dilution=False, custom_ode_update=None): """ This function generates the symbolic expressions for a reactor model :param reactor: :param sim_type: :param pool: :return: """ expression_list = [] parameters_list = [] # Flatten all the lists flatten_list = lambda this_list: [item for sublist in this_list \ for item in sublist] medium_symbols = [m.symbol for m in reactor.medium.values()] model_biomass_var = { b.model: b for b in reactor.biomass_variables.values() } for model in reactor.models.values(): medium_com = reactor.extracellular_compartment volume_scaling_medium = model.compartments[medium_com].parameters.cell_volume.symbol / \ model.compartments[medium_com].parameters.volume.symbol biomass_symbol = model_biomass_var[model].symbol * volume_scaling_medium all_data = get_expressions_from_model(model, sim_type, medium_symbols=medium_symbols, biomass_symbol=biomass_symbol) # get the dxdt expressions all_expr_model, _, all_parameters_model = list(zip(*all_data)) parameters_list.extend(all_parameters_model) expression_list.extend(all_expr_model) parameters_list = flatten_list(parameters_list) parameters_list = list(set(parameters_list)) parameters_list = iterable_to_tabdict(parameters_list, use_name=False) variables = TabDict([(k, v.symbol) for k, v in reactor.variables.items()]) volume_ratios = TabDict([]) for model in reactor.models.values(): # Volumes if model.compartments: this_volume_ratios = TabDict([ (k, v.compartment.parameters.cell_volume.symbol / v.compartment.parameters.volume.symbol) if k not in reactor.medium else (k, 1.0) for k, v in model.reactants.items() ]) for comp in model.compartments.values(): this_comp_parameters = { str(v.symbol): v.symbol for v in comp.parameters.values() } parameters_list.update(this_comp_parameters) else: this_volume_ratios = {} volume_ratios.update(this_volume_ratios) for k, biomass in reactor.biomass_variables.items(): volume_ratios[k] = 1.0 for k, var in reactor.custom_variables.items(): volume_ratios[k] = 1.0 # Make default ODE expressions expr = make_expressions(variables, expression_list, volume_ratios=volume_ratios, pool=pool) if add_dilution: # Dilution for intracellular metabolites for model in reactor.models.values(): growth_reaction = reactor.biomass_reactions[model.name] growth_rate_expression = growth_reaction.mechanism.reaction_rates[ 'v_net'] biomass_scaling = reactor.biomass_scaling[model.name] for r in model.reactants.values(): if not r.name in reactor.medium: expr[ r. symbol] -= r.symbol * growth_rate_expression / biomass_scaling # Add growth expressions for biomass in reactor.biomass_variables.values(): growth_reaction = reactor.biomass_reactions[biomass.model.name] growth_rate_expression = growth_reaction.mechanism.reaction_rates[ 'v_net'] biomass_scaling = reactor.biomass_scaling[biomass.model.name] expr[ biomass. symbol] += biomass.symbol * growth_rate_expression / biomass_scaling # Apply constraints. Constraints are modifiers that act on # expressions for model in reactor.models.values(): for this_constraint in model.constraints.values(): this_constraint(expr) # Apply boundary conditions. Boundaries are modifiers that act on # expressions for this_boundary_condition in reactor.boundary_conditions.values(): this_boundary_condition(expr) # Make vector function from expressions ode_fun = ODEFunction(reactor, variables, expr, parameters_list, pool=pool, custom_ode_update=custom_ode_update) return ode_fun, variables
def make_mca_functions(kinetic_model, parameter_list, sim_type): """ Create the elasticity and flux functions for MCA :param kinmodel: :param parameter_list: :return: """ # Get all variables and expressions (Better solution with types?) # TODO This should be a method in KineticModel that stores the expressions if sim_type == QSSA: all_data = [] #TODO Modifiers sould be applicable for all simulation types for this_reaction in kinetic_model.reactions.values(): this_reaction.mechanism.get_qssa_rate_expression() # Update rate expressions for this_mod in this_reaction.modifiers.values(): this_mod(this_reaction.mechanism.reaction_rates) this_reaction.mechanism.update_qssa_rate_expression() for r_type, reactant in this_mod.reactants.items(): # Add massbalances for modfier reactants if as non-zero stoich if this_mod.reactant_stoichiometry[r_type] == 0: continue mod_sym = reactant.symbol flux = this_reaction.mechanism.reaction_rates['v_net'] flux_expression = flux * this_mod.reactant_stoichiometry[ r_type] this_reaction.mechanism.expressions[ mod_sym] = flux_expression # Add small molecule parameters if they are if reactant.type == PARAMETER: this_reaction.mechanism.expression_parameters.update( [mod_sym]) all_data.append((this_reaction.mechanism.expressions, this_reaction.mechanism.expression_parameters)) elif sim_type == TQSSA: raise (NotImplementedError) elif sim_type == ELEMENTARY: raise (NotImplementedError) else: raise ArgumentError( '{} is not recognized as a simulation type'.format(sim_type)) # Get flux expressions for the net all_flux_expressions = [this_reaction.mechanism.reaction_rates['v_net'] \ for this_reaction in kinetic_model.reactions.values()] all_expr, all_parameters = list(zip(*all_data)) # Flatten all the lists flatten_list = lambda this_list: [item for sublist in this_list \ for item in sublist] all_rates = flatten_list( [these_expressions.keys() for these_expressions in all_expr]) # Sort into an ordered list all_parameters = flatten_list(all_parameters) all_parameters = list(set(all_parameters)) all_parameters = iterable_to_tabdict(all_parameters, use_name=False) all_variables = TabDict([(k, v.symbol) for k, v in kinetic_model.reactants.items()]) all_independent_variables = TabDict([ (k, v) for e, (k, v) in enumerate(all_variables.items()) if e in kinetic_model.independent_variables_ix ]) all_dependent_variables = TabDict([ (k, v) for e, (k, v) in enumerate(all_variables.items()) if e in kinetic_model.dependent_variables_ix ]) #parameter elasticity function if parameter_list: parameter_elasticities_fun = make_elasticity_fun( all_flux_expressions, parameter_list, all_variables, all_parameters, kinetic_model.pool) else: parameter_elasticities_fun = None #concentration elasticity functions independent_elasticity_fun = make_elasticity_fun( all_flux_expressions, all_independent_variables, all_variables, all_parameters, kinetic_model.pool) if all_dependent_variables: dependent_elasticity_fun = make_elasticity_fun( all_flux_expressions, all_dependent_variables, all_variables, all_parameters, kinetic_model.pool) else: dependent_elasticity_fun = None return independent_elasticity_fun, dependent_elasticity_fun, parameter_elasticities_fun
def make_ode_fun(kinetic_model, sim_type, pool=None, custom_ode_update=None): """ :param kinetic_model: :param sim_type: :return: """ all_data = get_expressions_from_model(kinetic_model, sim_type) # get expressions for dxdt all_expr, _, all_parameters = list(zip(*all_data)) # Flatten all the lists flatten_list = lambda this_list: [item for sublist in this_list \ for item in sublist] all_parameters = flatten_list(all_parameters) all_parameters = list(set(all_parameters)) all_parameters = iterable_to_tabdict(all_parameters, use_name=False) # Better since this is implemented now reactant_items = kinetic_model.reactants.items() variables = TabDict([(k, v.symbol) for k, v in reactant_items]) #Compartments # CHECK IF THIS ONLY IS TRUE IF ITS NOT EMPTY if kinetic_model.compartments: #TODO Throw error if no cell reference compartment is given volume_ratios = TabDict([ (k, v.compartment.parameters.cell_volume.symbol / v.compartment.parameters.volume.symbol) for k, v in kinetic_model.reactants.items() ]) for comp in kinetic_model.compartments.values(): this_comp_parameters = { str(v.symbol): v.symbol for v in comp.parameters.values() } all_parameters.update(this_comp_parameters) else: volume_ratios = None expr = make_expressions(variables, all_expr, volume_ratios=volume_ratios, pool=pool) # Apply constraints. Constraints are modifiers that act on # expressions for this_constraint in kinetic_model.constraints.values(): this_constraint(expr) # NEW: Boundary conditions are now handled as parameters # Apply boundary conditions. Boundaries are modifiers that act on # expressions # for this_boundary_condition in kinetic_model.boundary_conditions.values(): # this_boundary_condition(expr) # Make vector function from expressions ode_fun = ODEFunction(kinetic_model, variables, expr, all_parameters, pool=pool, custom_ode_update=custom_ode_update) return ode_fun, variables