def postAnalyzeFile(outputFile, bngLocation, database):
    """
    Performs a postcreation file analysis based on context information
    """
    #print('Transforming generated BNG file to BNG-XML representation for analysis')

    postAnalysisHelper(outputFile, bngLocation, database)

    # recreate file using information from the post analysis
    returnArray = analyzeHelper(database.document, database.reactionDefinitions, database.useID,
                                outputFile, database.speciesEquivalence, database.atomize, database.translator, database)
    with open(outputFile, 'w') as f:
        f.write(returnArray.finalString)
    # recompute bng-xml file
    consoleCommands.bngl2xml(outputFile)
    bngxmlFile = '.'.join(outputFile.split('.')[:-1]) + '.xml'
    # recompute context information
    contextAnalysis = postAnalysis.ModelLearning(bngxmlFile)

    # get those species patterns that follow uncommon motifs
    motifSpecies, motifDefinitions = contextAnalysis.processContextMotifInformation(database.assumptions['lexicalVsstoch'], database)
    #motifSpecies, motifDefinitions = contextAnalysis.processAllContextInformation()
    if len(motifDefinitions) > 0:
        logMess('INFO:CTX003', 'Species with suspect context information were found. Information is being dumped to {0}_context.log'.format(outputFile))
        with open('{0}_context.log'.format(outputFile), 'w') as f:
            pprint.pprint(dict(motifSpecies), stream=f)
            pprint.pprint(motifDefinitions, stream=f)
Example #2
0
 def changeToBNGL(functionList,rule,function):
     oldrule = ''
     #if the rule contains any mathematical function we need to reformat
     while any([re.search(r'(\W|^)({0})(\W|$)'.format(x),rule) != None for x in functionList]) and (oldrule != rule):
         oldrule = rule
         for x in functionList:
             rule  = re.sub('({0})\(([^,]+),([^)]+)\)'.format(x),function,rule)
         if rule == oldrule:
             logMess('ERROR:Translation','Malformed pow or root function %s' % rule)
             print 'meep'
     return rule
Example #3
0
def sanityCheck(database):
    '''
    checks for critical atomization errors like isomorphism
    '''
    stringrep = {x: str(database.translator[x]) for x in database.translator}
    repeats = set()
    for key in range(0, len(database.translator.keys()) - 1):
        for key2 in range(key + 1, len(database.translator.keys())):
            if stringrep[database.translator.keys()[key]] == stringrep[database.translator.keys()[key2]]:
                repeats.add((database.translator.keys()[key], database.translator.keys()[key2]))
    for repeat in repeats:
        temp = sorted(repeat)
        logMess('ERROR:SCT241', '{0}:{1}:produce the same translation:{2}:{1}:was empied'.format(temp[0], temp[1], database.prunnedDependencyGraph[temp[0]][0]))
        if temp[1] in database.translator:
            database.translator.pop(repeat[1])
Example #4
0
 def changeToBNGL(functionList, rule, function):
     oldrule = ''
     #if the rule contains any mathematical function we need to reformat
     while any([
             re.search(r'(\W|^)({0})(\W|$)'.format(x), rule) != None
             for x in functionList
     ]) and (oldrule != rule):
         oldrule = rule
         for x in functionList:
             rule = re.sub('({0})\(([^,]+),([^)]+)\)'.format(x), function,
                           rule)
         if rule == oldrule:
             logMess('ERROR', 'Malformed pow or root function %s' % rule)
             print 'meep'
     return rule
Example #5
0
def propagateChanges(translator, dependencyGraph):
    flag = True
    while flag:
        flag = False
        for dependency in dependencyGraph:
            if dependencyGraph[dependency] == []:
                continue
            for molecule in dependencyGraph[dependency][0]:
                try:
                    if updateSpecies(translator[dependency],
                                     translator[getTrueTag(dependencyGraph,
                                                           molecule)].molecules[0]):
                        flag = True
                except:
                    logMess('CRITICAL:Program',
                            'Species is not being properly propagated')
                    flag = False
Example #6
0
def postAnalyzeFile(outputFile, bngLocation, database):
    """
    Performs a postcreation file analysis based on context information
    """
    #print('Transforming generated BNG file to BNG-XML representation for analysis')
    consoleCommands.setBngExecutable(bngLocation)
    outputDir = os.sep.join(outputFile.split(os.sep)[:-1])
    if outputDir != '':
        retval = os.getcwd()
        os.chdir(outputDir)
    consoleCommands.bngl2xml(outputFile.split(os.sep)[-1])
    if outputDir != '':
        os.chdir(retval)
    bngxmlFile = '.'.join(outputFile.split('.')[:-1]) + '.xml'
    #print('Sending BNG-XML file to context analysis engine')
    contextAnalysis = postAnalysis.ModelLearning(bngxmlFile)
    # analysis of redundant bonds
    deleteBonds = contextAnalysis.analyzeRedundantBonds(database.assumptions['redundantBonds'])

    modificationFlag = True

    for molecule in database.assumptions['redundantBondsMolecules']:
        if molecule[0] in deleteBonds:
            for bond in deleteBonds[molecule[0]]:
                database.translator[molecule[1]].deleteBond(bond)
                logMess('INFO:Atomization', 'Used context information to determine that the bond {0} in species {1} is not likely'.format(bond,molecule[1]))

    returnArray = analyzeHelper(database.document, database.reactionDefinitions, database.useID,
                                outputFile, database.speciesEquivalence, database.atomize, database.translator)
    with open(outputFile, 'w') as f:
        f.write(returnArray.finalString)
    # recompute bng-xml file
    consoleCommands.bngl2xml(outputFile)
    bngxmlFile = '.'.join(outputFile.split('.')[:-1]) + '.xml'
    # recompute context information
    contextAnalysis = postAnalysis.ModelLearning(bngxmlFile)

    # get those species patterns that follow uncommon motifs
    motifSpecies, motifDefinitions = contextAnalysis.processContextMotifInformation(database.assumptions['lexicalVsstoch'], database)
    #motifSpecies, motifDefinitions = contextAnalysis.processAllContextInformation()
    if len(motifDefinitions) > 0:
        logMess('WARNING:ContextAnalysis', 'Species with suspect context information were found. Information is being dumped to {0}_context.log'.format(outputFile))
        with open('{0}_context.log'.format(outputFile), 'w') as f:
            pprint.pprint(dict(motifSpecies), stream=f)
            pprint.pprint(motifDefinitions, stream=f)
def postAnalysisHelper(outputFile, bngLocation, database):
    consoleCommands.setBngExecutable(bngLocation)
    outputDir = os.sep.join(outputFile.split(os.sep)[:-1])
    if outputDir != '':
        retval = os.getcwd()
        os.chdir(outputDir)
    consoleCommands.bngl2xml(outputFile.split(os.sep)[-1])
    if outputDir != '':
        os.chdir(retval)
    bngxmlFile = '.'.join(outputFile.split('.')[:-1]) + '.xml'
    #print('Sending BNG-XML file to context analysis engine')
    contextAnalysis = postAnalysis.ModelLearning(bngxmlFile)
    # analysis of redundant bonds
    deleteBonds = contextAnalysis.analyzeRedundantBonds(database.assumptions['redundantBonds'])
    for molecule in database.assumptions['redundantBondsMolecules']:
        if molecule[0] in deleteBonds:
            for bond in deleteBonds[molecule[0]]:
                database.translator[molecule[1]].deleteBond(bond)
                logMess('INFO:CTX002', 'Used context information to determine that the bond {0} in species {1} is not likely'.format(bond,molecule[1]))
