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

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

00001 
00002 """
00003 
00004 ScrumPy -- Metabolic Modelling with Python
00005 
00006 Copyright Mark Poolman 1995 - 2002
00007 
00008  This file is part of ScrumPy.
00009 
00010     ScrumPy is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     ScrumPy is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU General Public License for more details.
00019 
00020     You should have received a copy of the GNU General Public License
00021     along with ScrumPy; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 
00024 """
00025 
00026 
00027 import sys,  exceptions
00028 
00029 
00030 from Util import Seq, DynMatrix, Set, Types,Tree
00031 from Structural import StoMat, EnzSubset, ReacTree
00032 from Parser import lexer
00033 import ElModes
00034 
00035 BadElMsg="""
00036 !! Element types of stoichiometry matrix !!
00037 !!      *MUST* be arbitrary rational     !!
00038 !!              Giving up.               !!
00039 """
00040 
00041 def SMFromDesc(Desc):
00042 
00043     ElType =  Desc.OptDic["ElType"]
00044     StoDic = Desc.StoDic
00045     MetList =Desc.MetList
00046 
00047     sm = StoMat.StoMat(
00048         cnames=StoDic.keys(),
00049         rnames=MetList[:],
00050         Conv=ElType
00051     )
00052 
00053     for reac in sm.cnames:
00054         sto = StoDic[reac]
00055         sm.SetSto(reac, sto)
00056 
00057     return sm
00058 
00059 
00060 class Model:
00061 
00062     def Destroy(self):
00063         pass
00064 
00065     def BuildStructural(self):
00066         """pre: ModelDesc is correctly filled in instance of ScrumPy.Parser.Parser.ModelDescriptor """
00067 
00068         ModelDesc = self.ModelDesc
00069 
00070         self.smexterns = SMFromDesc(ModelDesc)
00071         ExtList = ModelDesc.ExtList[:]
00072         if ModelDesc.OptDic["AutoExtern"]:
00073             ExtList = Set.Union(ExtList,self.smexterns.Unbals())
00074 
00075         self.sm = self.smexterns.Copy()
00076         for e in ExtList:
00077             try:
00078                 self.sm.DelRow(e)
00079             except:
00080                 sys.stderr.write("! Warning: "+e+" declared external, but not used !\n")
00081 
00082         self.sm.Externs =  ExtList[:]
00083         self.smexterns.Externs = ExtList[:]
00084         if ModelDesc.OptDic["DeQuote"]:
00085             self.sm.DeQuote()
00086             self.smexterns.DeQuote()
00087 
00088         self.sm.Irrevs = self.sm.GetIrrevs()
00089         self.smexterns.Irrevs = self.sm.GetIrrevs()
00090 
00091         self.RemoveUnused()
00092 
00093 
00094 
00095 
00096 
00097     def DelReactions(self,Reactions):
00098         """ pre: Reactions is a list of strings
00099           post: reactions removed from self """
00100         for r in Reactions:
00101             if not r in self.sm.cnames:
00102                 sys.stderr.write("Warning: tried to delete non-existent reaction, " + r + "\n")
00103             else:
00104                 self.sm.DelReac(r)
00105                 self.smexterns.DelReac(r)
00106 
00107 
00108         self.sm.ZapZeroes()
00109         self.smexterns.ZapZeroes()
00110         self.smexterns.Externs = Set.Intersect(self.smexterns.Externs, self.smexterns.rnames)
00111         self.sm.Externs = self.smexterns.Externs[:]
00112 
00113 
00114     def AddReactions(self, StoDicDic):
00115         print "ScrumPy.Structural.Model.AddReactions due for removal"
00116         for reac in StoDicDic.keys():
00117            sto = StoDicDic[reac].copy()
00118            self.smexterns.NewReaction(reac, sto)
00119            for met in sto.keys():
00120                if met in self.sm.Externs:
00121                    del(sto[met])
00122            self.sm.NewReaction(reac, sto)
00123 
00124 
00125 
00126 
00127     def RemoveUnused(self):
00128 
00129         Unused = Set.Complement(self.smexterns.cnames, self.sm.cnames)
00130 
00131         if len(Unused) >0:
00132             print "The following reactions affect no internal metabolites, removing them:\n",Unused
00133         for u in Unused:
00134             if u in self.smexterns.cnames:
00135                 self.smexterns.DelCol(u)
00136             if u in self.sm.cnames:
00137                 self.sm.DelCol(u)
00138 
00139 
00140 
00141     def IsIrrev(self, name):
00142         """pre: name is a reaction name
00143           post: self.IsIrrev(name) => name is an irreversible reaction """
00144 
00145         return self.sm.IsIrrev(name)
00146 
00147 
00148     def NetSto(self,vels):
00149         "return a matrix of the net stoichs represented by the rate information in vels"
00150 
00151         rv = DynMatrix.matrix()
00152         sm = self.smexterns.ToNumPyMtx(conv=int)
00153         v = vels.ToNumPyMtx(conv=int)
00154         res = sm * v
00155         rv.FromNumPyMtx(res)
00156         rv.rnames = self.smexterns.rnames
00157         rv.cnames = vels.cnames
00158         return rv
00159 
00160 
00161     def Externals(self):
00162         return Set.Complement(self.smexterns.rnames, self.sm.rnames)
00163 
00164     def Transporters(self,NamesOnly=False):
00165         seen = {}
00166         rv = []
00167         exs = self.Externals()
00168         for e in exs:
00169             for tx in self.smexterns.InvolvedWith(e):
00170                 if not seen.has_key(tx):
00171                     seen[tx] = 1
00172                     rv.append([tx, Set.Intersect(exs,self.smexterns.Reactants(tx))])
00173 
00174         if NamesOnly:
00175             return seen.keys()
00176             return rv
00177 
00178 
00179     def FindIsoforms(self):
00180         stodic = {}
00181         for reac in self.smexterns.cnames:
00182             strsto = str(self.smexterns.InvolvedWith(reac))
00183             if stodic.has_key(strsto):
00184                 stodic[strsto].append(reac)
00185             else:
00186                 stodic[strsto] = [reac]
00187         rv = []
00188         for reac in stodic.values():
00189             if len(reac)>1:
00190                 rv.append(reac)
00191 
00192         return rv
00193 
00194 
00195     def DelIsoforms(self):
00196         isos = self.FindIsoforms()
00197         rv = {}
00198         for iso in isos:
00199             rv[iso[0]] = iso[1:]
00200             for reac in iso[1:]:
00201                 self.sm.DelReac(reac)
00202                 self.smexterns.DelReac(reac)
00203         return rv
00204 
00205 
00206     def FindOrphans(self):
00207         raise DeprecationWarning,  "use model.OrphanMets() instead"
00208 
00209 
00210     def OrphanMets(self):
00211         return self.smexterns.OrphanMets()
00212 
00213 
00214     def Core(self):
00215         """ pre: True
00216            post: A copy of the external stoichiometry matrix with all internal orphans
00217                  and associated reactions removed. """
00218 
00219         if self.smexterns.IsDeQuoted():
00220             self.smexterns.ReQuote()
00221             smx = self.Core()
00222             self.smexterns.DeQuote()
00223             smx.DeQuote()
00224         else:
00225             smx = self.smexterns.Copy()
00226             orphans  = Set.Complement(smx.OrphanMets(), smx.Externs)
00227             while len(orphans) > 0:
00228                 print "len(o)", len(orphans)
00229                 for met in orphans:
00230                     if not met in smx.Externs:
00231                         for rn in smx.InvolvedWith(met):
00232                             smx.DelReac(rn)
00233                         smx.DelRow(met)
00234 
00235                 smx.ZapZeroes()
00236                 orphans  = Set.Complement(smx.OrphanMets(), smx.Externs)
00237 
00238         return smx
00239 
00240 
00241     def DeadReactions(self):
00242         rv  = []
00243         k = self.sm.NullSpace()
00244         for r in k.rnames:
00245             if Seq.AllEq(k[r],0):
00246                 rv.append(r)
00247         return rv
00248 
00249     def DisconnectsK(self, thresh=1e-6,exts=False):
00250         """ pre: True
00251            post: return list of lists of disconnected subsystems by null-space analysis of self.sm
00252                     exts => use the external stoichiometry matrix
00253                     first item is possible empty list of dead reactions
00254         """
00255         if exts:
00256             k = self.smexterns.OrthNullSpace()
00257         else:
00258             k = self.sm.OrthNullSpace()
00259         deads = []
00260         for reac in k.rnames[:]:
00261             if Seq.AllMatch(k[reac], lambda x:abs(x)<thresh):
00262                 deads.append(reac)
00263                 k.DelRow(reac)
00264         return k.NonZeroR([deads],thresh)
00265 
00266 
00267     def MaxCycles(self):
00268         return self.DisconnectsK(exts=1)[1:]
00269 
00270 
00271 
00272 
00273 
00274     def EnzSubsets(self):
00275         """ pre: True
00276             post: return EnzSubset.EssDic(self)
00277                      see EnzSubset module for details
00278         """
00279 
00280         return EnzSubset.EssDic(self)
00281 
00282 
00283 
00284     def ElModes(self):
00285 
00286         ssm, sm, smx = self.EnzSubsets().CondensedSMs()
00287         if len(ssm.cnames) <2: # 0 or 1 ssubsets means 0 or 1 ems
00288             elmodes = ssm
00289             stos = smx
00290         else:
00291             ems = ElModes.GetElModes(sm)
00292             #ems.Transpose()
00293             elmodes = ssm.Mul(ems)
00294 
00295         return ElModes.ModesDB(elmodes,self)
00296 
00297 
00298 
00299     def ConsMoieties(self,raise_err=True):
00300 
00301         smt = self.sm.Copy(tx = 1)
00302         ksmt = smt.NullSpace()
00303         deps = []
00304         for c in ksmt.cnames:
00305             for r in ksmt.rnames:
00306                 if ksmt[r,c] != 0 and Seq.NumOfMatches(ksmt[r], lambda x: x!=0) ==1:
00307                     deps.append(r)
00308                     break
00309 
00310         if len(deps) != len(ksmt.cnames):
00311            print "! missed deps should have", len(smtk.cnames), "found", len(deps)
00312            if raise_er:
00313                raise exceptions.ValueError, str(len(smtk.cnames)-len(deps)) + "missing dependencies"
00314 
00315         for d in deps:
00316             ksmt.MakeFirstRow(d)
00317             c = deps.index(d)
00318             val = ksmt[0,c]
00319             ksmt.cnames[c] = d
00320             ksmt.DivCol(c,k=val)
00321 
00322 
00323         return ksmt
00324 
00325 
00326 
00327 ##
00328 ##    def ConsMoieties(self):
00329 ##        self.sm.Transpose()
00330 ##        rv  = self.sm.NullSpace()
00331 ##        if rv != None:
00332 ##            rv.RowReorder(self.sm.cnames)
00333 ##            rv.Transpose()
00334 ##            for r in range(len(rv)):
00335 ##                rv.rnames[r] = "CONS_"+str(r)
00336 ##                if  Seq.NumOfMatches(rv[r], lambda x: x<0) > Seq.NumOfMatches(rv[r], lambda x: x>0):# more -ve than +ve elements
00337 ##                    rv.MulRow(r, k = -1)
00338 ##
00339 ##            self.sm.Transpose()
00340 ##
00341 ##        return rv
00342 ##
00343     def ReacTree(self):
00344 
00345         def diff(a,b):
00346             return 1- abs(Seq.CosTheta(a,b))
00347 
00348         k = self.sm.OrthNullSpace()
00349         rdm = k.RowDiffMtx(diff)
00350         t= rdm.ToNJTree()
00351         t.rdm = rdm
00352         return t

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