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

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

00001 import sys
00002 from ScrumPy.Util.Tree import Tree
00003 from ScrumPy.Util import Set,Sci,Seq
00004 import StoMat
00005 
00006 
00007 def ListToName(l):
00008     l.sort()
00009     return "_".join(l)
00010 
00011 class Smholder:
00012     def __init__(self, sm, xsm):
00013         self.sm = sm
00014         self.smexterns = xsm
00015         
00016 
00017 class PartialMode:
00018     def __init__(self, sm,Balances = [],Uses = [],Irrev=False):
00019         
00020         names = sm.cnames[:]
00021         names.sort()
00022         self.Name = "_".join(names)
00023         self.sm = sm
00024         self.Balances = Balances
00025         self.Irrev = Irrev
00026         self.Uses = Uses
00027         
00028 
00029     def DefinedSto(self):
00030         return len(self.sm.cnames)==1
00031 
00032     def __str__(self):
00033         return ", ".join(
00034             (
00035                 self.Name,
00036                 str(self.Substrates()),
00037                 str(self.Products())
00038                 )
00039         )
00040 
00041     def __repr__(self):
00042         return self.Name
00043 
00044     def Substrates(self):
00045         rv = []
00046         for reac in self.sm.cnames:
00047             rv = Set.Union(rv,self.sm.InvolvedWith(reac,lambda x: x<0).keys())
00048         return rv
00049 
00050 
00051     def Products(self):
00052         rv = []
00053         for reac in self.sm.cnames:
00054             rv = Set.Union(rv,self.sm.InvolvedWith(reac,lambda x: x>0).keys())
00055         return rv
00056 
00057             
00058     def Reactants(self):
00059         return self.sm.rnames[:]
00060 
00061 
00062     def CombinedSM(self, Other, UseMets=[]):
00063 
00064         cols = self.sm.cnames + Other.sm.cnames
00065 
00066         rv = StoMat.StoMat(Conv=self.sm.Conv,rnames=UseMets,cnames=cols)
00067         for srcsm in self.sm,Other.sm:
00068             rows = Set.Intersect(srcsm.rnames, UseMets)
00069             for row in rows:
00070                 for col in srcsm.cnames:       
00071                     rv[row,col]=srcsm[row,col]
00072         return rv
00073 
00074     def SubSysModes(self, Other):
00075 
00076         sys.stderr.write( "Subsys modes\n")
00077 
00078         sReactants= self.Reactants()
00079         oReactants =Other.Reactants()
00080         Interns = Set.Intersect(sReactants, oReactants)
00081         if len(Interns)==0:
00082             return []
00083         AllMets = Set.Union(sReactants, oReactants)
00084         Intsm = self.CombinedSM(Other, Interns)
00085         Extsm = self.CombinedSM(Other, AllMets)
00086 
00087         Subtree = ReacTree(Smholder(Intsm,Extsm))
00088         Subtree.ElModes()
00089 
00090         print "Subsys modes end"
00091         return Subtree.ems.values() + Subtree.ParModes.values()
00092 
00093         
00094 
00095     def CombinedWith(self, Other):
00096         if Set.DoesIntersect(self.Balances, Other.Reactants()) or Set.DoesIntersect(self.Reactants(), Other.Balances):
00097             return []
00098 
00099         
00100 
00101         sReactants = self.Reactants()
00102         oReactants = Other.Reactants()
00103         Interns = Set.Intersect(sReactants, oReactants)
00104         Externs = Set.Difference(sReactants,oReactants)
00105         Balances = Set.Union(self.Balances, Other.Balances)
00106         LeafReacs = Set.Union(self.Uses,Other.Uses)
00107         
00108         print "Combining", self.Name, Other.Name, "sharing", Interns
00109         UnDefSto = True
00110 
00111         if Interns != []:
00112             #if not (self.DefinedSto() and Other.DefinedSto()):
00113             #    return self.SubSysModes(Other)
00114             
00115             Intsm = self.CombinedSM(Other, Interns)  
00116             print "intsm\n", Intsm,"\n"
00117             k = Intsm.NullSpace()
00118             print "k\n", k,"\n"
00119             if k != None:
00120                 kdim = len(k.cnames)
00121                 UnDefSto = False
00122                 Extsm = self.CombinedSM(Other, Externs)
00123                 if Externs !=[]:
00124                     stoich = Sci.mul(Extsm,k).tolist()                                                               # stoich of the new mode
00125                     Extsm.cnames = k.cnames
00126                     Extsm.rows = stoich
00127                     print "extsm orig\n", Extsm
00128                     name = ListToName(self.sm.cnames + Other.sm.cnames)
00129                     if kdim == 1:
00130                          Extsm.cnames = [name]
00131                     else:
00132                         Extsm.cnames = []
00133                         for cn in k.NamesNonZeroesInCols():
00134                             Extsm.cnames.append(ListToName(cn))
00135                 Balances = Set.Union(Balances, Intsm.rnames)
00136                 
00137         if UnDefSto:
00138             Extsm = self.CombinedSM(Other,Externs+Interns)
00139         Extsm.ZapZeroes()
00140         if UnDefSto: sys.stderr.write("!! ")
00141         print "final sto", Extsm    
00142         return [PartialMode(Extsm,Balances,LeafReacs)]
00143 
00144 
00145             
00146 
00147                
00148 class ReacTree(Tree):
00149     def __init__(self, Model=None,*args,**kwargs):
00150         Tree.__init__(self,*args,**kwargs)
00151         self.Model = Model
00152         if Model != None:
00153             self.FromNJStr(self.Model.sm.ReactionNJTree(),Constructor=ReacTree)
00154             self.SetModelData()
00155 
00156 
00157     def __str__(self):
00158         if self.IsLeaf():
00159             return str(self.UserData)
00160         return Tree.__str__(self)    
00161           
00162 
00163     def SetModelData(self,bid=0):
00164         if self.Parent !=None:
00165             self.Model = self.Parent.Model
00166             self.bid = bid  # binary id
00167         else:
00168             self.bid=1
00169 
00170         self.strbid = str(bid)
00171             
00172         chbid=0
00173         for ch in self.Children:
00174             ch.SetModelData(self.bid*2+chbid)
00175             chbid+=1
00176             
00177 
00178 
00179     def HasLeaf(self, name):
00180         return Tree.HasLeaf(self,name,lambda leaf,name: leaf.UserData==name)
00181 
00182 
00183 
00184     def Reactions(self):
00185         """ pre: True
00186           post: list of reactions in this tree """
00187 
00188         try:
00189             return self.__reactions
00190         except:
00191             if self.IsLeaf():
00192                 self.__reactions = [self.UserData] # UserData set by base class FromNJStr
00193             else:
00194                 self.__reactions = []
00195                 for l in  self.AllLeaves():
00196                     self.__reactions.extend(l.Reactions())
00197         return self.__reactions
00198 
00199 
00200     def Metabolites(self):
00201 
00202         try:
00203             return self.__metabolites
00204         except:
00205             self.__metabolites = []
00206             for reac in self.Reactions():
00207                 mets = self.Model.smexterns.InvolvedWith(reac).keys()
00208                 self.__metabolites= Set.Union(self.__metabolites,mets)
00209         return self.__metabolites
00210 
00211 
00212 
00213     def ExtMetabolites(self,Globals=True):
00214         """pre: True
00215          post: list of internal metabolites used by self external to the model or used by non-descendent nodes """
00216 
00217         mets = self.Metabolites() # metabolites we use
00218         if self.IsLeaf():   # if we are a leaf node, all our mets are external
00219             return mets
00220         root = self.Root()
00221         rv = []
00222         for met in mets:
00223             subtree =root.Uses([met])    # minimal subtree that uses met
00224             if not (subtree == self or  subtree.IsSub(self)):
00225                 rv.append(met)                  # met used outside of self
00226             elif Globals and met in self.Model.sm.Externs:
00227                 rv.append(met)
00228         return rv
00229 
00230 
00231 
00232     def Contains(self,Reactions=[]):
00233         """ pre: self.HasLeaves(Reactions), len(Reactions)>1
00234            post: minimal subtree containing Reactions"""
00235 
00236 
00237         if self[0].HasLeaf(Reactions[0]):
00238             ch = self[0]
00239         elif self[1].HasLeaf(Reactions[0]):
00240             ch = self[1]
00241         else:
00242             return self
00243 
00244         for r in Reactions[1:]:
00245             if not ch.HasLeaf(r):
00246                 return self
00247         return ch.Contains(Reactions)
00248 
00249 
00250     def Uses(self,Metabolites=[]):
00251         """pre: Metabolite is used by at least one reaction under self
00252           post: minimal subtree of reactions using Metabolite """
00253 
00254         reacs = []
00255         for met in Metabolites:
00256             reacs.extend(self.Model.smexterns.InvolvedWith(met).keys())
00257         return self.Root().Contains(reacs)
00258 
00259 
00260 
00261        
00262     def GetDoneParents(self):
00263         """ pre: True
00264           post: list of nodes for whom all children have a stoichiometry matrix """
00265 
00266 
00267         if self.DoneModes:
00268             return []
00269         if self[0].DoneModes and self[1].DoneModes:
00270             return [self]
00271 
00272         
00273         return self[0].GetDoneParents() + self[1].GetDoneParents()
00274 
00275 
00276 
00277         
00278     def PromoteCombinations(self):
00279  
00280         pms0 = self[0].ParModes
00281         pms1 = self[1].ParModes
00282         pms = self.ParModes
00283         ems = self.Root().ems
00284         Externs = self.Model.sm.Externs
00285                                                                                   
00286         for reac0 in pms0.keys():                                                   # now find and combine usable pairs of reactions
00287             pm0 = pms0[reac0]
00288             for reac1 in pms1.keys():
00289                 modes = []
00290                 pm1 = pms1[reac1]
00291                 if not pm0.DefinedSto() or not pm1.DefinedSto():
00292                     if len(Set.Union(pm0.Uses,pm1.Uses)) < len(self.Model.sm.cnames):
00293                         modes = pm0.SubSysModes(pm1)
00294                 else:
00295                     modes = pm1.CombinedWith(pm0)
00296                         
00297                 for pmnew in modes:
00298                     if Set.IsSubset(pmnew.Reactants(), Externs):
00299                         dest = ems
00300                         sys.stderr.write("Elementary " + pmnew.Name +"\n")
00301                     else:
00302                         dest = pms
00303                     dest[pmnew.Name] = pmnew
00304                 
00305                 
00306                                             
00307     def PromoteChildren(self):
00308 
00309         ParModes = self.ParModes
00310         ExtMets = self.ExtMetabolites()
00311         print  ExtMets
00312         
00313         for ch in self[0],self[1]:                           # promote children that can produce/consume metabolites external to this node
00314             chpms = ch.ParModes
00315             for reac in chpms.keys():
00316                 chpm = chpms[reac]
00317                 mets = chpm.Reactants()
00318  
00319                 if Set.DoesIntersect(mets, ExtMets):                # involved with at least one metabolite external to ourself
00320                     ParModes[reac] = ch.ParModes[reac]     # record it as one of our partial modes
00321    
00322 
00323 
00324     def CalcModes(self):
00325 
00326         print 
00327         if self.IsRoot(): print "Root" 
00328      
00329         self.ParModes = {}                                               # store partial modes in terms of leaf reactions
00330         self.ElType = self.Model.sm.Conv
00331        
00332         self.PromoteChildren()
00333         self.PromoteCombinations()
00334   
00335         self.DoneModes=True
00336 
00337         
00338                             
00339 
00340     def ElModes(self):
00341         """ pre: self.IsRoot()
00342           post: return pair of matrices sto, mo - stoichiometry matrix and reaction matrix of elmodes """
00343   
00344         self.ems = {}
00345         sm = self.Model.smexterns
00346 
00347         def SetFlags(self):
00348             if self.IsLeaf():
00349                 self.DoneModes=True
00350             else:
00351                 self.DoneModes=False
00352                 SetFlags(self[0])
00353                 SetFlags(self[1])
00354 
00355         SetFlags(self)
00356             
00357         for l in self.AllLeaves():
00358             reac = str(l)
00359             l.ParModes={reac:
00360                         PartialMode(
00361                             sm.SubSys([reac]),
00362                             Irrev = sm.IsIrrev(reac),
00363                             Uses= [reac]
00364                         )
00365                     }
00366                            
00367         while not self.DoneModes:
00368             for lp in self.GetDoneParents():
00369                lp.CalcModes()
00370               
00371               
00372 
00373 
00374             
00375             
00376         
00377 
00378        
00379         
00380             
00381                 
00382         
00383         
00384 
00385 
00386     

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