Example #8
0
def printTranslate(chemical,tags,translator={}):
    tmp = []
    if chemical[0] not in translator:
        app = chemical[0] + '()' + tags
    else:
        translator[chemical[0]].addCompartment(tags)
        app = str(translator[chemical[0]])
    if float(int(chemical[1])) == chemical[1]:
        for item in range(0,int(chemical[1])):
            tmp.append(app)
    else:
        idx = logMess("ERROR:Simulation","Cannot deal with non integer stoicheometries: {0}* {1}".format(chemical[1],chemical[0]))
        tmp.append(app)
    return ' + '.join(tmp)
Example #9
0
def printTranslate(chemical, tags, translator={}):
    tmp = []
    if chemical[0] not in translator:
        app = chemical[0] + '()' + tags
    else:
        translator[chemical[0]].addCompartment(tags)
        app = str(translator[chemical[0]])
    if float(int(chemical[1])) == chemical[1]:
        for item in range(0, int(chemical[1])):
            tmp.append(app)
    else:
        idx = logMess(
            "ERROR:Simulation",
            "Cannot deal with non integer stoicheometries: {0}* {1}".format(
                chemical[1], chemical[0]))
        tmp.append(app)
    return ' + '.join(tmp)
Example #10
0
def atomize(dependencyGraph, weights, translator, reactionProperties,
            equivalenceDictionary, bioGridFlag, sbmlAnalyzer, database, parser):
    '''
    The atomizer's main methods. Receives a dependency graph
    '''
    redrawflag = True
    loops = 0
    while redrawflag and loops < 10:
        loops +=1
        bindingCounter = Counter()
        bindingFailureDict = {}

        for idx, element in enumerate(weights):
            # 0 molecule
            if element[0] == '0':
                continue
            # user defined molecules to be the zero molecule
            if dependencyGraph[element[0]] == [['0']]:
                zeroSpecies = st.Species()
                zeroMolecule = st.Molecule('0')
                zeroSpecies.addMolecule(zeroMolecule)
                translator[element[0]] = zeroSpecies
                continue
            # undivisible molecules

            elif dependencyGraph[element[0]] == []:
                if element[0] not in translator:
                    translator[element[0]] = createEmptySpecies(element[0])
            else:
                if len(dependencyGraph[element[0]][0]) == 1:
                    # catalysis
                    createCatalysisRBM(dependencyGraph, element, translator, reactionProperties,
                                       equivalenceDictionary, sbmlAnalyzer, database)
                else:
                    try:
                        createBindingRBM(element, translator, dependencyGraph,
                                         bioGridFlag, database.pathwaycommons, parser, database)

                    except BindingException as e:
                        for c in e.combinations:
                            bindingCounter[c] += 1
                            bindingFailureDict[element[0]] = e.combinations
                        logMess('DEBUG:ATO003', "We don't know how {0} binds together in complex {1}. Not atomizing".format(
                                e.value, element[0]))
            
                        # there awas an issue during binding, don't atomize
                        translator[element[0]] = createEmptySpecies(element[0])
        
        # evaluate species that weren't bound properly and see if we can get information from all over the model to find the right binding partner
        bindingTroubleLog = defaultdict(list)
        modifiedPairs = set()

        redrawflag = False
        for molecule in bindingFailureDict:
            bindingWinner = defaultdict(list)
            for candidateTuple in bindingFailureDict[molecule]:
                bindingWinner[bindingCounter[candidateTuple]].append(candidateTuple)
            bestBindingCandidates = bindingWinner[max(bindingWinner.keys())]
            if len(bestBindingCandidates) > 1:
                bindingTroubleLog[tuple(sorted(bestBindingCandidates))].append(molecule)
            else:
                bindingPair = bestBindingCandidates[0]
                if bindingPair not in modifiedPairs:
                    modifiedPairs.add(bindingPair)
                else:
                    continue
                c1 = st.Component(bindingPair[1].lower())
                c2 = st.Component(bindingPair[0].lower())
                molecule1 = translator[translator[bindingPair[0]].molecules[0].name].molecules[0]
                molecule2 = translator[translator[bindingPair[1]].molecules[0].name].molecules[0]

                molecule1.addComponent(c1)
                molecule2.addComponent(c2)
                redrawflag = True
                logMess('INFO:ATO031','Determining that {0} binds together based on frequency of the bond in the reaction network.'.format(bindingPair))
    for trouble in bindingTroubleLog:
        logMess('ERROR:ATO202','{0}:{1}:We need information to resolve the bond structure of these complexes . \
Please choose among the possible binding candidates that had the most observed frequency in the reaction network or provide a new one'.format(bindingTroubleLog[trouble],trouble))
Example #11
0
def createCatalysisRBM(dependencyGraph, element, translator, reactionProperties,
                       equivalenceDictionary, sbmlAnalyzer, database):
    '''
    if it's a catalysis reaction create a new component/state
    '''
    if dependencyGraph[element[0]][0][0] == element[0]:
        if element[0] not in translator:
            translator[element[0]] = createEmptySpecies(element[0])
    else:
        componentStateArray = []
        tmp = element[0]
        existingComponents = []
        memory = []
        forceActivationSwitch = False
        while dependencyGraph[tmp] != []:
            # what kind of catalysis are we dealing with
            # classification = identifyReaction(
            #                                  equivalenceDictionary,
            #                                  dependencyGraph[tmp][0][0],tmp)

            classifications = None
            if not classifications:
                classifications = identifyReaction(
                    equivalenceDictionary,
                    dependencyGraph[tmp][0][0], tmp)
                classifications = classifications if classifications in reactionProperties else None
                if classifications is not None:
                    classifications = [classifications]
            if not classifications:
                classifications = sbmlAnalyzer.findMatchingModification(
                    tmp, dependencyGraph[tmp][0][0])

            if not classifications:
                classifications = sbmlAnalyzer.findMatchingModification(
                    element[0], dependencyGraph[tmp][0][0])

            # if we know what classification it is then add the corresponding
            # components and states
            if classifications is not None:
                for classification in classifications:
                    componentStateArray.append(
                        reactionProperties[classification])
                    # classificationArray.append([classification,
                    #                            tmp,dependencyGraph[tmp]
                    #                            [0][0]])
                    existingComponents.append(
                        reactionProperties[classification][0])
            # if we don't know we can create a force 1:1 modification
            elif database.forceModificationFlag and classifications is None and not forceActivationSwitch:
                forceActivationSwitch = True
                baseName = getTrueTag(dependencyGraph,
                                      dependencyGraph[element[0]][0][0])

                species = createEmptySpecies(baseName)

                componentStateArray.append(['{0}'.format(tmp), tmp])
                if not (element[0] in database.userLabelDictionary and database.userLabelDictionary[element[0]][0][0] == baseName):
                    logMess('WARNING:LAE002', 'adding forced transformation: {0}:{1}:{2}'.format(
                        baseName, dependencyGraph[element[0]][0][0], element[0]))
                # return
            # bail out if we couldn't figure out what modification it is
            elif classifications is None:
                logMess('DEBUG:MSC001', 'unregistered modification: {0}:{1}'.format(
                    element[0], dependencyGraph[element[0]]))
            memory.append(tmp)
            tmp = dependencyGraph[tmp][0][0]
            if tmp in memory:
                raise atoAux.CycleError(memory)
        baseName = getTrueTag(
            dependencyGraph, dependencyGraph[element[0]][0][0])

        species = createEmptySpecies(baseName)
        # use the already existing structure if its in the
        # translator,otherwise empty
        if baseName in translator:
            species = translator[baseName]
        #modifiedSpecies = deepcopy(translator[dependencyGraph[element[0]][0][0]])

        # modified species needs to start from the base speceis sine componentStateArray should contain the full set of modifications
        # check that this works correctly for double modifications
        modifiedSpecies = deepcopy(translator[baseName])
        # this counter is here for multi level modification events (e.g. double
        # phosporylation)
        modificationCounter = {
            componentState[0]: 2 for componentState in componentStateArray}
        for componentState in componentStateArray:
            addComponentToMolecule(species, baseName, componentState[0])
            addComponentToMolecule(
                modifiedSpecies, baseName, componentState[0])
            tmp = addStateToComponent(species, baseName,
                                      componentState[0], componentState[1])
            if tmp == componentState[1]:
                addStateToComponent(species, baseName, componentState[0],
                                    componentState[1] + componentState[1])
            # this modification was already activated so create a second
            # modification component
            if addStateToComponent(modifiedSpecies, baseName,
                                   componentState[0], componentState[1]) == componentState[1]:
                componentName = '{0}{1}'.format(
                    componentState[0],  modificationCounter[componentState[0]])
                modificationCounter[componentState[0]] += 1
                addComponentToMolecule(
                    modifiedSpecies, baseName, componentName)
                addStateToComponent(modifiedSpecies, baseName, componentName,
                                    componentState[1])
            addStateToComponent(species, baseName, componentState[0], '0')
        # update the base species
        if len(componentStateArray) > 0:
            translator[baseName] = deepcopy(species)
            translator[element[0]] = modifiedSpecies
