00001 import Tags,Base
00002
00003 import sys
00004
00005
00006
00007 import OrderedList
00008
00009
00010 DefaultFile="compounds.dat"
00011
00012
00013 class Record(Base.Record):
00014 RecordClass="Compound"
00015 def __init__(self,id,**kwargs):
00016 Base.Record.__init__(self,id,**kwargs)
00017 self.EmpForm = {}
00018 self.Atoms = []
00019
00020 def NewTag(self,tag,val):
00021 if tag == Tags.ChemForm:
00022 self.__NewAtoms__(val)
00023 Base.Record.NewTag(self,tag,val)
00024
00025 def __NewAtoms__(self, val):
00026 AtomValue = val[1:-1].split()
00027 Atom = AtomValue[0]
00028 if len(AtomValue) > 1:
00029 self.EmpForm[Atom] = int(AtomValue[1])
00030 else:
00031 self.EmpForm[Atom] = 1
00032 self.Atoms.append(Atom)
00033
00034 def NumAtoms(self,atom):
00035 try:
00036 return self.EmpForm[atom]
00037 except:
00038 return 0
00039
00040
00041 def GetParents(self):
00042 " return reaction UIDs that produce or consume this compound "
00043
00044
00045
00046
00047 try:
00048 return self.Parents[:]
00049 except:
00050 assocs = self.Org.GetAssocs(self.UID)
00051 uids = []
00052 self.Parents = []
00053 for a in assocs:
00054 uid = a.UID
00055 if self.Org.WhereIs(uid) == "Reaction" and not uid in uids:
00056 self.Parents.append(a)
00057 uids.append(uid)
00058 return self.Parents[:]
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 class DB(Base.DB):
00069 def __init__(self, path=Base.DefaultPath, file=DefaultFile, RecClass=Record, **kwargs):
00070 Base.DB.__init__( self, path, file, RecClass=Record,**kwargs)
00071
00072 self.MassList = []
00073 self.MassDic = {}
00074
00075 for compound in self.values():
00076 if compound.has_key(Tags.MolWt):
00077 try:
00078 mw = float(compound[Tags.MolWt][0])
00079 except:
00080 print "! Bad MW, ", compound[Tags.MolWt], " for ", str(compound)
00081 mw = -1
00082 OrderedList.Insert(self.MassList, mw)
00083 if self.MassDic.has_key(mw):
00084 self.MassDic[mw].append(compound)
00085 else:
00086 self.MassDic[mw] = [compound]
00087
00088 def MWSearch(self, targ,lo,hi):
00089
00090 print targ,lo,hi
00091 res = self.InMassRange(targ+lo, targ+hi)
00092 print res
00093 return res
00094
00095 def NearestByMass(self, m):
00096 idx = OrderedList.FindNearest(self.MassList, m)
00097 return self.MassDic[self.MassList[idx]]
00098
00099 def InMassRange(self,lo,hi):
00100 if lo > hi: lo,hi = hi,lo
00101 lidx = OrderedList.FindNearest(self.MassList,lo)
00102 hidx = OrderedList.FindNearest(self.MassList,hi)
00103
00104 if self.MassList[hidx] > hi: hidx -= 1
00105 if self.MassList[lidx] < lo: lidx += 1
00106
00107 rv = []
00108 span = self.MassList[lidx:hidx+1]
00109 for i in span:
00110 rv += self.MassDic[i]
00111 return rv
00112
00113
00114 def AtomImbal(self, StoDic):
00115 """ NET atomic stochiometry described by the dictionary StoDic.
00116 Will try to handle bad names gracefully.
00117 rv is a dictionary unbalanced atoms to coeffs.
00118 """
00119
00120 rv = {}
00121
00122 for s in StoDic:
00123
00124 coeff = StoDic[s]
00125 if not self.has_key(s):
00126 empform = {"Unknown compound " +s:coeff}
00127 else:
00128 empform = self[s].EmpForm
00129 if empform == {}:
00130 empform = {"Unknown composition "+s:coeff}
00131
00132 for atom in empform:
00133 natoms = coeff * empform[atom]
00134 if rv.has_key(atom):
00135 rv[atom] += natoms
00136 else:
00137 rv[atom] = natoms
00138
00139
00140 for k in rv.keys():
00141 if rv[k] == 0:
00142 del rv[k]
00143
00144 return rv
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160