Source code for CoreClasses

# class definitions for CoreEvolve
from collections import deque, Counter
from copy import copy,deepcopy
import random
        
## Reaction Class        
[docs]class Reaction(object): '''Reaction object containing an ID and reaction members (IDs not strings) as well as reaction coefficients and rate constants reactants, and products lists should contain integers which are the IDs of the reactant molecules and the product molecules reactant_coeff and product_coeff contain ints which are the reaction coefficients. The indices must match the corresponding ID lists Attributes: - ID: unique int which indentifies the reaction - reactants: a list of molecule IDs which stores the reactants - reactant_coeff: a list of integers which contains the reactant coefficients (if reactant_coeff is not provided all reactants are assumed to have coefficients of 1) - products: a list of molecule IDs which stores the products - product_coeff: a list of integers which contains the product_coeff coefficients - constant: a floating point number, the reaction rate constant - catalysts: a list of molecule IDs which specify which molecules catalyze this reaction - catalyzed_constants: a list of floating point numbers giving the catalytic effect of each molecule ''' def __init__(self, ID, reactants=list(), reactant_coeff = list(), products=list(), product_coeff = list(), constant=1.0, catalysts=list(), catalyzed_constants=list(), prop = str()): #initialise reaction # if reactant_coeff == None: # reactant_coeff = [1]*len(reactants) # if product_coeff == None: # product_coeff = [1]*len(products) # Sort of all molecule lists react_tuples = zip(reactants, reactant_coeff) prod_tuples = zip(products, product_coeff) react_tuples = sorted(react_tuples, key=lambda x: x[0]) prod_tuples = sorted(prod_tuples, key = lambda x: x[0]) reactants, reactant_coeff = zip(*react_tuples) products, product_coeff = zip(*prod_tuples) reactants = list(reactants) products = list(products) reactant_coeff = list(reactant_coeff) product_coeff = list(product_coeff) # If the reaction is catalyzed, do the same for the catalysts if len(catalysts) != 0: cat_tuples = zip(catalysts, catalyzed_constants) cat_tuples = sorted(cat_tuples, key = lambda x: x[0]) catalysts, catalyzed_constants = zip(*cat_tuples) catalysts = list(catalysts) catalyzed_constants = list(catalyzed_constants) # Find duplicates if len(reactants) > 1: i =0 while (i < len(reactants)-1): if reactants[i] == reactants[i+1]: reactant_coeff[i] += reactant_coeff[i+1] del reactant_coeff[i+1] del reactants[i+1] else: i += 1 if len(reactants) == 1: break if len(products) > 1: i =0 while (i< len(products)-1): if products[i] == products[i+1]: product_coeff[i] += product_coeff[i+1] del product_coeff[i+1] del products[i+1] else: i += 1 if len(products) == 1: break if len(catalysts) > 1: i =0 while (i< len(catalysts)-1): if catalysts[i] == catalysts[i+1]: del catalyzed_constants[i+1] del catalysts[i+1] else: i += 1 if len(catalysts) == 1: break self.ID = ID self.reactants = reactants # List of reactant IDs self.reactant_coeff = reactant_coeff # List of reactant stochiometric coefficients self.products = products # List of Product IDs self.product_coeff = product_coeff # List of product stochiometric coefficients self.catalysts = catalysts # List of catalysts for the reaction self.constant = constant self.catalyzed_constants = catalyzed_constants self.prop = prop #Propensity Str to indicate function def __str__(self): #returns unique reaction string (without catalysts) rep = '' # Add reactants for i in range(len(self.reactants)): rep += str(self.reactant_coeff[i]) + '[' + str(self.reactants[i]) + '] + ' rep = rep[:-2] rep += '-- ' + str(self.constant) +' -> ' # Add products for i in range(len(self.products)): rep += str(self.product_coeff[i]) + '[' + str(self.products[i]) + '] + ' rep = rep[:-2] return rep
## Reaction System Class
[docs]class CRS(object): """ A chemical reaction system comprising a list of molecules, and allowed reactions molecule_list contains strings, indexing molecules by their ID molecule_dict maps molecule strings to IDs (indices) reactions contains a list of reaction objects Attributes: - molecule_list: a list of molecule strings, indexed by their ID (which is an int) - molecule_dict: a dictionary that maps molecule strings to IDs - reactions: a list of all reaction objects allowed in the Reaction System, indexed by their ID """ #molecules and reactions are implemented as sets. def __init__(self, molecule_list=list(), molecule_dict = dict(), reactions=list()): self.molecule_list = molecule_list #list of molecules indexed by ID| molecule_list[ID] = m self.molecule_dict = molecule_dict # Maps molecule strings to IDs| {'string': ID} self.reactions = reactions #List of reactions to iterate over # def __str__(self): # rep = "Reaction set containing:\n" # for r in self.reaction_dict: # rep += self.reaction_dict[r].__str__()+"\n" # return rep
[docs] def savetxt(self, file_name): """Writes CRS to textfile""" #open text file and write header text_file = open(file_name, "w") text_file.write("<meta-data>\n") text_file.write("nrMolecules = "+str(len(self.molecule_list))+"\n") text_file.write("nrReactions = "+str(len(self.reactions))+"\n\n<molecules>\n") #write molecule entries for ID,molecule in enumerate(self.molecule_list): #print ID, molecule text_file.write("["+str(ID)+"] "+str(molecule)+"\n") #write reactions text_file.write("\n<reactions>\n") for rxn in self.reactions: line = "["+str(rxn.ID)+"] " num_reactants = len(rxn.reactants) num_products = len(rxn.products) # Write Reactants for i in range(num_reactants): molecule = self.molecule_list[rxn.reactants[i]] line += str(rxn.reactant_coeff[i]) + '['+str(molecule) + '] + ' line = line[:-2] # Write Constant line += '-- ' + str(rxn.constant) + ' -> ' # Write Products for i in range(num_products): molecule = self.molecule_list[rxn.products[i]] line += str(rxn.product_coeff[i]) + '['+str(molecule) + '] + ' line = line[:-2] # Write Propensity line += ' ' + rxn.prop + ' ' # Write catalysts if rxn.catalysts != []: num_catalysts = len(rxn.catalysts) line += ' (' for i in range(num_catalysts): molecule = self.molecule_list[rxn.catalysts[i]] line += str(rxn.catalyzed_constants[i]) +'[' + str(molecule) +']' + ',' line = line[:-1] line += ')' line += '\n' text_file.write(line) text_file.close()
[docs] def readtxt(self, file_name): """Reads from text file. The current data is discarded.""" def read_m(s): #subfunction to read molecule entry s = s.replace('\n', '') s = s.split(' ') IDstr = s[0] IDstr = IDstr[:-1] IDstr = IDstr[1:] ID = int(IDstr) m = s[-1] return ID, m def read_r(s): #subfunction to read reaction entry # Initialize lists reactants = [] reactant_coeff = [] products = [] product_coeff = [] catalysts = [] catalyzed_constants = [] constant = None # Clear some newlines split by whitespace s = s.strip('\n') s = s.rstrip() s = s.split(' ') #print s # The first element contains the reaction ID IDstr = s[0] s.remove(IDstr) IDstr = IDstr[:-1] IDstr = IDstr[1:] ID = int(IDstr) #print ID # Seperate everything else into reactants or product-propensity-catalysts split_r = s.index('--') split_psc = s.index('->') constant = float(s[split_r+1]) r = s[:split_r] psc = s[split_psc+1:] #print "Reactants: ", r #print "product-catalysts: ", psc # Get the reactants and their coefficients for item in r: if item != '+': coef, molecule = item.split('[') molecule = molecule[:-1] reactants.append(molecule) reactant_coeff.append(int(coef)) # Get the catalyst IDs catStr = psc[-1] #print catStr if '(' in catStr and ')' in catStr: cats = catStr.split(',') #print cats for c in cats: c = c.strip('(') c = c.strip(')') const, molecule = c.split('[') molecule = molecule[:-1] catalysts.append(molecule) catalyzed_constants.append(float(const)) #print 'Catalysts: ', catalysts, ' Constants: ', catalyzed_constants del psc[-1] del psc[-1] # Get the propensity string propStr = psc[-1] #print propStr del psc[-1] del psc[-1] #print psc # Get the products and their coefficients for item in psc: if item != '+' and item != ' ': #print item coef, molecule = item.split('[') molecule = molecule[:-1] products.append(molecule) product_coeff.append(int(coef)) #print ID, constant, reactants, reactant_coeff, products, product_coeff, catalyzed_constants, catalysts #raw_input("Enter") return ID, constant, reactants, reactant_coeff, products, product_coeff, catalysts, catalyzed_constants, propStr #open text file and read in all lines text_file = open(file_name, "r") l = text_file.readlines() text_file.close() #use deque instead of list because we are looking at the first element l = deque(l) #print l.popleft() #check and read header if l.popleft() == "<meta-data>\n": s=l.popleft() num_M=s[s.rfind(' '):len(s)-1] s=l.popleft() num_R=s[s.rfind(' '):len(s)-1] l.popleft() l.popleft() m_list = [None]*int(num_M) # This maps molecule IDs to molecule objects r_list = [None]*int(num_R) # This maps reaction IDs to reaction objects m_dict = dict() # This maps molecule strings to IDs #read molecules for i in range(int(num_M)): ID, m=read_m(l.popleft() ) m_list[ID] = m #print "Molecule: ", m, 'ID: ', ID m_dict[m] = ID l.popleft() l.popleft() #read reactions for i in range(int(num_R)): # Read Line rID, rconstant, reactant_molecules, reactant_coeff, product_molecules, product_coeff, catalyst_molecules, catalyzed_constants, propStr = read_r(l.popleft() ) # Convert molecule strings to IDs reactant_IDs = [] product_IDs = [] catalyst_IDs = [] # Get reactant IDs for r in reactant_molecules: reactant_IDs.append(m_dict[r]) # Get Product IDs for p in product_molecules: product_IDs.append(m_dict[p]) # Get Catalyst IDs for c in catalyst_molecules: catalyst_IDs.append(m_dict[c]) #print rID, rconstant, reactant_molecules, reactant_coeff, product_molecules, product_coeff, catalyst_molecules, catalyzed_constants, propStr r_list[rID] = Reaction(rID, constant= rconstant, reactants = reactant_IDs, reactant_coeff = reactant_coeff, products = product_IDs, product_coeff = product_coeff, catalysts = catalyst_IDs, catalyzed_constants = catalyzed_constants, prop = propStr) # print r_list[rID].catalysts # raw_input("Enter") # print 'Reactants: ', reactant_molecules,'Reactant IDs: ', reactant_IDs, ' Coefficients: ', reactant_coeff # print 'Products: ', product_molecules, 'Product IDs: ', product_IDs, ' Coefficients: ', product_coeff # print 'Catalysts: ', catalyst_IDs self.reactions = r_list self.molecule_dict = m_dict self.molecule_list = m_list #self.update_molecules() else: print("invalid file")