Example #12
0
def getComplexationComponents2(moleculeName, species, bioGridFlag, pathwaycommonsFlag=False,
                               parser=None, bondSeeding=[], bondExclusion=[], database=None):
    '''
    method used during the atomization process. It determines how molecules
    in a species bind together
    '''

    def sortMolecules(array, reverse):
        return sorted(array, key=lambda molecule: (len(molecule.components),
                                                   len([
                                                       x for x in molecule.components if x.activeState not in [0, '0']]),
                                                   len(str(molecule)), str(molecule)),
                      reverse=reverse)

    def getBiggestMolecule(array):
        sortedMolecule = sortMolecules(array, reverse=False)

        #sortedMolecule = sorted(sortedMolecule, key=lambda rule: len(rule.components))

        return sortedMolecule[-1]

    def getNamedMolecule(array, name):

        for molecule in sortMolecules(array, True):
            if molecule.name == name:
                return molecule
    speciesDict = {}
    # this array will contain all molecules that bind together
    pairedMolecules = []
    for x in sortMolecules(species.molecules, reverse=True):
        for y in x.components:
            if y.name not in speciesDict:
                speciesDict[y.name] = []
            speciesDict[y.name].append(x)
    # this array wil contain all molecules that dont bind to anything
    orphanedMolecules = [x for x in species.molecules]
    # seed the list of pairs from the seeds
    pairedMolecules = copy(bondSeeding)
    if bondSeeding:
        orphanedMolecules = [
            x for x in orphanedMolecules for y in bondSeeding if x not in y]

    # determine how molecules bind together
    redundantBonds = []

    for x in sortMolecules(species.molecules, reverse=True):
        for component in [y for y in x.components if y.name.lower()
                          in speciesDict.keys()]:
            if x.name.lower() in speciesDict:
                if(x in speciesDict[component.name.lower()]) and component.name in [y.name.lower() for y
                                                                                    in speciesDict[x.name.lower()]]:
                    for mol in speciesDict[x.name.lower()]:
                        if mol.name.lower() == component.name and x != mol and x in \
                                speciesDict[component.name]:
                            speciesDict[x.name.lower()].remove(mol)
                            speciesDict[component.name].remove(x)
                            if x not in orphanedMolecules and mol not in orphanedMolecules:
                                # FIXME: is it necessary to remove double bonds
                                # in complexes?
                                
                                lhs = set([])
                                rhs = set([])
                                repeatedFlag = False
                                for pair in pairedMolecules:
                                    

                                    if x in pair:
                                        lhs.add(pair[0])
                                        lhs.add(pair[1])
                                    elif mol in pair:
                                        rhs.add(pair[0])
                                        rhs.add(pair[1])
                                    # is this particular pair of molecules bound together?
                                    if x in pair and mol in pair:
                                        repeatedFlag = True
                                        break
                                # this pair already exists
                                if repeatedFlag:
                                    continue
                                redundantBonds.append([x, mol])
                                intersection = lhs.intersection(rhs)
                                redundantBonds[-1].extend(list(intersection))
                                if len(redundantBonds[-1]) < 3:
                                    redundantBonds.pop()
                                # continue
                            if [x, mol] not in bondSeeding and [mol, x] not in bondSeeding and [x, mol] not in bondExclusion and [mol, x] not in bondExclusion:
                                pairedMolecules.append([x, mol])
                            if x in orphanedMolecules:
                                orphanedMolecules.remove(x)
                            if mol in orphanedMolecules:
                                orphanedMolecules.remove(mol)

    if len(redundantBonds) > 0:
        for x in redundantBonds:
            if database:
                atoAux.addAssumptions(
                    'redundantBonds', tuple(sorted([y.name for y in x])), database.assumptions)
                atoAux.addAssumptions(
                    'redundantBondsMolecules', (tuple(sorted([y.name for y in x])), moleculeName), database.assumptions)
            logMess('WARNING:CTX001', 'Redundant bonds detected between molecules {0} in species {1}'.format(
                [y.name for y in x], moleculeName))
    totalComplex = [set(x) for x in pairedMolecules]
    isContinuousFlag = True

    # iterate over orphaned and find unidirectional interactions
    # e.g. if a molecule has a previous known interaction with the
    # same kind of molecule, even if it has no available components
    # e.g. k-mers`

    for element in speciesDict:
        for individualMolecule in speciesDict[element]:
            if individualMolecule in orphanedMolecules:
                candidatePartner = [x for x in species.molecules if x.name.lower(
                ) == element and x != individualMolecule]
                if len(candidatePartner) == 1:
                    pairedMolecules.append(
                        [candidatePartner[0], individualMolecule])
                    orphanedMolecules.remove(individualMolecule)
    # determine which pairs form a continuous chain

    while isContinuousFlag:
        isContinuousFlag = False
        for idx in range(0, len(totalComplex) - 1):
            for idx2 in range(idx + 1, len(totalComplex)):
                if len([x for x in totalComplex[idx] if x in totalComplex[idx2]]) > 0:
                    totalComplex[idx] = totalComplex[
                        idx].union(totalComplex[idx2])
                    totalComplex.pop(idx2)
                    isContinuousFlag = True
                    break
            if isContinuousFlag:
                break
    # now we process those molecules where we need to create a new component
    for element in orphanedMolecules:

        for mol1 in species.molecules:
            # when adding orphaned molecules make sure it's not already in
            # the list
            if mol1 == element and mol1 not in set().union(*totalComplex):
                totalComplex.append(set([mol1]))
    # now we process for those molecules we are not sure how do they bind
    while len(totalComplex) > 1:

        if len(totalComplex[0]) == 1 and len(totalComplex[1]) == 1:
            mol1 = list(totalComplex[0])[0]
            mol2 = list(totalComplex[1])[0]
        else:
            mol1, mol2 = solveComplexBinding(totalComplex, pathwaycommonsFlag, parser, database.prunnedDependencyGraph[moleculeName][0])
        pairedMolecules.append([mol1, mol2])
        totalComplex[0] = totalComplex[0].union(totalComplex[1])
        totalComplex.pop(1)
    # totalComplex.extend(orphanedMolecules)
    return pairedMolecules
