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))
def createEmptySpecies(name): species = st.Species() molecule = st.Molecule(name) species.addMolecule(molecule) return species
def createBindingRBM(element, translator, dependencyGraph, bioGridFlag, pathwaycommonsFlag, parser, database): species = st.Species() # go over the sct and reuse existing stuff for molecule in dependencyGraph[element[0]][0]: if molecule in translator: tmpSpecies = translator[molecule] if molecule != getTrueTag(dependencyGraph, molecule): original = translator[getTrueTag(dependencyGraph, molecule)] updateSpecies(tmpSpecies, original.molecules[0]) if tmpSpecies.molecules[0].name in database.constructedSpecies: tmpSpecies.molecules[0].trueName = molecule else: tmpSpecies.molecules[0].trueName = tmpSpecies.molecules[0].name species.addMolecule(deepcopy(tmpSpecies.molecules[0])) else: mol = st.Molecule(molecule) mol.trueName = molecule #dependencyGraph[molecule] = deepcopy(mol) species.addMolecule(mol) dependencyGraphCounter = Counter(dependencyGraph[element[0]][0]) # XXX: this wont work for species with more than one molecule with the # same name changeFlag = False partialBonds = defaultdict(list) for partialUserEntry in database.partialUserLabelDictionary: partialCounter = Counter(partialUserEntry) if all([partialCounter[x] <= dependencyGraphCounter[x] for x in partialCounter]): changeFlag = True for molecule in database.partialUserLabelDictionary[partialUserEntry].molecules: for molecule2 in species.molecules: if molecule.name == molecule2.name: for component in molecule.components: for bond in component.bonds: if molecule2.name not in [x.name for x in partialBonds[bond]]: partialBonds[bond].append(molecule2) ''' for component in molecule.components: component2 = [x for x in molecule2.components if x.name == component.name] # component already exists in species template if component2: if component.bonds: component2[0].bonds = component.bonds else: molecule2.addComponent(deepcopy(component)) ''' bondSeeding = [partialBonds[x] for x in partialBonds if x > 0] bondExclusion = [partialBonds[x] for x in partialBonds if x < 0] # how do things bind together? moleculePairsList = getComplexationComponents2( element[0], species, bioGridFlag, pathwaycommonsFlag, parser, bondSeeding, bondExclusion, database) #moleculeCount = Counter([y for x in moleculePairsList for y in x]) # print moleculeCount #moleculePairsList = [sorted(x) for x in moleculePairsList] #moleculePairsList.sort(key=lambda x: [-moleculeCount[x[0]],(str(x[0]), x[0],str(x[1]),x[1])]) # TODO: update basic molecules with new components # translator[molecule[0].name].molecules[0].components.append(deepcopy(newComponent1)) # translator[molecule[1].name].molecules[0].components.append(deepcopy(newComponent2)) moleculeCounter = defaultdict(list) for molecule in moleculePairsList: flag = False # create an index on m0 and m1 depending on their name and repeats in # the species if molecule[0] not in moleculeCounter[molecule[0].name]: moleculeCounter[molecule[0].name].append(molecule[0]) if molecule[1] not in moleculeCounter[molecule[1].name]: moleculeCounter[molecule[1].name].append(molecule[1]) m0index = moleculeCounter[molecule[0].name].index(molecule[0]) m1index = moleculeCounter[molecule[1].name].index(molecule[1]) bondIdx = getBondNumber('{0}{1}'.format( molecule[0].name, m0index), '{0}{1}'.format(molecule[1].name, m1index)) # add bonds where binding components already exist and they are not # occupied for component in molecule[0].components: if component.name == molecule[1].name.lower() and \ len(component.bonds) == 0: component.bonds.append(bondIdx) flag = True break if not flag: # create components if they dont exist already. # Add a bond afterwards newComponent1 = st.Component(molecule[1].name.lower()) molecule[0].components.append(newComponent1) if newComponent1.name not in [x.name for x in translator[molecule[0].name].molecules[0]. components]: translator[molecule[0].name].molecules[ 0].components.append(deepcopy(newComponent1)) molecule[0].components[-1].bonds.append(bondIdx) flag = False # same thing for the other member of the bond for component in molecule[1].components: if component.name == molecule[0].name.lower() and len(component.bonds) == 0: component.bonds.append(bondIdx) flag = True break if not flag: newComponent2 = st.Component(molecule[0].name.lower()) molecule[1].components.append(newComponent2) if molecule[0].name != molecule[1].name: if newComponent2.name not in [x.name for x in translator[molecule[1].name].molecules[0]. components]: translator[molecule[1].name].molecules[ 0].components.append(deepcopy(newComponent2)) molecule[1].components[-1].bonds.append(bondIdx) # update the translator translator[element[0]] = species