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:
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
00135
00136
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
00256
00257
00258
00259
00260
00261
00262
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):
00354
00355 def __init__(self, sm):
00356 """pre: sm = StoMat.StoMat(...) """
00357
00358
00359
00360
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
00367
00368 id = DynMatrix.GetIdent(len(sm.cnames))
00369 id.cnames = sm.cnames[:]
00370 self.AugCol(id)
00371
00372 self.nMets = len(sm.rnames)
00373 self.RowLen = len(self.rows[0])
00374 self.IrrevIdxs = []
00375 for name in sm.GetIrrevs():
00376 self.IrrevIdxs.append(self.rnames.index(name)+self.nMets)
00377 self.IrrevLen = len(self.IrrevIdxs)
00378 self.Results = []
00379
00380
00381
00382
00383 def GetElModes(self):
00384
00385 ElModes.ElModes(self)
00386
00387 self.cnames = []
00388 self.rows=[]
00389 self.RevProps = {}
00390
00391 print "" ,
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
00433
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