Example #13
0
def solveComplexBinding(totalComplex, pathwaycommonsFlag, parser, compositionEntry):
    '''
    given two binding complexes it will attempt to find the ways in which they bind using different criteria

    '''
    def sortMolecules(array, reverse):
        return sorted(array, key=lambda molecule: (len(molecule.components),
                                                   len([
                                                       x for x in molecule.components if x.activeState not in [0, '0']]),
                                                   len(str(molecule)), str(molecule)), reverse=reverse)

    def getBiggestMolecule(array):
        sortedMolecule = sortMolecules(array, reverse=False)

        #sortedMolecule = sorted(sortedMolecule, key=lambda rule: len(rule.components))

        return sortedMolecule[-1]

    def getNamedMolecule(array, name):

        for molecule in sortMolecules(array, True):
            if molecule.name == name:
                return molecule
            elif molecule.trueName == name:
                return molecule

    names1 = [str(x.trueName) for x in totalComplex[0] ]
    names2 = [str(x.trueName) for x in totalComplex[1] ]
    bioGridDict = {}
    # find all pairs of molecules
    comb = set([tuple(sorted([x, y])) for x in names1 for y in names2])
    comb2 = set([tuple(sorted([x,y])) for x in compositionEntry for y in compositionEntry])

    dbPair = set([])
    combTemp = set()

    # search pathway commons for binding candidates
    if pathwaycommonsFlag:
        dbPair = isInComplexWith(comb, parser)
    else:
        for element in comb:
            if element[0].upper() in bioGridDict and element[1] in bioGridDict[element[0].upper()] or \
                    element[1].upper() in bioGridDict and element[0] in bioGridDict[element[1].upper()]:
                #logMess('INFO:ATO001', 'Biogrid info: {0}:{1}'.format(element[0], element[1]))
                dbPair.add((element[0], element[1]))
        # elif pathwaycommonsFlag:
        #    if pwcm.isInComplexWith(element[0], element[1]):
        #        dbPair.add((element[0], element[1]))
    dbPair = list(dbPair)

    if dbPair != []:
        mol1 = mol2 = None
        # select the best candidate if there's many ways to bind (in general
        # one that doesn't overlap with an already exising pair)
        finalDBpair = []
        if len(dbPair) > 1:

            for element in dbPair:
                mset1 = Counter(element)
                mset2 = Counter(names1)
                mset3 = Counter(names2)
                intersection1 = mset1 & mset2
                intersection2 = mset1 & mset3
                intersection1 = list(intersection1.elements())
                intersection2 = list(intersection2.elements())
                if len(intersection1) < 2 and len(intersection2) < 2:
                    finalDBpair.append(element)
        if len(finalDBpair) > 0:
            dbPair = finalDBpair

        if len(dbPair) > 1:

            # @FIXME: getNamedMolecule should never receive parameters that cause it to return null, but somehow that's what is happening
            # when you receive a malformed user definition file. The error
            # should be caught way before we reach this point
            tmpComplexSubset1 = [getNamedMolecule(totalComplex[0], element[0]) 
                                 for element in dbPair if getNamedMolecule(totalComplex[0], element[0]) is not None]
            if not tmpComplexSubset1:
                tmpComplexSubset1 = [getNamedMolecule(totalComplex[0], element[
                                                      1]) for element in dbPair if getNamedMolecule(totalComplex[0], element[1]) is not None]
                tmpComplexSubset2 = [getNamedMolecule(totalComplex[1], element[
                                                      0]) for element in dbPair if getNamedMolecule(totalComplex[1], element[0]) is not None]
            else:
                tmpComplexSubset2 = [getNamedMolecule(totalComplex[1], element[
                                                      1]) for element in dbPair if getNamedMolecule(totalComplex[1], element[1]) is not None]

            mol1 = getBiggestMolecule(tmpComplexSubset1)
            mol2 = getBiggestMolecule(tmpComplexSubset2)
            #was ATO002
            logMess('WARNING:ATO111', "{0}-{1}:The two pairs can bind in these ways according to BioGrid/Pathwaycommons:{2}:Defaulting to:('{3}', '{4}')".format(names1, names2, dbPair,
                                                                                                                                                                   mol1.name, mol2.name))

        else:
            mol1 = getNamedMolecule(totalComplex[0], dbPair[0][0])
            if not mol1:
                mol1 = getNamedMolecule(totalComplex[1], dbPair[0][0])
                mol2 = getNamedMolecule(totalComplex[0], dbPair[0][1])

            else:
                mol2 = getNamedMolecule(totalComplex[1], dbPair[0][1])
                if not mol2:
                    mol1 = getNamedMolecule(totalComplex[1], dbPair[0][0])
                    mol2 = getNamedMolecule(totalComplex[0], dbPair[0][1])

            logMess('INFO:ATO001', 'Binding information found in BioGrid/Pathwaycommons for for {0}-{1}'.format(mol1.name, mol2.name))

    else:

        #mol1 = getBiggestMolecule(totalComplex[0])
        #mol2 = getBiggestMolecule(totalComplex[1])
        '''
        if pathwaycommonsFlag:
            logMess('ERROR:ATO201', "We don't know how {0} and {1} bind together and there's no relevant BioGrid/Pathway commons information. Not atomizing".format(
                [x.name for x in totalComplex[0]], [x.name for x in totalComplex[1]]))
            # addAssumptions('unknownBond',(mol1.name,mol2.name))
        else:

            logMess('ERROR:ATO202', "We don't know how {0} and {1} bind together. Not atomizing".format(
                [x.name for x in totalComplex[0]], [x.name for x in totalComplex[1]]))
            # addAssumptions('unknownBond',(mol1.name,mol2.name))
        '''
        raise BindingException(
            '{0}-{1}'.format(sorted([x.name for x in totalComplex[0]]), sorted([x.name for x in totalComplex[1]])), comb)

    return mol1, mol2
