def cellzillafy(modelfile, tissuefile): #------------------------------------------------------------------------- def Diffusion_Correction(X, diffusion_dict, icell): corrections = 0 if X in diffusion_dict: D = symbols(diffusion_dict[X]) neighbors = T.neighbors_of(icell) xhere = symbols(indexify(X, icell, max_digits)) corrections = 0 for neighbor in neighbors: other_cell_number, common_edge_number, ell_over_A = neighbor xthere = symbols(indexify(X, other_cell_number, max_digits)) correction = ell_over_A * D * (xthere - xhere) correction = correction.subs({ xthere: specify(xthere), xhere: specify(xhere) }) corrections = corrections + correction return corrections #-------------------------------------------------------------------------- def numberfy_species(n, max_digits, ic, symbol_dict, diffusion_dict, odeterms): old_species_names = list(ic) old_species = [symbol_dict[X] for X in old_species_names] tissufied_ode_terms = {} for icell in range(n): # for each cell in the tissue # define names of the subscripted species # subscripted_species = [ indexify(X, icell, max_digits) for X in old_species_names ] new_species = [symbols(X) for X in subscripted_species] old_new = zip(old_species, new_species) i = 0 for X in old_species_names: newterm = odeterms[X] for (old, new) in old_new: newterm = newterm.subs(old, specify(new)) X_sub_i = subscripted_species[i] corrections = Diffusion_Correction(X, diffusion_dict, icell) newterm = newterm + corrections # index by string instead of symbol tissufied_ode_terms[X_sub_i] = newterm i += 1 return tissufied_ode_terms #-------------------------------------------------------------------------- cpu_in_the_beginning = time.clock() T = Tissue2D.readGeometryFile(tfile) n = len(T.cells) max_digits = round(ceil(log(n, 10))) # digits needed for pretty indices print "%5d" % (n), "cells in tissue." # # read the data file # (raw_reactions, ic, rates, frozenvars, functions, assignments, filename) = readmodel(INFILE=modelfile) # # # parse the raw_reactions # classes = {} DUMP = ("-DUMP" in argv) parsed_reactions = interpreter.invokeParser(raw_reactions, dump=DUMP) expanded_reactions = classify_input(parsed_reactions, n, len(ic), PRINT=True) symbol_dict = interpreter.makeSymbolDictionary(expanded_reactions, rates, ic) odeterms = interpreter.makeODETerms(expanded_reactions, symbol_dict, frozen=frozenvars) # # instantiate rates in output code # precode = [] for rate in sorted(list(rates)): precode.append(rate + "=" + str(rates[rate])) # unique_solution_variable = make_solution_variable(symbol_dict, list(ic)) # # determine species that have diffusion # diffusion_dict = make_diffusion_dictionary(parsed_reactions) # # repeat the reactions on each cell in the tissue # cpu_2 = time.clock() tissufied_ode_terms = numberfy_species(n, max_digits, ic, symbol_dict, diffusion_dict, odeterms) cpu_3 = time.clock() print "generate code as Species(name(cell)): ", cpu_3 - cpu_2, " seconds." # # generate replacement rules to number all species # 0 to ncells-1: first species # ncells to 2ncells-1: second species # 2ncells to 3ncells-1: third species # ... # Species_Names = sorted(map(str, list(tissufied_ode_terms))) Species_Zip = zip(Species_Names, range(len(Species_Names))) Species_Name_to_Number = {name: num for name, num in Species_Zip} code = precode cpu_4 = time.clock() for S in Species_Names: rhs = tissufied_ode_terms[S] rhs = str(rhs) # # # insert string replacement to replace "_SPECIES_(k)" --> y[k] # # REGULAR EXPRESSION SYNTAX: ?P<fred>d+ means create a group named "fred" # the d+ matches to one or more digits # \g<fred> in the second argument replaces the # corresponding match from the first argument for (vari, index) in Species_Zip: fromstring = "_SPECIES_\(" + vari + "\)" tostring = unique_solution_variable + "[" + str(index) + "]" rhs = re.sub(fromstring, tostring, rhs) # # do the lhs of the equations: (dX/dt) --> yprime[i] # #lhs = "_SPECIES_PRIME_("+str(S_Replace[S])+")" lhs = "_SPECIES_PRIME_(" + str(Species_Name_to_Number[S]) + ")" lhs=re.sub("_SPECIES_PRIME_\((?P<fred>\d+)\)", \ unique_solution_variable+"prime[\g<fred>]", \ lhs) code.append(lhs + "=" + rhs) # cpu_5 = time.clock() substime = cpu_5 - cpu_4 print "convert (SPECIES(name(cell)) --> y[i]):", substime, " seconds." code = [4 * (" ") + L for L in code] headers = function_header() code = headers + code + [" return yprime"] print "total time to generate all code: ", time.clock( ) - cpu_in_the_beginning, " seconds." return (code)
def cellzillafy(modelfile, tissuefile): #------------------------------------------------------------------------- def Diffusion_Correction(X, diffusion_dict, icell): corrections = 0 if X in diffusion_dict: D = symbols(diffusion_dict[X]) neighbors = T.neighbors_of(icell) xhere = symbols(indexify(X,icell, max_digits)) corrections=0 for neighbor in neighbors: other_cell_number, common_edge_number, ell_over_A=neighbor xthere = symbols(indexify(X,other_cell_number, max_digits)) correction = ell_over_A * D * (xthere - xhere) correction = correction.subs({xthere:specify(xthere), xhere:specify(xhere)}) corrections = corrections + correction return corrections #-------------------------------------------------------------------------- def numberfy_species(n, max_digits, ic, symbol_dict, diffusion_dict, odeterms): old_species_names = list(ic) old_species = [symbol_dict[X] for X in old_species_names] tissufied_ode_terms={} for icell in range(n): # for each cell in the tissue # define names of the subscripted species # subscripted_species = [indexify(X, icell, max_digits) for X in old_species_names] new_species=[symbols(X) for X in subscripted_species] old_new = zip(old_species, new_species) i=0 for X in old_species_names: newterm = odeterms[X] for (old, new) in old_new: newterm = newterm.subs(old, specify(new)) X_sub_i = subscripted_species[i] corrections = Diffusion_Correction(X, diffusion_dict, icell) newterm = newterm + corrections # index by string instead of symbol tissufied_ode_terms[X_sub_i]=newterm i += 1 return tissufied_ode_terms #-------------------------------------------------------------------------- cpu_in_the_beginning = time.clock() T = Tissue2D.readGeometryFile(tfile) n=len(T.cells) max_digits = round( ceil(log(n,10))) # digits needed for pretty indices print "%5d" %(n),"cells in tissue." # # read the data file # (raw_reactions, ic, rates, frozenvars, functions,assignments, filename)=readmodel(INFILE=modelfile) # # # parse the raw_reactions # classes = {} DUMP = ("-DUMP" in argv) parsed_reactions = interpreter.invokeParser(raw_reactions, dump=DUMP) expanded_reactions=classify_input(parsed_reactions, n, len(ic), PRINT=True) symbol_dict=interpreter.makeSymbolDictionary(expanded_reactions, rates, ic) odeterms = interpreter.makeODETerms(expanded_reactions, symbol_dict, frozen=frozenvars) # # instantiate rates in output code # precode=[] for rate in sorted(list(rates)): precode.append(rate+"="+str(rates[rate])) # unique_solution_variable = make_solution_variable(symbol_dict, list(ic)) # # determine species that have diffusion # diffusion_dict = make_diffusion_dictionary(parsed_reactions) # # repeat the reactions on each cell in the tissue # cpu_2 = time.clock() tissufied_ode_terms= numberfy_species(n, max_digits, ic, symbol_dict, diffusion_dict, odeterms) cpu_3 = time.clock() print "generate code as Species(name(cell)): ", cpu_3-cpu_2, " seconds." # # generate replacement rules to number all species # 0 to ncells-1: first species # ncells to 2ncells-1: second species # 2ncells to 3ncells-1: third species # ... # Species_Names = sorted(map(str, list(tissufied_ode_terms))) Species_Zip = zip(Species_Names, range(len(Species_Names))) Species_Name_to_Number = {name:num for name,num in Species_Zip} code = precode cpu_4=time.clock() for S in Species_Names: rhs = tissufied_ode_terms[S] rhs = str(rhs) # # # insert string replacement to replace "_SPECIES_(k)" --> y[k] # # REGULAR EXPRESSION SYNTAX: ?P<fred>d+ means create a group named "fred" # the d+ matches to one or more digits # \g<fred> in the second argument replaces the # corresponding match from the first argument for (vari, index) in Species_Zip: fromstring = "_SPECIES_\("+vari+"\)" tostring = unique_solution_variable+"["+str(index)+"]" rhs = re.sub(fromstring, tostring, rhs) # # do the lhs of the equations: (dX/dt) --> yprime[i] # #lhs = "_SPECIES_PRIME_("+str(S_Replace[S])+")" lhs = "_SPECIES_PRIME_("+str(Species_Name_to_Number[S])+")" lhs=re.sub("_SPECIES_PRIME_\((?P<fred>\d+)\)", \ unique_solution_variable+"prime[\g<fred>]", \ lhs) code.append(lhs + "=" + rhs ) # cpu_5=time.clock() substime = cpu_5-cpu_4 print "convert (SPECIES(name(cell)) --> y[i]):", substime, " seconds." code = [4*(" ")+L for L in code] headers=function_header() code = headers + code + [" return yprime"] print "total time to generate all code: ", time.clock()-cpu_in_the_beginning," seconds." return (code)
def generatePythonFunction(reactions, rates, ics, frozenvars, functions, assignments, holdrates=[], substituteRates=False): """ input: reactions - list of reactions in cellerator text form inputrates - list of rate constants in dictionary form output: writes a function to file tmp.py that is solver-compatible return values: (y, y0) y: list of string names of variables ["y1", "y2",...] y0: list of values of variables at initial time """ #print "solver:assignments:",assignments #print "solver:frozenvars:",frozenvars d = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") codefile = utils.uniqueFileName("tmp.py") f = open(codefile, "w") f.write("from math import *\n") if len(functions) > 0: f.write("\n") for funct in functions: f.write(funct + "\n") f.write("\n") f.write("def ode_function_rhs(y,t):\n") f.write(" # \n") f.write(" # this odeint(..) compatible function was \n") f.write(" # automatically generated by Cellerator " + d + " \n") ver = sys.version.replace("\n", " ") f.write(" # " + ver + "\n") f.write(" # " + sys.platform + "\n") f.write(" # \n") f.write( " # =============================================================\n") f.write(" # Model: \n #\n") # # there may be a whole boatload of reactions to print # define a generator def printable_reaction(k): for j in xrange(k): reaction = reactions[j] yield " # " + reaction.strip() + "\n" for r in printable_reaction(len(reactions)): f.write(r) #for reaction in reactions: # f.write(" # " + reaction.strip() + "\n") # # write a whole shitload of comments with the rate constants, unless # the rate constants are themselves written out # if substituteRates: f.write(" #\n # Parameter values used: \n #\n") for r in rates: f.write(" # " + r + "=" + str(rates[r]) + "\n") if len(holdrates) > 0: f.write(" global " + holdrates[0] + "\n") if len(frozenvars) > 0: f.write( " #\n # Frozen Variables (species with fixed derivatives):\n #\n" ) for v in frozenvars: f.write(" # " + str(v) + "\n") f.write( " # =============================================================\n") results = interpreter.invokeParser(reactions, dump=False) results = expand(results) s = interpreter.makeSymbolDictionary(results, rates, ics) odeterms = interpreter.makeODETerms(results, s, frozen=frozenvars) if substituteRates: newterms = substituteRateConstants(odeterms, rates, s, holdrates) na = [] # rate constants also appear in assignment rules for a in assignments: value, assignment = a.split("=") assignment = sympify(assignment) newassignment = value + "=" + str( applyReplacementRules(assignment, rates, s)) na.append(newassignment) assignments = na else: # better this way because applyReplacementRules grows superquadratically newterms = odeterms ks = rates.keys() ks.sort() f.write(" # rate constants\n") for k in ks: if k in holdrates: continue v = rates[k] nextline = " " + k + " = " + str(v) + "\n" f.write(nextline) (y, yprime, ics) = makeODEfunc(newterms, s, ics) y = map(str, y) yprime = map(str, yprime) f.write("# pick up values from previous iteration\n") n = len(y) for i in range(n): nextline = " " + y[i] + " = " + "max(0, y[" + str(i) + "])\n" # nextline = nextline.replace("{", "[").replace("}", "]") # f.write(nextline) if (len(assignments) > 0): f.write("# apply boundary conditions / assignment rules \n") for a in assignments: f.write(" " + a + "\n") f.write("# calculate derivatives of all variables\n") f.write(" yp=[0 for i in range(" + str(n) + ")]\n") for i in range(n): nextline = " yp[" + str(i) + "] = " + yprime[i] + "\n" # # # nextline = nextline.replace("{", "[").replace("}", "]") # # f.write(nextline) #print "solver:",nextline f.write(" return yp\n") f.close() #sys.exit() return (y, ics, codefile)
def genmodel(infile, outfile, verbose=False): (reactions, ic, rates, frozenvars, functions, assignments, filename) = readmodel(infile) # Expand reactions # r = interpreter.invokeParser(reactions, dump=False) er = expander.expand(r) s = interpreter.makeSymbolDictionary(er, rates, ic) try: SBML=SBMLDocument(3,1) except ValueError: exit("Could not create the SBMLDocument.") m = SBML.createModel() m.setTimeUnits("dimensionless") m.setSubstanceUnits("item") m.setExtentUnits("item") c = m.createCompartment() c.setId('compartment') c.setConstant(True) c.setSize(1) c.setSpatialDimensions(3) c.setUnits("dimensionless") for function in functions: if verbose: print "function: ", function fnew=m.createFunctionDefinition() fname, formula = function.split("=") fname=fname.strip() formula=formula.strip() formula=formula.replace("**","^") functionvar, functiondef=formula.split(":") # print "functiondef:", functiondef functionvar=functionvar.split()[-1] # print "functionvar:", functionvar lambdadef="lambda("+functionvar+","+functiondef+")" # print "lambdadef: ", lambdadef math_ast = parseL3Formula(lambdadef) # print "math_ast=",math_ast fnew.setId(fname) fnew.setMath(math_ast) species=list(ic) sp=[] for specie in species: snew=m.createSpecies() snew.setId(specie) if specie in frozenvars: snew.setConstant(True) else: snew.setConstant(False) snew.setBoundaryCondition(False) snew.setHasOnlySubstanceUnits(True) amount = ic[specie] snew.setInitialAmount(amount) snew.setCompartment("compartment") sp.append(snew) # add nil species snew=m.createSpecies() snew.setId("Nil") snew.setConstant(False) snew.setBoundaryCondition(False) snew.setHasOnlySubstanceUnits(True) snew.setInitialAmount(0) snew.setCompartment("compartment") sp.append(snew) RATES=list(rates) ks=[] for rate in rates: k = m.createParameter() k.setId(rate) k.setConstant(True) k.setValue(rates[rate]) k.setUnits('dimensionless') ks.append(k) #print assignments i=1 for assignment in assignments: lhs, rhs = assignment.split("=") lhs=lhs.strip() rhs=rhs.strip() if verbose: print "assignment: to:", lhs, "from:",rhs arule = m.createAssignmentRule() patchedlaw=rhs.replace("**","^") math_ast = parseL3Formula(patchedlaw) arule.setMath(math_ast) arule.setVariable(lhs) aid = "arule"+str(i) i+=1 arule.setId(aid) reacts=[] i = 1 for line in er: new_reaction=m.createReaction() rid = "r"+str(i) new_reaction.setId(rid) new_reaction.setReversible(False) new_reaction.setFast(False) odeterm = interpreter.makeODETerms([line], s, frozen=frozenvars) termkeys=list(odeterm) # print "termkeys:", termkeys # print "**** Reaction ", i,"\n", line.LHS(),"\n",line.MHS(),"\n",line.RHS() S, ST = reduceStoichiometry(line.LHS(), line.LH_STOIC()) # print "reactant: ", S, ST for X,Z in zip(S, ST): if X in termkeys: sref=new_reaction.createReactant() sref.setSpecies(X) sref.setStoichiometry(float(Z)) if X in frozenvars: sref.setConstant(True) else: sref.setConstant(False) # # some Cellerator "Reactants" are really modifiers # elif str(X) != "Nil": sref=new_reaction.createModifier() sref.setSpecies(X) S, ST = reduceStoichiometry(line.RHS(), line.RH_STOIC()) # print "product: ", S, ST for X,Z in zip(S, ST): sref=new_reaction.createProduct() sref.setSpecies(X) sref.setStoichiometry(float(Z)) if X in frozenvars: sref.setConstant(True) else: sref.setConstant(False) for X in line.MHS(): sref=new_reaction.createModifier() sref.setSpecies(X) terms = [str(odeterm[X]) for X in termkeys] # print "terms: ", terms terms = map(lambda x: x.lstrip("-"), terms) terms = set(terms) - set(["0"]) if len(terms)>0: law = list(terms)[0] else: law = "0" if verbose: print "using kinetic law ", law, " for "+str(rid)+": ", line.Input() patchedlaw=law.replace("**","^") math_ast = parseL3Formula(patchedlaw) kinetic_law = new_reaction.createKineticLaw() kinetic_law.setMath(math_ast) # print "kinetic law ", i, " is ", law, odeterm i +=1 return (writeSBMLToString(SBML))
def generatePythonFunction(reactions, rates, ics, frozenvars, functions, assignments, holdrates=[], substituteRates=False): """ input: reactions - list of reactions in cellerator text form inputrates - list of rate constants in dictionary form output: writes a function to file tmp.py that is solver-compatible return values: (y, y0) y: list of string names of variables ["y1", "y2",...] y0: list of values of variables at initial time """ #print "solver:assignments:",assignments #print "solver:frozenvars:",frozenvars d=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") codefile=utils.uniqueFileName("tmp.py") f=open(codefile,"w") f.write("from math import *\n") if len(functions)>0: f.write("\n") for funct in functions: f.write(funct+"\n") f.write("\n") f.write("def ode_function_rhs(y,t):\n") f.write(" # \n") f.write(" # this odeint(..) compatible function was \n") f.write(" # automatically generated by Cellerator "+d+" \n") ver = sys.version.replace("\n"," ") f.write(" # " + ver + "\n") f.write(" # " + sys.platform + "\n") f.write(" # \n") f.write(" # =============================================================\n") f.write(" # Model: \n #\n") # # there may be a whole boatload of reactions to print # define a generator def printable_reaction(k): for j in xrange(k): reaction=reactions[j] yield " # " + reaction.strip() + "\n" for r in printable_reaction(len(reactions)): f.write(r) #for reaction in reactions: # f.write(" # " + reaction.strip() + "\n") # # write a whole shitload of comments with the rate constants, unless # the rate constants are themselves written out # if substituteRates: f.write(" #\n # Parameter values used: \n #\n") for r in rates: f.write(" # " + r + "=" + str(rates[r]) + "\n") if len(holdrates)>0: f.write(" global "+holdrates[0]+"\n") if len(frozenvars) >0: f.write(" #\n # Frozen Variables (species with fixed derivatives):\n #\n") for v in frozenvars: f.write(" # "+str(v)+ "\n") f.write(" # =============================================================\n") results = interpreter.invokeParser(reactions, dump=False) results = expand(results) s=interpreter.makeSymbolDictionary(results, rates, ics) odeterms = interpreter.makeODETerms(results, s, frozen=frozenvars) if substituteRates: newterms = substituteRateConstants(odeterms, rates, s, holdrates) na = [] # rate constants also appear in assignment rules for a in assignments: value,assignment = a.split("=") assignment = sympify(assignment) newassignment = value+"="+str(applyReplacementRules(assignment, rates, s)) na.append(newassignment) assignments = na else: # better this way because applyReplacementRules grows superquadratically newterms = odeterms ks=rates.keys() ks.sort() f.write(" # rate constants\n") for k in ks: if k in holdrates: continue v=rates[k] nextline=" "+k+" = " + str(v)+"\n" f.write(nextline) (y, yprime, ics) = makeODEfunc(newterms, s, ics) y = map(str, y) yprime = map(str,yprime) f.write("# pick up values from previous iteration\n") n = len(y) for i in range(n): nextline = " "+y[i]+" = "+"max(0, y["+str(i)+"])\n" # nextline = nextline.replace("{","[").replace("}","]") # f.write(nextline) if (len(assignments)>0): f.write("# apply boundary conditions / assignment rules \n") for a in assignments: f.write(" "+a+"\n") f.write("# calculate derivatives of all variables\n") f.write(" yp=[0 for i in range("+str(n)+")]\n") for i in range(n): nextline = " yp["+str(i)+"] = " + yprime[i]+"\n" # # # nextline = nextline.replace("{","[").replace("}","]") # # f.write(nextline) #print "solver:",nextline f.write(" return yp\n") f.close() #sys.exit() return (y, ics, codefile)