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

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

00001 
00002 
00003 """
00004 
00005 ScrumPy -- Metabolic Modelling with Python
00006 
00007 Copyright Mark Poolman 1995 - 2002
00008 
00009  This file is part of ScrumPy.
00010 
00011     ScrumPy is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     ScrumPy is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU General Public License for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with ScrumPy; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025 """
00026 
00027 import sys
00028 
00029 import StoMat, Decompose
00030 from clib.ElModes import ElModes
00031 from Util import   Set, Seq, Sorter,  Types, DynMatrix
00032 from Data import Histo
00033 
00034 
00035 
00036 neg = lambda x: x<0
00037 pos = lambda x: x>0
00038 
00039 def deb(msg):
00040     sys.__stderr__.write("ElModes.py" + msg + "\n")
00041 
00042 class ModesDB:      # a data base type thing, to allow searching of elementary modes etc.
00043 
00044     def __init__(self, tabl,srcmodel, sto=None):
00045 
00046         self.model = srcmodel
00047         if tabl.__class__ == Tableau:
00048             self.mo = tabl.AsStoMat()
00049         else:
00050             self.mo = tabl
00051 
00052         if sto != None:
00053             self.sto = sto
00054         else:
00055             self.sto =  srcmodel.smexterns.Mul(self.mo)
00056 
00057             self.sto.RevProps = self.mo.RevProps = RevProps = {}
00058             for e in self.mo.cnames:
00059                 reacs = self.mo.InvolvedWith(e).keys()
00060                 RevProps[e] = StoMat.t_Rever
00061                 for r in reacs:
00062                     if not srcmodel.sm.RevProps[r] == StoMat.t_Rever:
00063                         RevProps[e] = StoMat.t_Irrev
00064                         break
00065 
00066 
00067 
00068 
00069 
00070 
00071     def _retmosto(self):
00072 
00073         mo  = StoMat.StoMat(len(self.mo))
00074         mo.rnames = self.mo.rnames[:]
00075         return mo
00076 
00077 
00078     def __len__(self):
00079         if len(self.mo) >0:
00080             return len(self.mo[0])
00081         return 0
00082 
00083     def __add__(self, other):
00084         mo = self.mo.Copy()
00085         sto = self.sto.Copy()
00086 
00087         mo.AugRow(other.mo)
00088         sto.AugRow(other.sto)
00089 
00090         return ModesDB(mo,sto,self.model,False)
00091 
00092     def NormByName(self,names):
00093         """ Normalise all modes and stos such that they consume 1 mol of the first
00094             species in  names that they utilise """
00095 
00096         for mo in self.mo.rnames:
00097             for name in names:
00098                 coeff = self.sto[mo,name]
00099                 if coeff <0:
00100                     self.mo.DivRow(mo, k=-coeff)
00101                     self.sto.DivRow(mo, k=-coeff)
00102                     break
00103 
00104 
00105 
00106 
00107 
00108     def Copy(self):
00109         return ModesDB(self.mo.Copy(), self.sto.Copy(), self.model,False)
00110 
00111     def AddMode(self,StoDic,MoDic,Name=None):
00112 
00113         if Name == None:
00114             Name = "ElMode_"+str(len(self))
00115 
00116         for dic,mat in (StoDic, self.sto),(MoDic,self.mo):
00117             mat.NewRow(name=Name)
00118             for k in dic.keys():
00119                 if not k in mat.cnames:
00120                     mat.NewCol(name=k)
00121                 mat[Name,k] = dic[k]
00122 
00123 
00124 
00125 
00126     def DelMode(self,mode):
00127         self.mo.DelRow(mode)
00128         self.sto.DelRow(mode)
00129 
00130     def Stos(self):
00131         "return a string repesentation of stoichiometries"
00132         return "".join(map(self.sto.ReacToStr, self.sto.cnames))
00133 
00134     #def Modes(self):
00135     #    "return a string representation of the elementary modes"
00136     #    return self.mo.ToStr()
00137 
00138     def Modes(self):
00139         retlist = []
00140         for e in self.mo.cnames:
00141             molist = [e]
00142             rd = self.mo.InvolvedWith(e)
00143             for r in rd:
00144                 molist.append(" ".join((str(rd[r]),r)))
00145             retlist.append(", ".join(molist))
00146         return "\n\n".join(retlist)
00147 
00148 
00149     def LenHist(self,nbins=20):
00150         """ histogram of mode lengths. """
00151 
00152         lens  = map(lambda em: self.LenOf(em), self.mo.cnames)
00153         return Histo.Histo(lens,nbins=nbins)
00154 
00155 
00156 
00157     def _rowsearch(self, name, crit, mtx, neg=0):
00158 
00159         if neg:
00160             return self._rowsearch(name, lambda x,fun=crit: not fun(x), mtx)
00161 
00162         matches = mtx.InvolvedWith(name, crit).keys()
00163         mo = self.mo.SubSys(matches)
00164         sto = self.sto.SubSys(matches)
00165 
00166         return ModesDB(mo, self.model, sto)
00167 
00168 
00169     def Consumes(self, name, neg=0):
00170         return self._rowsearch(name, lambda x: x<0, self.sto, neg)
00171 
00172     def Produces(self,name, neg=0):
00173         return self._rowsearch(name, lambda x: x>0, self.sto, neg)
00174 
00175     def Used(self, name, neg=0):
00176         return self._rowsearch(name, lambda x: x!=0, self.sto, neg)
00177 
00178     def Unused(self, name, neg=0):
00179         return self._rowsearch(name, lambda x: x==0, self.sto, neg)
00180 
00181     def PosFlux(self,name, neg=0):
00182         return self._rowsearch(name, lambda x: x>0, self.mo, neg)
00183 
00184     def NegFlux(self, name, neg=0):
00185         return self._rowsearch(name, lambda x: x<0, self.mo, neg)
00186 
00187     def HasFlux(self, name, neg=0):
00188         return self._rowsearch(name, lambda x: x!=0, self.mo, neg)
00189 
00190     def NoFlux(self, name, neg=0):
00191         return self._rowsearch(name, lambda x: x==0, self.mo, neg)
00192 
00193     def PartSto(self, names):
00194         rv = DynMatrix.matrix()
00195         for name in names:
00196             rv.NewCol(self.sto.GetCol(name), name)
00197         rv.rnames = self.sto.rnames
00198 
00199     def ReacsOf(self, m):
00200         return self.mo.InvolvedWith(m)
00201 
00202 
00203     def ConsumesAnyOf(self, names):
00204 
00205         rvd = {}
00206         for name in names:
00207             rvd.update( self.sto.InvolvedWith(name, neg))
00208 
00209         ems = rvd.keys()
00210         mo = self.mo.SubSys(ems)
00211         sto = self.sto.SubSys(ems)
00212 
00213         return ModesDB(mo,  self.model, sto)
00214 
00215     def ConsumesOnly(self, names):
00216 
00217         rv = self.ConsumesAnyOf(names)
00218         for em in rv.sto.cnames[:]:
00219             if len(rv.sto.InvolvedWith(em, neg))!=1:
00220                 rv.mo.DelCol(em)
00221                 rv.sto.DelCol(em)
00222 
00223         return rv
00224 
00225 
00226 
00227     def ProducesAnyOf(self, names):
00228         rvd = {}
00229         for name in names:
00230             rvd.update( self.sto.InvolvedWith(name, pos))
00231 
00232         ems = rvd.keys()
00233         mo = self.mo.SubSys(ems)
00234         sto = self.sto.SubSys(ems)
00235 
00236         return ModesDB(mo,  self.model, sto)
00237 
00238     def ProducesOnly(self, names):
00239 
00240         rv = self.ProducesAnyOf(names)
00241         for em in rv.sto.cnames[:]:
00242             if len(rv.sto.InvolvedWith(em, pos))!=1:
00243                 rv.mo.DelCol(em)
00244                 rv.sto.DelCol(em)
00245 
00246         return rv
00247 
00248 
00249     def Integise(self):
00250         """ convert rational -> integer representation"""
00251 
00252         self.sto.IntegiseC()
00253         self.mo.IntegiseC()
00254 
00255         #Integise = lambda s: map(int,  Seq.Integise(s))
00256         #if self.sto.Conv == Types.ArbRat:
00257         #    self.sto.rows = map(Integise,  self.sto.rows)
00258         #    self.sto.Conv = int
00259         #    self.mo.rows = map(Integise,  self.mo.rows)
00260         #    self.mo.Conv = int
00261         #else:
00262         #    print >>sys.__stderr__,  "Can only integise if matrix elements are rational - ignoring."
00263 
00264 
00265 
00266     def Futile(self):
00267         """Strictly internal cycles - ie no net stoichiometry"""
00268 
00269         ems = []
00270         for e in self.sto.cnames:
00271             if Seq.AllEq(self.sto.GetCol(e),0):
00272                 ems.append(e)
00273         mo = self.mo.SubSys(ems)
00274         sto = self.sto.SubSys(ems)
00275         return ModesDB(mo,  self.model,  sto)
00276 
00277     def GetDupStos(self):
00278         return self.sto.DupRows()
00279 
00280 
00281     def DelDupStos(self):
00282         """ remove elmodes with identical stoichs """
00283 
00284         for dups in self.GetDupStos():
00285             for d in dups[1:]:
00286                 self.sto.DelRow(d)
00287                 self.mo.DelRow(d)
00288 
00289     def MergeDupStos(self):
00290         """ merge elmodes with duplicate stoichs to form non-elementary modes """
00291 
00292         dups = self.GetDupStos()
00293         for dup in dups:
00294             for d in dup[1:]:
00295                 self.sto.DelRow(d)
00296             self.mo.AddAndRemoveRows(dup)
00297 
00298 
00299 
00300 
00301     def Decompose(self,DataSet,**opts):
00302 
00303         return Decompose.Decompose(self, DataSet, **opts)
00304 
00305 
00306     def StoOf(self, ElMo):
00307         """ returns a string repn of the net Sto of ElMo"""
00308 
00309         return self.sto.ReacToStr(ElMo)
00310 
00311 
00312 
00313     def LenOf(self, mo):
00314         """ The number of reactions in mode, mo """
00315 
00316         return  len(filter(lambda x: x!=0,self.mo.GetCol(mo)))
00317 
00318 
00319     def Shortest(self):
00320         rv = []
00321         best = len(self.mo[0])
00322         for mode in self.mo.rnames:
00323             length = self.LenOf(mode)
00324             if length < best:
00325                 rv = [mode]
00326                 best = length
00327             elif length == best:
00328                 rv.append(mode)
00329         return rv
00330 
00331 
00332 
00333     def Irrevs(self):
00334         """ pre: true:
00335            post: e.Irrves() == a posibly empty list of irreverible mode names
00336         """
00337 
00338         return filter(lambda em:self.IsIrrev(em),  self.mo.cnames)
00339 
00340 
00341     def IsIrrev(self, em):
00342 
00343         return self.mo.RevProps[em] == "->"
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 class Tableau(StoMat.StoMat): #DynMatrix.matrix):
00354 
00355     def __init__(self, sm):
00356         """pre: sm = StoMat.StoMat(...) """
00357 
00358         #StoMat.StoMat.__init__(self, Conv=Types.ArbRat, FromMtx=sm)
00359         ## FromMtx will over-ride Conv, hence we do it as a separate step. The C module
00360         ## *MUST* have ArbRats as ElType.
00361         StoMat.StoMat.__init__(self, FromMtx=sm)
00362         if self.Conv != Types.ArbRat:
00363             self.ChangeType(Types.ArbRat)
00364         self.RevProps.update(sm.RevProps)
00365         self.Transpose()
00366         # start with a transposed copy of the stoichiometry matrix
00367 
00368         id = DynMatrix.GetIdent(len(sm.cnames))           # get ident matrix of same size
00369         id.cnames = sm.cnames[:]                          # ident col names will be reaction names
00370         self.AugCol(id)                                   # augment transposed stomat with ident
00371 
00372         self.nMets = len(sm.rnames)                       # Make data available in convenient form
00373         self.RowLen = len(self.rows[0])                   # for the C library
00374         self.IrrevIdxs = []                               # indices of irreversible reactions in self
00375         for name in sm.GetIrrevs():                          # from those in the original sm
00376             self.IrrevIdxs.append(self.rnames.index(name)+self.nMets)
00377             self.IrrevLen = len(self.IrrevIdxs)
00378         self.Results = []                                   # where the C lib will deposit the results
00379 
00380 
00381 
00382 
00383     def GetElModes(self):
00384 
00385         ElModes.ElModes(self)  # ElModes is the low-level C entity
00386 
00387         self.cnames = []
00388         self.rows=[]
00389         self.RevProps = {}
00390 
00391         print "" , # very wierd - Idle ? - next line sometimes excepts without *some* write to stdout/stderr
00392         for i in self.rnames:
00393             self.rows.append([])
00394 
00395         for r in range(len(self.Results)):
00396             cname = "ElMo_" + str(r)
00397             self.NewCol(map(
00398                 self.Conv,
00399                 self.Results[r][self.nMets:]
00400               ),
00401               cname
00402             )
00403 
00404 
00405 
00406 
00407 
00408 
00409     def AsStoMat(self):
00410         rv =StoMat.StoMat(FromMtx=self)
00411         rv.RevProps=dict(self.RevProps)
00412         return rv
00413 
00414 
00415 def GetElModes(sm):
00416     t = Tableau(sm)
00417     t.GetElModes()
00418     return t
00419 
00420 
00421 def GetModesDB(m):
00422 
00423     t = GetElModes(m.sm)
00424     return ModesDB(t, m)
00425 
00426 
00427 
00428 
00429 def FancyGetElModes(sm):
00430 
00431 
00432     #def ColSort(Col, mtx):
00433     #    return Seq.Angle(mtx.GetCol(0), mtx.GetCol(Col))
00434 
00435     def ModSort(row, mtx):
00436         return Seq.Mod(mtx[row])
00437     sort = Sorter.Sorter()
00438     for r in sm.rnames:
00439         sort.append(r)
00440     sorted = sort.Sort(ModSort,mtx=sm)
00441     print sorted
00442     sm.RowReorder(sorted)
00443     t = Tableau(sm)
00444 
00445     t.GetElModes()
00446 
00447     return t
00448 
00449 
00450 
00451 

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