def analyzeHelper(document, reactionDefinitions, useID, outputFile, speciesEquivalence, atomize, translator, database, bioGrid=False):
    '''
    taking the atomized dictionary and a series of data structure, this method
    does the actual string output.
    '''

    useArtificialRules = False
    parser = SBML2BNGL(document.getModel(), useID)
    parser.setConversion(database.isConversion)
    #database = structures.Databases()
    #database.assumptions = defaultdict(set)
    #translator,log,rdf = m2c.transformMolecules(parser,database,reactionDefinitions,speciesEquivalence)
        
    #try:
    #bioGridDict = {}
    #if biogrid:
    #    bioGridDict = biogrid()
    #if atomize:
    #    translator = mc.transformMolecules(parser,database,reactionDefinitions,speciesEquivalence,bioGridDict)
    #else:
    #    translator={}
    
    #except:
    #    print 'failure'
    #    return None,None,None,None
    
    #translator = {}
    param,zparam = parser.getParameters()
    rawSpecies = {}
    for species in parser.model.getListOfSpecies():
            rawtemp = parser.getRawSpecies(species,[x.split(' ')[0] for x in param])
            rawSpecies[rawtemp['identifier']] = rawtemp
    parser.reset()

    molecules, initialConditions, observables, speciesDict,\
        observablesDict, annotationInfo = parser.getSpecies(translator, [x.split(' ')[0] for x in param])

    # finally, adjust parameters and initial concentrations according to whatever  initialassignments say
    param, zparam, initialConditions = parser.getInitialAssignments(translator, param, zparam, molecules, initialConditions)

    # FIXME: this method is a mess, improve handling of assignmentrules since we can actually handle those
    aParameters, aRules, nonzparam, artificialRules, removeParams, artificialObservables = parser.getAssignmentRules(zparam, param, rawSpecies, 
                                                                                                                     observablesDict, translator)

    compartments = parser.getCompartments()
    functions = []
    assigmentRuleDefinedParameters = []

    reactionParameters, rules, rateFunctions = parser.getReactions(translator, len(compartments) > 1,
                                                                   atomize=atomize, parameterFunctions=artificialObservables, database=database)

    functions.extend(rateFunctions)

    for element in nonzparam:
        param.append('{0} 0'.format(element))
    param = [x for x in param if x not in removeParams]


    tags = '@{0}'.format(compartments[0].split(' ')[0]) if len(compartments) == 1 else '@cell'
    molecules.extend([x.split(' ')[0] for x in removeParams])

    if len(molecules) == 0:
        compartments = []
    observables.extend('Species {0} {0}'.format(x.split(' ')[0]) for x in removeParams)
    for x in removeParams:
        initialConditions.append(x.split(' ')[0] + tags + ' ' + ' '.join(x.split(' ')[1:]))

    ## Comment out those parameters that are defined with assignment rules
    ## TODO: I think this is correct, but it may need to be checked
    tmpParams = []

    for idx, parameter in enumerate(param):
        for key in artificialObservables:
            
            if re.search('^{0}\s'.format(key),parameter)!= None:
                assigmentRuleDefinedParameters.append(idx)
    tmpParams.extend(artificialObservables)
    tmpParams.extend(removeParams)
    tmpParams = set(tmpParams)
    correctRulesWithParenthesis(rules,tmpParams)

    for element in assigmentRuleDefinedParameters:
        param[element] = '#' + param[element]
    
    deleteMolecules = []
    deleteMoleculesFlag = True 

    for key in artificialObservables:
        flag = -1
        for idx,observable in enumerate(observables):
            if 'Species {0} {0}()'.format(key) in observable:
                flag = idx
        if flag != -1:
            observables.pop(flag)
        functions.append(artificialObservables[key])
        flag = -1
        
        if '{0}()'.format(key) in molecules:
            flag = molecules.index('{0}()'.format(key))
        
        if flag != -1:
            if deleteMoleculesFlag:
                deleteMolecules.append(flag)
            else:
                deleteMolecules.append(key)
            #result =validateReactionUsage(molecules[flag],rules)
            #if result != None:
            #    logMess('ERROR','Pseudo observable {0} in reaction {1}'.format(molecules[flag],result))
            #molecules.pop(flag)
            
        flag = -1
        for idx,specie in enumerate(initialConditions):
            if ':{0}('.format(key) in specie:
                flag = idx
        if flag != -1:
            initialConditions[flag] = '#' + initialConditions[flag]

    for flag in sorted(deleteMolecules,reverse=True):
        
        if deleteMoleculesFlag:
            logMess('WARNING:SIM101','{0} reported as function, but usage is ambiguous'.format(molecules[flag]) )
            result = validateReactionUsage(molecules[flag], rules)
            if result is not None:
                logMess('ERROR:Simulation','Pseudo observable {0} in reaction {1}'.format(molecules[flag],result))

            #since we are considering it an observable delete it from the molecule and
            #initial conditions list
            #s = molecules.pop(flag)
            #initialConditions = [x for x in initialConditions if '$' + s not in x]
        else:
            logMess('WARNING:SIM101','{0} reported as species, but usage is ambiguous.'.format(flag) )
            artificialObservables.pop(flag)
            
    sbmlfunctions = parser.getSBMLFunctions()

    functions.extend(aRules)
    #print functions

    processFunctions(functions,sbmlfunctions,artificialObservables,rateFunctions)
    for interation in range(0,3):
        for sbml2 in sbmlfunctions:
            for sbml in sbmlfunctions:
                if sbml == sbml2:
                    continue
                if sbml in sbmlfunctions[sbml2]:
                    sbmlfunctions[sbml2] = writer.extendFunction(sbmlfunctions[sbml2],sbml,sbmlfunctions[sbml])

    functions = reorderFunctions(functions)


    functions = changeNames(functions, aParameters)
    # change reference for observables with compartment name
    functions = changeNames(functions, observablesDict)
