• Main Page
  • Namespaces
  • Classes
  • Files
  • File List

/home/mark/model/software/ScrumPy/ScrumPy/Bioinf/PyoCyc/Reaction.py

00001 import Base
00002 import Tags
00003 from  ECEquivs import ECEquivs
00004 
00005 
00006 DefaultFile = "reactions.dat"
00007 
00008 from Parser.lexer import  t_Irrev,  t_BackIrrev,  t_Rever
00009 
00010 
00011 DirecMap = {
00012     'IRREVERSIBLE-RIGHT-TO-LEFT' : t_BackIrrev,
00013     'PHYSIOL-RIGHT-TO-LEFT'      : t_BackIrrev,
00014     'LEFT-TO-RIGHT'              : t_Rever,
00015     'REVERSIBLE'                 : t_Rever,
00016     'RIGHT-TO-LEFT'              : t_BackIrrev,
00017     'IRREVERSIBLE-LEFT-TO-RIGHT' : t_Irrev,
00018     'PHYSIOL-LEFT-TO-RIGHT'      : t_Irrev
00019 }
00020 ## Better to define these strings as consdtants in Tags ??
00021 DefaultDirec = DirecMap['LEFT-TO-RIGHT']
00022 
00023 
00024 class Record(Base.Record):
00025     ParentFields=[Tags.EnzReac]
00026     ChildFields = [Tags.Left, Tags.Right, Tags.InPath]
00027     RecordClass="Reaction"
00028     def __init__(self, id,BadCoeffs=[],**kwargs):
00029         Base.Record.__init__(
00030             self,
00031             id,
00032             **kwargs)
00033         self.lhs = []
00034         self.rhs = []
00035         self[Tags.Left] = []
00036         self[Tags.Right] = []
00037 
00038         self.CoeffDic={}
00039         self.CurMet = ""
00040         self.BadCoeffs =BadCoeffs  # add our self to this list if we have bad coeffs, eg substrate is polymer
00041 
00042     def __AddLeft__(self, met):
00043         self.CoeffDic[met] = -1
00044         self.lhs.append(met)
00045 
00046     def __AddRight__(self, met):
00047         self.CoeffDic[met] = 1
00048         self.rhs.append(met)
00049 
00050     def __AddCoeff__(self, k):
00051         self.CoeffDic[self.CurMet] *= int(k)
00052 
00053     def NewTag(self, tag, val):
00054 
00055         if tag == Tags.Left:
00056             self.CurMet=val
00057             self.__AddLeft__(val)
00058         elif tag == Tags.Right:
00059             self.CurMet=val
00060             self.__AddRight__(val)
00061         elif tag == Tags.Coeff:
00062             try:
00063                 self.__AddCoeff__(val)
00064             except:
00065                 self.BadCoeffs.append(self)
00066         Base.Record.NewTag(self,tag,val)
00067 
00068 
00069 
00070     def strhs(self, side):
00071         if side ==[]:
00072             return "NOTHING"
00073         met = side[0]
00074         coeff =  abs(self.CoeffDic[met])
00075         if coeff == 1:    # coeff of first met = 1 ?
00076             rv = '"'+met+'"'     #  yes - just keep the met not the 1
00077         else:
00078             rv = str(coeff) + ' "' + met+'"'   # no - record the coeff and the met
00079 
00080         for met in side[1:]:    # do the same on the rest
00081             coeff =  abs(self.CoeffDic[met])
00082             if coeff ==1:
00083                 rv +=' + "' + met +'"'
00084             else:
00085                 rv += " + " + str(coeff) + '  "' + met +'"'
00086         return rv
00087 
00088     def AsScrumPy(self,Prep=""):
00089 
00090         Name = "".join(['"',Prep,self.UID,'":'])
00091         RevCom = ""
00092         Indent = " "*4
00093                         
00094         if self.lhs==[] or self.rhs==[]:
00095             print "Warning :", self.UID, " has missing reactants(s)"
00096 
00097         lhs = self.strhs(self.lhs)
00098         rhs = self.strhs(self.rhs)
00099         Direc = DefaultDirec
00100 
00101         if self.has_key(Tags.ReacDir):
00102             Rev =  self[Tags.ReacDir][0]
00103             RevCom= "".join([Indent,"#",Rev])
00104             if DirecMap.has_key(Rev):
00105                 Direc = DirecMap[Rev]
00106             else:
00107                 print " ".join(["!! Warning:", Name,  "has unknown",  Tags.ReacDir,  "using",  Direc,  "!!"] )
00108 
00109 
00110         Stoich = "".join([Indent, lhs, Direc, rhs])
00111         Kins = Indent + "~"
00112 
00113         return "\n".join([Name, Stoich, Kins,  RevCom,  "\n"])
00114 
00115 
00116     def __str__(self):
00117         keys = self.keys()
00118         keys.remove(Tags.UID)
00119         rv = Base.Field2Str(Tags.UID, self[Tags.UID])
00120         for k in keys:
00121             if k not in [Tags.Coeff, Tags.Right,Tags.Left]:  # The order matters for these so do themseperately
00122                 rec = self[k]
00123                 for r in rec:
00124                     rv += Base.Field2Str(k, r)
00125 
00126         for left in self[Tags.Left]:
00127            rv += Base.Field2Str(Tags.Left, left)
00128            if self.CoeffDic.has_key(left):
00129                rv += Base.Field2Str(Tags.Coeff, self.CoeffDic[left])
00130 
00131         for right in self[Tags.Right]:
00132            rv += Base.Field2Str(Tags.Right, right)
00133            if self.CoeffDic.has_key(right):
00134                rv += Base.Field2Str(Tags.Coeff, self.CoeffDic[right])
00135 
00136         try:
00137             cat = Base.TabStrFormat("Catalyses", self.strhs(self.lhs) + " -> " + self.strhs(self.rhs))
00138         except:
00139             cat = ""
00140         return rv + cat
00141 
00142     def AtomSto(self, side):
00143         """pre: side == Tags.Left' || side ==  Tags.Right
00144           post: AtomSto => dictionary of atomic stoichiometry of l or r hs """
00145 
00146         rv = {}
00147         if not self.has_key(side):
00148             return rv
00149         for comp in self[side]:
00150             if comp[0] == "|":
00151                 c2=comp[1:-1]
00152                 self.CoeffDic[c2]=self.CoeffDic[comp]
00153                 comp=c2
00154             if self.Org.Compound.has_key(comp):
00155                 atoms = self.Org.Compound[comp].EmpForm
00156                 coeff = abs(self.CoeffDic[comp])
00157                 for k in atoms.keys():
00158                     if rv.has_key(k):
00159                         rv[k] +=  coeff *atoms[k]
00160                     else:
00161                         rv[k] = coeff*atoms[k]
00162             else:
00163                 #print "!!! missing compound ", comp, " for reaction ", self[Tags.UID], " !!!"
00164                 rv ["Missing "+ comp] = 1
00165         return rv
00166 
00167 
00168     def NetBal(self):
00169         BalDic = self.AtomSto(Tags.Left)
00170         right = self.AtomSto(Tags.Right)
00171         for k in right.keys():
00172             if BalDic.has_key(k):
00173                 BalDic[k] -= right[k]
00174             else:
00175                 BalDic[k] = -right[k]
00176         return BalDic
00177 
00178     def ImBal(self):
00179         bal = self.NetBal()
00180         for met in bal.keys():
00181             if bal[met]==0:
00182                 del bal[met]
00183         return bal
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 class DB(Base.DB):
00194     def __init__(self,
00195                  path=Base.DefaultPath,
00196                  file=DefaultFile,
00197                  RecClass=Record,
00198                  **kwargs):
00199 
00200 
00201         BadCoeffs = []
00202 
00203         Base.DB.__init__(
00204             self,
00205             path,
00206             file,
00207             RecClass=Record,
00208             BadCoeffs = BadCoeffs,
00209             **kwargs
00210         )
00211 
00212         self.ECNos = {}
00213         self.BadCoeffs = BadCoeffs                           # list of reactions for which coeff could not be dermined
00214         for reac in self.values():                   #  for every reaction
00215             if reac.has_key(Tags.EC):             # if that record has an EC field
00216                 ec = reac[Tags.EC][0]               # get the ec number
00217                 if self.ECNos.has_key(ec):        # have we seen this before ?
00218                     self.ECNos[ec].append(reac)    # yes, put it in with the others
00219                 else:
00220                     self.ECNos[ec] = [reac]            # no, start a new list
00221 
00222         self.ExtraReacs = {}
00223         if '# MetaCyc\n' in self.Comments:     # if we are a metacyc db look for extra reactions
00224             self.ExtraReacs = DB(path=path, file="ExtraReacs.dat")
00225 
00226 
00227     def __getitem__(self,k):
00228 
00229         try:
00230             return Base.DB.__getitem__(self,k)    # is the key present ?
00231         except:
00232             try:
00233                 return self.ECNos[k]                      # no - is it present as an ec number ?
00234             except:
00235                 try:
00236                     return self.ECNos[ECEquivs[k]]    # no - can we get an equivalent ec number ?
00237                 except:
00238                     try:
00239                         return self.ExtraReacs[k]            # finally, see if we have it in extra reacctions
00240                     except: return []
00241 
00242 
00243     def has_key(self, k):
00244 
00245         return len(self[k]) != 0 # yes, very icky - has_key and getitem need re-writing nicely
00246 
00247 
00248     def GoodBadBals(self):
00249         """ pre: True
00250           post: returns (good,bad) dictionaries of reactions wich do/not balance"""
00251 
00252 
00253         rv = ({},{})
00254         for k in self.keys():
00255             dic = 0
00256             bal = self[k].NetBal()
00257             for v in bal.values():
00258                 if v != 0:
00259                     dic = 1
00260                     break
00261             rv[dic][k] = bal
00262         return rv
00263 

Generated on Tue Sep 4 2012 15:38:01 for ScrumPy by  doxygen 1.7.1