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

/home/mark/model/software/ScrumPy/ScrumPy/Structural/EnzSubset.py

00001 """
00002 Classes and functions dealing with enzyme subsets
00003 Main user interface is class EssDic
00004 functions before this are private(ish) helpers for EssDic
00005 functions following are public
00006 """
00007 
00008 
00009 
00010 
00011 # import pickle - No ! pickle **WAY** too slow for large models
00012 import sys
00013 from Util import DynMatrix,Set,Seq,Types
00014 from Structural import StoMat
00015 
00016 
00017 def EssList(m,k=None):
00018     """ pre: m = ScrumPy.Model()
00019                  k = None || k = m.sm.NullSpace()
00020          post: list subsets, each subset is a list of (name, value) tuples
00021                   first item is (possibly empty) subset of dead reactions
00022     """
00023 
00024     if k == None:
00025         k = m.sm.NullSpace()
00026     else:
00027         k = k.Copy()
00028 
00029     k.ZapZeroes()
00030     One = k.Conv(1)
00031     deads = Set.Complement(m.sm.cnames, k.rnames)
00032     ess = [map(lambda x:(x,One), deads)]
00033 
00034     while len(k) !=0:
00035         ss = [(k.rnames[0],One)]
00036         row = k[0]
00037         k.DelRow(0)
00038         for r in k.rnames[:]:
00039             ap = Seq.AreParallel(k[r],row)
00040             if ap[0]:
00041                 ss.append((r,ap[1]))
00042                 k.DelRow(r)
00043         ess.append(ss)
00044 
00045     return ess
00046 
00047 
00048 def EssMtx(m,essl = None):
00049     """ pre: m = ScrumPy.Model()
00050                  essl == None || EssAsList(m)
00051        post:  matrix of enz subsets """
00052 
00053     essl = EssList(m)[1:]
00054     rle = range(len(essl))
00055     ssnames = map(lambda x: "Ess_"+str(x), rle)
00056     rnames  = m.sm.cnames[:]
00057     rv = StoMat.StoMat(rnames = rnames, cnames = ssnames)
00058     for ssi in rle:                  # for each subset index
00059         ss = essl[ssi]              # the subset
00060         for reac,val in ss:
00061             rv[reac,ssi] = val
00062     return rv
00063 
00064 
00065 
00066 class EssDic(dict):
00067     """ Dictionary subclass mapping enzyme subsets to reactions and vice-versa
00068           pretty much anything useful with subsets should be done via this class
00069     """
00070 
00071     def __init__(self,m,essl=None):
00072         """ pre: m = ScrumPy.Model
00073                      essl = None || essl = EssList(m)
00074                      (only use essl for development/debugging purposes)
00075              post: OK. will write messages on sys.stderr if inconsistent irreversibility
00076                       specifications found, but will not act on this
00077         """
00078 
00079         if essl == None:
00080             essl = EssList(m)
00081 
00082         self.Model = m
00083         self.ReacRevProps = dict(m.sm.RevProps)
00084         self.RevProps = {}
00085         self.Rev ={}
00086         self.Inconsistants = [] # list of subsets with inconsitent irreversible reactions
00087 
00088         self._AddSS("DeadReacs",essl[0])
00089         n = 1
00090         for ss in essl[1:]:
00091             if len(ss)==1:
00092                 name = ss[0][0]
00093             else:
00094                 name = "Ess_"+str(n)
00095                 n+= 1
00096             self._AddSS(name,ss)
00097 
00098 
00099     def _AddSS(self,key,ss):
00100         """ Private """
00101 
00102         val = {}
00103         rev = True    # Reversibility of subset
00104         for s in ss:
00105             reac = s[0]
00106             val[reac] = s[1]
00107             self.Rev[reac] = key # reverse lookup: reac->ss
00108             if self.ReacRevProps[reac] != StoMat.t_Rever:
00109                 rev = False
00110 
00111         self[key]= val
00112         if rev:
00113             self.RevProps[key] = StoMat.t_Rever
00114         else:
00115             self.RevProps[key] = StoMat.t_Irrev
00116             self.RevCheck(key)
00117 
00118 
00119 
00120 
00121     def RevCheck(self,  key):
00122 
00123         def WrongWay(ss):
00124             for reac in ss:
00125                 coeff = ss[reac]
00126                 revcrit = self.ReacRevProps[reac]
00127                 if (coeff < 0 and revcrit == StoMat.t_Irrev) or (
00128                     coeff > 0 and revcrit == StoMat.t_BackIrrev):
00129                        return True
00130             return False
00131 
00132 
00133         ss = self[key]
00134 
00135         if WrongWay(ss):
00136             for reac in ss.keys():
00137                 ss[reac] *= -1
00138 
00139         if WrongWay(ss):
00140             sys.stderr.write("!\n! Inconsistent irreversible reactions in subset "+ key + "\n")
00141             sys.stderr.write("! " + str(ss.keys()) + "\n!\n")
00142             self.Inconsistants.append(key)
00143 
00144 
00145     def RevCheckOld(self, key):
00146         """ pre: self.has_key(key) (privateish)
00147             post: checks for irreversible reactions in self[key],
00148                      ensures correct sign  of coeffs, and marks as irrev  if irreversible,
00149                      reports inconsistent irreversbility in self[key]
00150         """
00151 
00152         subset = self[key]
00153         irrevs = []
00154         negate = False
00155 
00156         for reac in subset.keys():
00157             if reac in self.Model.sm.Irrevs:
00158                 irrevs.append(reac)
00159                 if  subset[reac] <0:
00160                     negate = True
00161 
00162         if negate:
00163             for reac in subset.keys():
00164                 subset[reac] *= -1
00165 
00166             error = False
00167             for reac in  irrevs:
00168                 if subset[reac] < 0:
00169                     error = True
00170 
00171             if error:
00172                 sys.stderr.write("!\n! Inconsistent irreversible reactions in subset "+ key + "\n")
00173                 sys.stderr.write("! " + str(subset.keys()) + "\n!\n")
00174                 self.Inconsistants.append(key)
00175                 del self.Irrevs[key]
00176 
00177 
00178 
00179 
00180 
00181     def ReacToSS(self,reac):
00182         """ pre: reac present in the model
00183             post: name of subset of which reac is a member
00184         """
00185         return self.Rev[reac]
00186 
00187 
00188 
00189     def SameSS(self,reac):
00190         """ pre: self.ReacToSS(reac)
00191             post: return the names of reactions in the same subset (including reac)
00192         """
00193         return self[self.ReacToSS(reac)].keys()
00194 
00195 
00196 
00197 
00198     def ToMtx(self,ExclDeadIncs=False):
00199         """ pre: True
00200             post: subsets in matrix form, ExclDeadIncs => don't include dead or inconsistant subsets in the matrix
00201         """
00202 
00203         rnames  = self.Model.sm.cnames[:]
00204         ssnames = self.keys()
00205         if ExclDeadIncs:
00206             for i in self.Inconsistants+["DeadReacs"]:
00207                 ssnames.remove(i)
00208 
00209         rv = StoMat.StoMat(rnames = rnames, cnames =ssnames)
00210         for ssn in ssnames:
00211             ss = self[ssn]
00212             for reac in ss.keys():
00213                 rv[reac,ssn] = self[ssn][reac]
00214         rv.RevProps = dict(self.ReacRevProps)
00215 
00216         return rv
00217 
00218 
00219     def CondensedSMs(self):
00220         """ pre: True
00221            post: (self.ToMtx(), Condensed Internal SM, Condensed External SM) """
00222 
00223 
00224         ssm = self.ToMtx(True)
00225         m = self.Model
00226         sm = m.sm.Mul(ssm)
00227         sm.ZapZeroes()
00228 
00229         sm.RevProps = dict(self.RevProps)
00230         smx = m.smexterns.Mul(ssm)
00231         smx.ZapZeroes()
00232         smx.RevProps = dict(self.RevProps)
00233 
00234         return ssm, sm, smx
00235 
00236 
00237 
00238     def SaveCondensedModel(self,fname=None):
00239         """ pre: fname != None => fname can be opened for writing
00240                      else:  current working directory is writable
00241             post: current model is in condensed form saved as a ScrumPy file
00242                      with a cPickled self.
00243                      as fname_Condensed and fname_Condensed_esd.pic
00244                      if fname was None model.fname will be used
00245         """
00246 
00247         m = self.Model
00248 
00249         mfname = fname or m.FileName + "_Condensed"
00250         out = open(mfname,"w")
00251         print "Saving condensed model", mfname
00252 
00253         smx = m.smexterns.Mul(self.ToMtx(True))
00254 
00255 
00256         smx.RevProps = self.RevProps()
00257         for c in range(len(smx.cnames)):
00258             cname = smx.cnames[c]
00259             if len(self[cname])>1:
00260                 reac = "_".join([cname]+self[cname].keys())
00261                 smx.RevProps[reac] = self.RevProps[cname]
00262                 smx.cnames[c] = reac
00263 
00264         smx.ToScrumPy(out,Externs=self.Model.Externals())
00265 
00266 
00267 
00268     def ToList(self):
00269 
00270         keys = self.keys()
00271         keys.remove("DeadReacs")
00272         rv = [self["DeadReacs"].items()]
00273         for k in keys:
00274             rv.append(map(lambda x:x[0],self[k].items()))
00275         return rv
00276 
00277     def SaveFile(self, FileName=None):
00278         """ pre: FileName != None => open(FileName,"w") will succeed
00279            post: self saved as Pickle to FileName if given
00280                     or to self.Model.FileName +" _esd.pic" if FileName != None"""
00281 
00282         print "Don't use 'SaveFile()'"
00283         return
00284 
00285         if FileName == None:
00286             FileName = self.Model.FileName + "_esd.pic"
00287 
00288         model = self.Model
00289         self.Model = self.Model.FileName
00290 
00291         for v in self.values():
00292             for k in v.keys():
00293                 v[k] = str(v[k])
00294 
00295         out = open(FileName,"w")
00296         pickle.dump(self,out)
00297 
00298         self.Model = model
00299 
00300         for v in self.values():
00301             for k in v.keys():
00302                 v[k] = Types.ArbRat(v[k])
00303 
00304 
00305 
00306     def IsIrrev(self,ss):
00307         """ pre: True
00308            post: self.IsIrrev(ss) => ss is irreversible
00309         """
00310         return  self.RevProps[ss] != StoMat.t_Rever
00311 
00312 
00313     def Irrev_ss(self):
00314         """ pre: True
00315             post: list of irreversible subsets
00316         """
00317         return map(lambda reac:self.RevProps[reac],  filter(self.IsIrrev,  self.keys()))
00318 
00319 
00320 
00321 def EsdFromFile(FileName, LoadModel=False):
00322     """ pre: Esd.SaveFile(FileName)
00323         post: loads and returns previously saved esd
00324                 LoadModel => model is loaded too
00325     """
00326 
00327     inp = open(FileName)
00328     rv = pickle.load(inp)
00329 
00330 
00331     for v in rv.values():
00332         for k in v.keys():
00333             v[k] = Types.ArbRat(v[k])
00334 
00335 
00336     if LoadModel:
00337         rv.Model = ScrumPy.Model(rv.Model)
00338     return rv
00339 

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