Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
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))
Пример #5
0
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)