def dynamic_function_from_file(obj, filename): """ Load a dynamic function from a file and attach it to the obj. (A Network or Trajectory.) The filename must be <function_name>.py """ f = file(filename, 'r') function_body = f.read() f.close() basename = os.path.basename(filename) func = os.path.splitext(basename)[0] file_type = os.path.splitext(basename)[1][1:] if isinstance(obj, Trajectory_mod.Trajectory): setattr(obj, '%s_functionBody' % func, function_body) # We try to get the attribute 'namespace' for the object. Network_mod._exec_dynamic_func(obj, func, getattr(obj, 'namespace', {})) elif isinstance(obj, Network_mod.Network): if file_type == 'py': obj._dynamic_funcs_python[func] = function_body obj.exec_dynamic_functions(disable_c = True) elif file_type == 'c': obj.exec_dynamic_functions(curr_c_code = function_body)
def dynamic_function_from_file(obj, filename): """ Load a dynamic function from a file and attach it to the obj. (A Network or Trajectory.) The filename must be <function_name>.py """ f = file(filename, 'r') function_body = f.read() f.close() basename = os.path.basename(filename) func = os.path.splitext(basename)[0] file_type = os.path.splitext(basename)[1][1:] if isinstance(obj, Trajectory_mod.Trajectory): setattr(obj, '%s_functionBody' % func, function_body) # We try to get the attribute 'namespace' for the object. Network_mod._exec_dynamic_func(obj, func, getattr(obj, 'namespace', {})) elif isinstance(obj, Network_mod.Network): if file_type == 'py': obj._dynamic_funcs_python[func] = function_body obj.exec_dynamic_functions(disable_c=True) elif file_type == 'c': obj.exec_dynamic_functions(curr_c_code=function_body)
def appendSensFromODEINT(self, timepoints, odeint_array, holds_dt=False): if getattr(self, '_assignment', None) is None: Network_mod._exec_dynamic_func(self, '_assignment', self.namespace, bind=False) if getattr(self, '_sens_assignment', None) is None: Network_mod._exec_dynamic_func(self, '_sens_assignment', self.namespace, bind=False) numAdded = odeint_array.shape[0] addedValues = scipy.zeros((numAdded, len(self.key_column)), scipy.float_) self.values = scipy.concatenate((self.values, addedValues)) self.timepoints = scipy.concatenate((self.timepoints, timepoints)) nDv = len(self.dynamicVarKeys) nOv = len(self.optimizableVarKeys) # fill in trajectory for ii, dvId in enumerate(self.dynamicVarKeys): self.values[-numAdded:, self.key_column.get(dvId)] = \ odeint_array[:, ii] # ... and sensitivities for ii, dvId in enumerate(self.dynamicVarKeys): for jj, ovId in enumerate(self.optimizableVarKeys): self.values[-numAdded:, self.key_column.get((dvId, ovId))]\ = odeint_array[:, ii + (jj+1)*nDv] self._assignment(self.values, self.timepoints, -numAdded, None) self._sens_assignment(self.values, self.timepoints, -numAdded, None) if holds_dt: # fill in the time derivative of the trajectory for ii, dvId in enumerate(self.dynamicVarKeys): self.values[-numAdded:, self.key_column.get((dvId,'time'))] = \ odeint_array[:, ii + nDv*(nOv+1)] # ... and of the sensitivities for ii, dvId in enumerate(self.dynamicVarKeys): for jj, ovId in enumerate(self.optimizableVarKeys): self.values[-numAdded:, self.key_column.get((dvId, ovId,'time'))]\ = odeint_array[:, ii + (jj+1)*nDv + nDv*(nOv+1)]
def appendSensFromODEINT(self, timepoints, odeint_array, holds_dt = False): if getattr(self, '_assignment', None) is None: Network_mod._exec_dynamic_func(self, '_assignment', self.namespace, bind=False) if getattr(self, '_sens_assignment', None) is None: Network_mod._exec_dynamic_func(self, '_sens_assignment', self.namespace, bind=False) numAdded = odeint_array.shape[0] addedValues = scipy.zeros((numAdded, len(self.key_column)), scipy.float_) self.values = scipy.concatenate((self.values, addedValues)) self.timepoints = scipy.concatenate((self.timepoints, timepoints)) nDv = len(self.dynamicVarKeys) nOv = len(self.optimizableVarKeys) # fill in trajectory for ii, dvId in enumerate(self.dynamicVarKeys): self.values[-numAdded:, self.key_column.get(dvId)] = \ odeint_array[:, ii] # ... and sensitivities for ii, dvId in enumerate(self.dynamicVarKeys): for jj, ovId in enumerate(self.optimizableVarKeys): self.values[-numAdded:, self.key_column.get((dvId, ovId))]\ = odeint_array[:, ii + (jj+1)*nDv] self._assignment(self.values, self.timepoints, -numAdded, None) self._sens_assignment(self.values, self.timepoints, -numAdded, None) if holds_dt : # fill in the time derivative of the trajectory for ii, dvId in enumerate(self.dynamicVarKeys): self.values[-numAdded:, self.key_column.get((dvId,'time'))] = \ odeint_array[:, ii + nDv*(nOv+1)] # ... and of the sensitivities for ii, dvId in enumerate(self.dynamicVarKeys): for jj, ovId in enumerate(self.optimizableVarKeys): self.values[-numAdded:, self.key_column.get((dvId, ovId,'time'))]\ = odeint_array[:, ii + (jj+1)*nDv + nDv*(nOv+1)]
def appendFromODEINT(self, timepoints, odeint_array, holds_dt = False): if getattr(self, '_assignment', None) is None: Network_mod._exec_dynamic_func(self, '_assignment', self.namespace, bind=False) numAdded = odeint_array.shape[0] addedValues = scipy.zeros((numAdded, len(self.key_column)), scipy.float_) self.values = scipy.concatenate((self.values, addedValues)) self.timepoints = scipy.concatenate((self.timepoints, timepoints)) for ii, id in enumerate(self.dynamicVarKeys): self.values[-numAdded:, self.key_column.get(id)] =\ odeint_array[:, ii] self._assignment(self.values, self.timepoints, -numAdded, None) if holds_dt : for ii, id in enumerate(self.dynamicVarKeys) : self.values[-numAdded:, self.key_column.get((id,'time'))] = \ odeint_array[:,ii+len(self.dynamicVarKeys)]
def createNetworkParameter(p): id, name = p.getId(), p.getName() v = p.getValue() isConstant = p.getConstant() parameter = Network_mod.Parameter(id=id, value=v, is_constant=isConstant, name=name, typical_value=None, is_optimizable=True) # optimizable by default return parameter
def fromSBMLString(sbmlStr, id=None, duplicate_rxn_params=False): r = libsbml.SBMLReader() d = r.readSBMLFromString(sbmlStr) if d.getNumErrors(): message = 'libSBML reported errors in SBML file. Try running file '\ 'through the online validator: '\ 'http://www.sbml.org/Facilities/Validator . Specific errors '\ 'noted are: ' errors = [] for ii in range(d.getNumErrors()): pm = d.getError(ii) errors.append(pm.getMessage()) print(message + '; '.join(errors)) m = d.getModel() modelId = m.getId() if (id is None) and (modelId == ''): raise ValueError('Network id not specified in SBML or passed in.') elif id is not None: modelId = id rn = Network_mod.Network(id=modelId, name=m.getName()) for f in m.getListOfFunctionDefinitions(): id, name = f.getId(), f.getName() math = f.getMath() variables = [] for ii in range(math.getNumChildren() - 1): variables.append(formula_to_py(math.getChild(ii))) math = formula_to_py(math.getRightChild()) rn.addFunctionDefinition(id, variables, math) for c in m.getListOfCompartments(): id, name = c.getId(), c.getName() size = c.getSize() isConstant = c.getConstant() rn.addCompartment(id=id, size=size, isConstant=isConstant, name=name) for s in m.getListOfSpecies(): id, name = s.getId(), s.getName() compartment = s.getCompartment() if s.isSetInitialConcentration(): iC = s.getInitialConcentration() elif s.isSetInitialAmount(): iC = s.getInitialAmount() else: iC = 1 isBC, isConstant = s.getBoundaryCondition(), s.getConstant() xml_text = s.toSBML() uniprot_ids = set([ entry[1:].split('"')[0] for entry in xml_text.split('uniprot')[1:] ]) rn.addSpecies(id=id, compartment=compartment, initialConcentration=iC, isConstant=isConstant, is_boundary_condition=isBC, name=name, uniprot_ids=uniprot_ids) for p in m.getListOfParameters(): parameter = createNetworkParameter(p) rn.addVariable(parameter) for rxn in m.getListOfReactions(): id, name = rxn.getId(), rxn.getName() kL = rxn.getKineticLaw() kLFormula = kL.getFormula() substitution_dict = {} # Deal with parameters defined within reactions for p in kL.getListOfParameters(): parameter = createNetworkParameter(p) # If a parameter with this name already exists, **and it has a # different value than this parameter** we rename this parameter # instance by prefixing it with the rxn name so there isn't a # clash. if parameter.id in rn.variables.keys(): logger.warn('Parameter %s appears in two different reactions ' 'in SBML file.' % parameter.id) if parameter.value != rn.variables.get(parameter.id).value or\ duplicate_rxn_params: oldId = parameter.id parameter.id = id + '_' + parameter.id substitution_dict[oldId] = parameter.id logger.warn('It has different values in the two positions ' 'so we are creating a new parameter %s.' % (parameter.id)) else: logger.warn('It has the same value in the two positions ' 'so we are only defining one parameter %s. ' 'This behavior can be changed with the option ' 'duplicate_rxn_params = True' % (parameter.id)) if parameter.id not in rn.variables.keys(): rn.addVariable(parameter) kLFormula = ExprManip.sub_for_vars(kLFormula, substitution_dict) # Assemble the stoichiometry. SBML has the annoying trait that # species can appear as both products and reactants and 'cancel out' # For each species appearing in the reaction, we build up a string # representing the stoichiometry. Then we'll simplify that string and # see whether we ended up with a float value in the end. stoichiometry = {} reactant_stoichiometry = {} product_stoichiometry = {} for reactant in rxn.getListOfReactants(): species = reactant.getSpecies() stoichiometry.setdefault(species, '0') stoich = reactant.getStoichiometryMath() stoich = stoichToString(reactant, stoich) stoichiometry[species] += '-(%s)' % stoich if species in reactant_stoichiometry: reactant_stoichiometry[species].append(stoich) else: reactant_stoichiometry[species] = [stoich] for product in rxn.getListOfProducts(): species = product.getSpecies() stoichiometry.setdefault(species, '0') stoich = product.getStoichiometryMath() stoich = stoichToString(product, stoich) stoichiometry[species] += '+(%s)' % stoich if species in product_stoichiometry: product_stoichiometry[species].append(stoich) else: product_stoichiometry[species] = [stoich] for species, stoich in stoichiometry.items(): stoich = ExprManip.simplify_expr(stoich) try: # Try converting the string to a float. stoich = float(stoich) except ValueError: pass stoichiometry[species] = stoich for modifier in rxn.getListOfModifiers(): stoichiometry.setdefault(modifier.getSpecies(), 0) rn.addReaction(id=id, stoichiometry=stoichiometry, kineticLaw=kLFormula, reactant_stoichiometry=reactant_stoichiometry, product_stoichiometry=product_stoichiometry) for ii, r in enumerate(m.getListOfRules()): if r.getTypeCode() == libsbml.SBML_ALGEBRAIC_RULE: math = formula_to_py(r.getMath()) rn.add_algebraic_rule(math) else: variable = r.getVariable() math = formula_to_py(r.getMath()) if r.getTypeCode() == libsbml.SBML_ASSIGNMENT_RULE: rn.addAssignmentRule(variable, math) elif r.getTypeCode() == libsbml.SBML_RATE_RULE: rn.addRateRule(variable, math) for ii, e in enumerate(m.getListOfEvents()): id, name = e.getId(), e.getName() if id == '': id = 'event%i' % ii try: # For libSBML 3.0 trigger_math = e.getTrigger().getMath() except AttributeError: # For older versions trigger_math = e.getTrigger() trigger = formula_to_py(trigger_math) if e.getDelay() is not None: try: # For libSBML 3.0 delay_math = e.getDelay().getMath() except AttributeError: # For older versions delay_math = e.getDelay() delay = formula_to_py(delay_math) else: delay = 0 timeUnits = e.getTimeUnits() eaDict = KeyedList() for ea in e.getListOfEventAssignments(): ea_formula = formula_to_py(ea.getMath()) ea_formula = ea_formula.replace('or(', 'or_func(') ea_formula = ea_formula.replace('and(', 'and_func(') eaDict.set(ea.getVariable(), ea_formula) rn.addEvent(id=id, trigger=trigger, eventAssignments=eaDict, delay=delay, name=name) for ii, con in enumerate(m.getListOfConstraints()): id, name = con.getId(), con.getName() if id == '': id = 'constraint%i' % ii trigger_math = con.getMath() trigger = formula_to_py(trigger_math) if con.isSetMessage(): message = con.getMessage() else: message = None rn.addConstraint(id=id, trigger=trigger, message=message, name=name) return rn