#     print [x for x in functions if 'functionRate60' in x]

    functions = unrollFunctions(functions)
    rules = changeRates(rules, aParameters)
    if len(compartments) > 1 and 'cell 3 1.0' not in compartments:
        compartments.append('cell 3 1.0')

    #sbml always has the 'cell' default compartment, even when it
    #doesn't declare it
    elif len(compartments) == 0 and len(molecules) != 0:
        compartments.append('cell 3 1.0')
    
    
    if len(artificialRules) + len(rules) == 0:
        logMess('ERROR:SIM203','The file contains no reactions')
    if useArtificialRules or len(rules) == 0:
        rules =['#{0}'.format(x) for x in rules]
        evaluate =  evaluation(len(observables),translator)

        artificialRules.extend(rules)
        rules = artificialRules
        


    else:
        artificialRules =['#{0}'.format(x) for x in artificialRules]
        evaluate =  evaluation(len(observables),translator)

        rules.extend(artificialRules)
    commentDictionary = {}
    
    if atomize:
        commentDictionary['notes'] = "'This is an atomized translation of an SBML model created on {0}.".format(time.strftime("%d/%m/%Y"))
    else:
        commentDictionary['notes'] = "'This is a plain translation of an SBML model created on {0}.".format(time.strftime("%d/%m/%Y"))
    commentDictionary['notes'] += " The original model has {0} molecules and {1} reactions. The translated model has {2} molecules and {3} rules'".format(parser.model.getNumSpecies(),parser.model.getNumReactions(),len(molecules),len(set(rules)))
    meta = parser.getMetaInformation(commentDictionary)

    

    finalString = writer.finalText(meta, param + reactionParameters, molecules, initialConditions, 
                                   list(OrderedDict.fromkeys(observables)), list(OrderedDict.fromkeys(rules)), functions, compartments,
                                   annotationInfo, outputFile)
    
    logMess('INFO:SUM001','File contains {0} molecules out of {1} original SBML species'.format(len(molecules), len(observables)))

    # rate of each classified rule
    evaluate2 = 0 if len(observables) == 0 else len(molecules)*1.0/len(observables)

    # add unit information to annotations

    annotationInfo['units'] = parser.getUnitDefinitions()
    return AnalysisResults(len(rules), len(observables), evaluate, evaluate2, len(compartments),
                           parser.getSpeciesAnnotation(), finalString, speciesDict, None, annotationInfo)

    '''
Example #15
0
def bnglFunction(rule,
                 functionTitle,
                 reactants,
                 compartments=[],
                 parameterDict={},
                 reactionDict={}):
    def powParse(match):
        if match.group(1) == 'root':
            exponent = '(1/%s)' % match.group(3)
        else:
            exponent = match.group(3)
        if match.group(1) in ['root', 'pow']:
            operator = '^'
        return '({0}){1}({2})'.format(match.group(2), operator, exponent)

    def compParse(match):

        translator = {
            'gt': '>',
            'lt': '<',
            'and': '&&',
            'or': '||',
            'geq': '>=',
            'leq': '<=',
            'eq': '=='
        }
        exponent = match.group(3)
        operator = translator[match.group(1)]
        return '{0} {1} {2}'.format(match.group(2), operator, exponent)

    def ceilfloorParse(math):
        flag = False
        if math.group(1) == 'ceil':
            flag = True
        if flag:
            return 'min(rint({0}+0.5),rint({0} + 1))'.format(math.group(2))
        else:
            return 'min(rint({0}-0.5),rint({0}+0.5))'.format(math.group(2))

    def parameterRewrite(match):
        return match.group(1) + 'param_' + match.group(2) + match.group(3)

    def constructFromList(argList, optionList):
        parsedString = ''
        idx = 0
        translator = {
            'gt': '>',
            'lt': '<',
            'and': '&&',
            'or': '||',
            'geq': '>=',
            'leq': '<=',
            'eq': '=='
        }
        while idx < len(argList):
            if type(argList[idx]) is list:
                parsedString += '(' + constructFromList(
                    argList[idx], optionList) + ')'
            elif argList[idx] in optionList:
                if argList[idx] == 'ceil':
                    parsedString += 'min(rint(({0}) + 0.5),rint(({0}) + 1))'.format(
                        constructFromList(argList[idx + 1], optionList))
                    idx += 1
                elif argList[idx] == 'floor':
                    parsedString += 'min(rint(({0}) -0.5),rint(({0}) + 0.5))'.format(
                        constructFromList(argList[idx + 1], optionList))
                    idx += 1
                elif argList[idx] in ['pow']:
                    index = rindex(argList[idx + 1], ',')
                    parsedString += '((' + constructFromList(
                        argList[idx + 1][0:index], optionList) + ')'
                    parsedString += ' ^ ' + '(' + constructFromList(
                        argList[idx + 1][index + 1:], optionList) + '))'
                    idx += 1
                elif argList[idx] in ['sqr', 'sqrt']:
                    tag = '1/' if argList[idx] == 'sqrt' else ''
                    parsedString += '((' + constructFromList(
                        argList[idx + 1],
                        optionList) + ') ^ ({0}2))'.format(tag)
                    idx += 1
                elif argList[idx] == 'root':
                    index = rindex(argList[idx + 1], ',')
                    tmp = '1/(' + constructFromList(argList[idx + 1][0:index],
                                                    optionList) + '))'
                    parsedString += '((' + constructFromList(
                        argList[idx + 1][index + 1:],
                        optionList) + ') ^ ' + tmp
                    idx += 1
                elif argList[idx] == 'piecewise':
                    index1 = argList[idx + 1].index(',')
                    try:
                        index2 = argList[idx + 1][index1 +
                                                  1:].index(',') + index1 + 1
                        try:
                            index3 = argList[idx +
                                             1][index2 +
                                                1:].index(',') + index2 + 1
                        except ValueError:
                            index3 = -1
                    except ValueError:
                        parsedString += constructFromList(
                            [argList[idx + 1][index1 + 1:]], optionList)
                        index2 = -1
                    if index2 != -1:
                        condition = constructFromList(
                            [argList[idx + 1][index1 + 1:index2]], optionList)
                        result = constructFromList([argList[idx + 1][:index1]],
                                                   optionList)
                        if index3 == -1:
                            result2 = constructFromList(
                                [argList[idx + 1][index2 + 1:]], optionList)
                        else:
                            result2 = constructFromList(
                                ['piecewise', argList[idx + 1][index2 + 1:]],
                                optionList)
                        parsedString += 'if({0},{1},{2})'.format(
                            condition, result, result2)
                    idx += 1
                elif argList[idx] in ['and', 'or']:
                    symbolDict = {'and': ' && ', 'or': ' || '}
                    indexArray = [-1]
                    elementArray = []
                    for idx2, element in enumerate(argList[idx + 1]):
                        if element == ',':
                            indexArray.append(idx2)
                    indexArray.append(len(argList[idx + 1]))
                    tmpStr = argList[idx + 1]
                    for idx2, _ in enumerate(indexArray[0:-1]):
                        elementArray.append(
                            constructFromList(
                                tmpStr[indexArray[idx2] +
                                       1:indexArray[idx2 + 1]], optionList))
                    parsedString += symbolDict[argList[idx]].join(elementArray)
                    idx += 1
                elif argList[idx] == 'lambda':

                    tmp = '('
                    upperLimit = rindex(argList[idx + 1], ',')
                    parsedParams = []
                    for x in argList[idx + 1][0:upperLimit]:
                        if x == ',':
                            tmp += ', '
                        else:
                            tmp += 'param_' + x
                            parsedParams.append(x)

                    #tmp = ''.join([x for x in constructFromList(argList[idx+1][0:upperLimit])])
                    tmp2 = ') = ' + constructFromList(
                        argList[idx + 1][rindex(argList[idx + 1], ',') + 1:],
                        optionList)
                    for x in parsedParams:
                        while re.search(r'(\W|^)({0})(\W|$)'.format(x),
                                        tmp2) != None:
                            tmp2 = re.sub(r'(\W|^)({0})(\W|$)'.format(x),
                                          r'\1param_\2 \3', tmp2)
                    idx += 1
                    parsedString += tmp + tmp2
            else:
                parsedString += argList[idx]
            idx += 1
        return parsedString

    def changeToBNGL(functionList, rule, function):
        oldrule = ''
        #if the rule contains any mathematical function we need to reformat
        while any([
                re.search(r'(\W|^)({0})(\W|$)'.format(x), rule) != None
                for x in functionList
        ]) and (oldrule != rule):
            oldrule = rule
            for x in functionList:
                rule = re.sub('({0})\(([^,]+),([^)]+)\)'.format(x), function,
                              rule)
            if rule == oldrule:
                logMess('ERROR', 'Malformed pow or root function %s' % rule)
                print 'meep'
        return rule

    #rule = changeToBNGL(['pow','root'],rule,powParse)
    rule = changeToBNGL(['gt', 'lt', 'leq', 'geq', 'eq'], rule, compParse)
    #rule = changeToBNGL(['and','or'],rule,compParse)
    flag = True
    contentRule = pyparsing.Word(
        pyparsing.alphanums + '_'
    ) | ',' | '.' | '+' | '-' | '*' | '/' | '^' | '&' | '>' | '<' | '=' | '|'
    parens = pyparsing.nestedExpr('(', ')', content=contentRule)
    finalString = ''
    #remove ceil,floor

    if any([
            re.search(r'(\W|^)({0})(\W|$)'.format(x), rule) != None for x in
        ['ceil', 'floor', 'pow', 'sqrt', 'sqr', 'root', 'and', 'or']
    ]):
        argList = parens.parseString('(' + rule + ')').asList()
        rule = constructFromList(
            argList[0],
            ['floor', 'ceil', 'pow', 'sqrt', 'sqr', 'root', 'and', 'or'])

    while 'piecewise' in rule:
        argList = parens.parseString('(' + rule + ')').asList()
        rule = constructFromList(argList[0], ['piecewise'])
    #remove references to lambda functions
    if 'lambda(' in rule:
        lambdaList = parens.parseString('(' + rule + ')')
        functionBody = constructFromList(lambdaList[0].asList(), ['lambda'])
        flag = False
        rule = '{0}{1}'.format(functionTitle, functionBody)

    tmp = rule
    #delete the compartment from the rate function since cBNGL already does it
    for compartment in compartments:
        tmp = re.sub('^{0}\s*[*]'.format(compartment[0]), '', tmp)
        tmp = re.sub('([*]\s*{0})$'.format(compartment[0]), '', tmp)
        if compartment[0] in tmp:
            tmp = re.sub(r'(\W|^)({0})(\W|$)'.format(compartment[0]),
                         r'\1 {0} \3'.format(str(compartment[1])), tmp)
            #tmp = re.sub(r'(\W)({0})(\W)'.format(compartment[0]),r'\1%s\3' % str(compartment[1]),tmp)
            logMess(
                'INFO',
                'Exchanging reference to compartment %s for its dimensions' %
                compartment[0])

    #change references to time for time()
    #tmp =re.sub(r'(\W|^)(time)(\W|$)',r'\1time()\3',tmp)
    #tmp =re.sub(r'(\W|^)(Time)(\W|$)',r'\1time()\3',tmp)
    while re.search(r'(\W|^)inf(\W|$)', tmp) != None:
        tmp = re.sub(r'(\W|^)(inf)(\W|$)', r'\1 1e20 \3', tmp)
    #BNGL has ^ for power.
    if flag:
        finalString = '%s = %s' % (functionTitle, tmp)
    else:
        finalString = tmp
    #change references to local parameters
    for parameter in parameterDict:
        finalString = re.sub(r'(\W|^)({0})(\W|$)'.format(parameter),
                             r'\g<1>{0}\g<3>'.format(parameterDict[parameter]),
                             finalString)
    #change references to reaction Id's to their netflux equivalent
    for reaction in reactionDict:
        if reaction in finalString:
            finalString = re.sub(
                r'(\W|^)({0})(\W|$)'.format(reaction),
                r'\g<1>{0}\g<3>'.format(reactionDict[reaction]), finalString)

    #combinations '+ -' break ibonetgen
    finalString = re.sub(r'(\W|^)([-])(\s)+', r'\1-', finalString)
    #changing reference of 't' to time()
    #finalString = re.sub(r'(\W|^)(t)(\W|$)',r'\1time()\3',finalString)
    #pi
    finalString = re.sub(r'(\W|^)(pi)(\W|$)', r'\g<1>3.1415926535\g<3>',
                         finalString)
    #print reactants,finalString
    #log for log 10
    finalString = re.sub(r'(\W|^)log\(', r'\1 ln(', finalString)
    #reserved keyword: e
    finalString = re.sub(r'(\W|^)(e)(\W|$)', r'\g<1>are\g<3>', finalString)
    #changing ceil
    #avoiding variables whose name starts with a number

    #removing mass-action elements

    tmp = finalString

    #print finalString,reactants
    #for reactant in reactants:
    #    finalString = re.sub(r'(\W|^)({0}\s+\*)'.format(reactant[0]),r'\1',finalString)
    #    finalString = re.sub(r'(\W|^)(\*\s+{0}(\s|$))'.format(reactant[0]),r'\1',finalString)
    #print finalString

    #if finalString != tmp:
    #    logMess('WARNING','Removed mass action elements from )
    return finalString
Example #16
0
def bnglFunction(rule,functionTitle,reactants,compartments=[],parameterDict={},reactionDict={}):
    def powParse(match):
        if match.group(1) == 'root':
            exponent = '(1/%s)' % match.group(3)
        else:
            exponent = match.group(3)
        if match.group(1) in ['root','pow']:
            operator = '^'
        return '({0}){1}({2})'.format(match.group(2),operator,exponent)
    def compParse(match):

        translator = {'gt':'>','lt':'<','and':'&&','or':'||','geq':'>=','leq':'<=','eq':'=='}
        exponent = match.group(3)
        operator = translator[match.group(1)]
        return '{0} {1} {2}'.format(match.group(2),operator,exponent)
      
    def ceilfloorParse(math):
        flag = False
        if math.group(1) == 'ceil':
             flag = True
        if flag:
            return 'min(rint({0}+0.5),rint({0} + 1))'.format(math.group(2))
        else:
            return 'min(rint({0}-0.5),rint({0}+0.5))'.format(math.group(2))
    
    
    def parameterRewrite(match):
        return match.group(1) + 'param_' + match.group(2) + match.group(3)
    
    def constructFromList(argList,optionList):
        parsedString = ''
        idx = 0
        translator = {'gt':'>','lt':'<','and':'&&','or':'||','geq':'>=','leq':'<=','eq':'=='}
        while idx < len(argList):
            if type(argList[idx]) is list:
                parsedString += '(' + constructFromList(argList[idx],optionList) + ')'
            elif argList[idx] in optionList:
                if argList[idx] == 'ceil':
                    parsedString += 'min(rint(({0}) + 0.5),rint(({0}) + 1))'.format(constructFromList(argList[idx+1],optionList))
                    idx += 1
                elif argList[idx] == 'floor':
                    parsedString += 'min(rint(({0}) -0.5),rint(({0}) + 0.5))'.format(constructFromList(argList[idx+1],optionList))
                    idx += 1
                elif argList[idx] in ['pow']:
                    index = rindex(argList[idx+1],',')
                    parsedString += '(('+ constructFromList(argList[idx+1][0:index],optionList) + ')' 
                    parsedString += ' ^ '  + '(' + constructFromList(argList[idx+1][index+1:] ,optionList) + '))'
                    idx += 1
                elif argList[idx] in ['sqr','sqrt']:
                    tag = '1/' if argList[idx] == 'sqrt' else ''
                    parsedString += '((' + constructFromList(argList[idx+1],optionList) + ') ^ ({0}2))'.format(tag)
                    idx += 1
                elif argList[idx] == 'root':
                    index = rindex(argList[idx+1],',')
                    tmp =  '1/('+ constructFromList(argList[idx+1][0:index],optionList) + '))' 
                    parsedString += '((' + constructFromList(argList[idx+1][index+1:] ,optionList) + ') ^ ' + tmp
                    idx += 1
                elif argList[idx] == 'piecewise':
                    index1 = argList[idx+1].index(',')
                    try:
                        index2 = argList[idx+1][index1+1:].index(',') + index1+1
                        try:
                            index3 = argList[idx+1][index2+1:].index(',') + index2+1
                        except ValueError:
                            index3 = -1
                    except ValueError:
                        parsedString += constructFromList([argList[idx+1][index1+1:]],optionList)
                        index2 = -1
                    if index2 != -1:
                        condition = constructFromList([argList[idx+1][index1+1:index2]],optionList)
                        result = constructFromList([argList[idx+1][:index1]],optionList)
                        if index3 == -1:
                            result2 = constructFromList([argList[idx+1][index2+1:]],optionList)
                        else:
                            result2 = constructFromList(['piecewise', argList[idx+1][index2+1:]],optionList)
                        parsedString += 'if({0},{1},{2})'.format(condition,result,result2)
                    idx+=1
                elif argList[idx] in ['and', 'or']:
                    symbolDict = {'and':' && ','or':' || '}
                    indexArray = [-1]
                    elementArray = []
                    for idx2,element in enumerate(argList[idx+1]):
                        if element ==',':
                            indexArray.append(idx2)
                    indexArray.append(len(argList[idx+1]))
                    tmpStr = argList[idx+1]
                    for idx2,_ in enumerate(indexArray[0:-1]):
                        elementArray.append(constructFromList(tmpStr[indexArray[idx2]+1:indexArray[idx2+1]],optionList))
                    parsedString += symbolDict[argList[idx]].join(elementArray)
                    idx+=1
                elif argList[idx] == 'lambda':
                    
                    tmp = '('
                    upperLimit = rindex(argList[idx+1],',')
                    parsedParams = []
                    for x in argList[idx+1][0:upperLimit]:
                        if x == ',':
                            tmp += ', '
                        else:
                            tmp += 'param_' + x
                            parsedParams.append(x)
                            
                    #tmp = ''.join([x for x in constructFromList(argList[idx+1][0:upperLimit])]) 
                    tmp2 = ') = ' + constructFromList(argList[idx+1][rindex(argList[idx+1],',')+1:],optionList)
                    for x in parsedParams:
                        while re.search(r'(\W|^)({0})(\W|$)'.format(x),tmp2) != None:
                            tmp2 = re.sub(r'(\W|^)({0})(\W|$)'.format(x),r'\1param_\2 \3',tmp2)
                    idx+= 1
                    parsedString += tmp + tmp2
            else:
                parsedString += argList[idx]
            idx += 1
        return parsedString
            
        
        
    def changeToBNGL(functionList,rule,function):
        oldrule = ''
        #if the rule contains any mathematical function we need to reformat
        while any([re.search(r'(\W|^)({0})(\W|$)'.format(x),rule) != None for x in functionList]) and (oldrule != rule):
            oldrule = rule
            for x in functionList:
                rule  = re.sub('({0})\(([^,]+),([^)]+)\)'.format(x),function,rule)
            if rule == oldrule:
                logMess('ERROR','Malformed pow or root function %s' % rule)
                print 'meep'
        return rule

    #rule = changeToBNGL(['pow','root'],rule,powParse)
    rule = changeToBNGL(['gt','lt','leq','geq','eq'],rule,compParse)
    #rule = changeToBNGL(['and','or'],rule,compParse)
    flag = True
    contentRule = pyparsing.Word(pyparsing.alphanums + '_') | ',' | '.' | '+' | '-' | '*' | '/' | '^' | '&' | '>' | '<' | '=' | '|' 
    parens     = pyparsing.nestedExpr( '(', ')', content=contentRule)
    finalString = ''
    #remove ceil,floor 
    
    if any([re.search(r'(\W|^)({0})(\W|$)'.format(x),rule) != None for x in ['ceil','floor','pow','sqrt','sqr','root','and','or']]):
        argList = parens.parseString('('+ rule + ')').asList()
        rule = constructFromList(argList[0],['floor','ceil','pow','sqrt','sqr','root','and','or'])
    
    
    while 'piecewise' in rule:
        argList = parens.parseString('('+ rule + ')').asList()
        rule = constructFromList(argList[0],['piecewise'])
    #remove references to lambda functions
    if 'lambda(' in rule:
        lambdaList =  parens.parseString('(' + rule + ')')
        functionBody =  constructFromList(lambdaList[0].asList(),['lambda'])
        flag = False
        rule =  '{0}{1}'.format(functionTitle,functionBody)
    
    tmp = rule
    #delete the compartment from the rate function since cBNGL already does it
    for compartment in compartments:
        tmp = re.sub('^{0}\s*[*]'.format(compartment[0]),'',tmp)
        tmp = re.sub('([*]\s*{0})$'.format(compartment[0]),'',tmp)
        if compartment[0] in tmp:
            tmp =re.sub(r'(\W|^)({0})(\W|$)'.format(compartment[0]),r'\1 {0} \3'.format(str(compartment[1])),tmp)
            #tmp = re.sub(r'(\W)({0})(\W)'.format(compartment[0]),r'\1%s\3' % str(compartment[1]),tmp)
            logMess('INFO','Exchanging reference to compartment %s for its dimensions' % compartment[0])
    
    #change references to time for time()    
    #tmp =re.sub(r'(\W|^)(time)(\W|$)',r'\1time()\3',tmp)
    #tmp =re.sub(r'(\W|^)(Time)(\W|$)',r'\1time()\3',tmp)
    while re.search(r'(\W|^)inf(\W|$)',tmp) != None:
        tmp =re.sub(r'(\W|^)(inf)(\W|$)',r'\1 1e20 \3',tmp)
    #BNGL has ^ for power. 
    if flag:
        finalString = '%s = %s' % (functionTitle,tmp)
    else:
        finalString = tmp
    #change references to local parameters
    for parameter in parameterDict:
        finalString = re.sub(r'(\W|^)({0})(\W|$)'.format(parameter),r'\g<1>{0}\g<3>'.format(parameterDict[parameter]),finalString)
    #change references to reaction Id's to their netflux equivalent
    for reaction in reactionDict:
        if reaction in finalString:
            finalString = re.sub(r'(\W|^)({0})(\W|$)'.format(reaction),r'\g<1>{0}\g<3>'.format(reactionDict[reaction]),finalString)
    
    #combinations '+ -' break ibonetgen
    finalString = re.sub(r'(\W|^)([-])(\s)+',r'\1-',finalString)
    #changing reference of 't' to time()
    #finalString = re.sub(r'(\W|^)(t)(\W|$)',r'\1time()\3',finalString)
    #pi
    finalString = re.sub(r'(\W|^)(pi)(\W|$)',r'\g<1>3.1415926535\g<3>',finalString)
    #print reactants,finalString
    #log for log 10
    finalString = re.sub(r'(\W|^)log\(',r'\1 ln(',finalString)
    #reserved keyword: e
    finalString = re.sub(r'(\W|^)(e)(\W|$)',r'\g<1>are\g<3>',finalString)
    #changing ceil
    #avoiding variables whose name starts with a number
    
    #removing mass-action elements
    
    tmp = finalString
    
    #print finalString,reactants
    #for reactant in reactants:
    #    finalString = re.sub(r'(\W|^)({0}\s+\*)'.format(reactant[0]),r'\1',finalString)
    #    finalString = re.sub(r'(\W|^)(\*\s+{0}(\s|$))'.format(reactant[0]),r'\1',finalString)
    #print finalString
    
    #if finalString != tmp:
    #    logMess('WARNING','Removed mass action elements from )
    return finalString