/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

vrb.py
Go to the documentation of this file.
00001 #!/usr/bin/env python 
00002 """
00003 For debugging::
00004 
00005    ipython vrb.py 
00006 
00007 """
00008 
00009 import os, logging
00010 from pprint import pformat
00011 log = logging.getLogger(__name__)
00012 
00013 def parse_cfg( val ):
00014     """
00015     Parse config like the below into dict:: 
00016 
00017         [mig20120820]
00018         src = GCalibPmtHighGainPariah -1 27877 6533
00019         tgt = GCalibPmtFineGain 1 1410 6533
00020 
00021     """
00022     bits = val.split(' ') ; assert len(bits) == 4, "unexpected fields in value %s %s " % (repr(bits), val)
00023     return dict(kln=bits[0],task=int(bits[1]),offseq=int(bits[2]),count=int(bits[3]))
00024 
00025 
00026 class CFConf(dict):
00027     """
00028     Usage::
00029 
00030           from tools impoty CFConf
00031           def handler( val ):
00032               return dict()
00033           cfc = CFConf("offsets.cfg", "mig20120820", handler ) 
00034 
00035     The handler parses the config value and returns a dict  
00036 
00037     """
00038     def __init__(self, path, section , parse_cfg_ = lambda _:{} ):
00039         dict.__init__(self)
00040         from ConfigParser import ConfigParser
00041         cfp = ConfigParser()
00042         cfp.optionxform = str   ## avoid lowercasing keys, making the keys case sensitive
00043         path = os.path.expandvars(os.path.expanduser(path))
00044         cfp.read(path) 
00045         assert cfp.has_section(section), "section %s not present in config file %s " % ( section, path)
00046         for key, val in cfp.items(section):
00047             self[key] = parse_cfg_( val )
00048 
00049     def __repr__(self):
00050         return pformat(dict(self))
00051 
00052 
00053 
00054 def pydigest_( rpt , first=0 ):
00055     """
00056     :param first: index of first column to include in digest
00057           
00058     The default `first=0` duplicates the C++ `rpt.digest`. 
00059     The python version can in addition restrict the comparison to ignore columns.
00060  
00061     The vals are strings like::
00062  
00063         67241993 20.937 0.203 6.333 0.94
00064         67241994 18.892 0.146 5.217 1.03
00065 
00066     Thus using a `first=1` allows digest content 
00067     comparisons between tables using sensorid and channelid keys 
00068  
00069     """
00070     from ROOT import TMD5   
00071     md5 = TMD5()
00072     for i,r in enumerate(rpt):
00073         vals = " ".join(r.values.split(" ")[first:])
00074         if i == 0:
00075             log.debug(vals) 
00076         md5.Update(vals, len(vals))
00077     md5.Final()
00078     return md5.AsString()
00079 
00080 
00081 class CompareVrb(dict):
00082     def __init__(self, **kwa):
00083         dict.__init__(self, **kwa)
00084 
00085     def __call__(self):
00086         rpt = {}
00087         ldict = {}
00088         for tag, vrb in self.items():
00089             ldict[tag] = len(vrb)
00090             rpt[tag] = vrb.kls.Rpt().Clone()
00091         self.rpt = rpt
00092 
00093         lset = list(set(ldict.values()))   # uniquing by passing thru the set
00094         assert len(lset) == 1, ("all argument vrb required to have the same length", ldict )
00095         self.length = lset[0]
00096 
00097     def check_payload(self, first=0, check=None):
00098         """
00099         SEQNO by SEQNO comparisons of digests between tables
00100 
00101         :param first: column index to start the digest from, 1 to skip first column, 0 to include all
00102         :param check: function that accepts single arguement, the single seqno dict 
00103 
00104         C++ digests `rpt.digest` are constructed from all values in the payloads allowing 
00105         a quick way to check payload correspondence between multiple tables
00106         """
00107         for i in range(self.length):
00108             d = dict(index=i) 
00109             for tag,vrb in self.items():
00110                 vrec = vrb.offseq_(i)
00111                 self.rpt[tag].ctx( validityrec=vrec ) 
00112                 d[tag] = dict(seqno=vrec.seqno,digest=self.rpt[tag].digest,pydigest=pydigest_(self.rpt[tag], first=first))
00113             tags = self.keys()
00114             for tag in tags[1:]:
00115                 assert d[tags[0]]['pydigest'] == d[tag]['pydigest'], ("pydigest mismatch", d )
00116             if check:
00117                 check(d)
00118 
00119     def check_validity(self, check=None ):
00120         """
00121         SEQNO by SEQNO comparisons of validity fields between tables
00122         """
00123         pass
00124         for i in range(self.length):
00125             v = dict(index=i)
00126             for tag,vrb in self.items():
00127                 vrec = vrb.offseq_(i)
00128                 for qwn in Vrec.qwns:
00129                     if qwn not in v:
00130                         v[qwn] = {}
00131                     qbit = qwn.split(".")
00132                     if len(qbit) == 2: 
00133                         g_ = lambda vrec:getattr(getattr(vrec,qbit[0]),qbit[1]) 
00134                     else:
00135                         g_ = lambda vrec:getattr(vrec,qwn)
00136                     v[qwn][tag] = g_(vrec) 
00137                 pass
00138             if check:
00139                 check(v)
00140 
00141 
00142 
00143 
00144 class Vrec(object):
00145    qwns = "contextrange.timestart contextrange.timeend contextrange.sitemask contextrange.simmask subsite task aggregateno versiondate".split()
00146    def __init__(self, vrec ):
00147         self.vrec = vrec
00148 
00149    def vdict(self):
00150        v = {}
00151        for qwn in self.qwns:
00152            qbit = qwn.split(".")
00153            g_ = lambda vrec:getattr(getattr(vrec,qbit[0]),qbit[1]) if len(qbit) == 2 else lambda vrec:getattr(vrec,qwn)
00154            v[qwn] = g_(self.vrec) 
00155        return v
00156 
00157 
00158 class Vrb(object):
00159     def __init__(self, kls, task=-1, offseq=0, sqlcontext="1=1", subsite=-1 ):
00160         """
00161         :param kls:
00162         :param task:
00163         :param offseq:  seqno offset, used by offseq_ for comparison between tables with shifted SEQNO 
00164         """
00165         self.vrb = kls.GetTableProxy().MakeValidityRecBuilder( sqlcontext, subsite, task )
00166         self.seqnos = map(lambda _:_.seqno, self.vrb)
00167         self.seqnos.sort()
00168         self.kls = kls
00169         self.offseq = offseq
00170         self.cursor = 0
00171 
00172 
00173     def __len__(self):
00174         return len(self.vrb)
00175 
00176     def __getitem__(self, rowNo ):
00177         """
00178         List access with square brackets queries by rowNo. 
00179         But the ordering appears to make no sense, so not very useful. 
00180         """
00181         return self.vrb.__getitem__(rowNo)
00182 
00183     def offseq_( self, count ):
00184         return self( self.offseq + count + 1 ) 
00185 
00186     def __call__(self, seqno):
00187         """
00188         Call access with round brackets queries by SEQNO
00189 
00190         :param seqno:
00191         """
00192         return self.vrb.GetValidityRecFromSeqNo(seqno)
00193 
00194     def purge(self):
00195         self.kls.GetTableProxy().GetCache().Purge()
00196 
00197     def __iter__(self):
00198         return self
00199 
00200     def next(self):
00201         """
00202         Adds iterability to the Vrb providing (seqno, vrec) tuples 
00203         """ 
00204         if self.cursor >= len(self.seqnos) or self.cursor < 0:
00205              raise StopIteration
00206         else:
00207              seqno = self.seqnos[self.cursor]
00208              vrec = self(seqno)
00209              assert seqno == vrec.seqno, ("seqno vrec.seqno mismatch", seqno, vrec.seqno)
00210              self.cursor += 1
00211              return ( seqno, vrec )
00212 
00213     def replace_insertdate( self, ts=None, seqnos=[], dbno=0 ):
00214         """
00215         The functionality of changeing INSERTDATES is not for general use. 
00216         It is intended for special purpose usage only, as INSERTDATEs are subsequently 
00217         fastforwarded to real times anyhow as part of the Standard Operation Procedures.
00218         """
00219         nrep = 0 
00220         if not ts:
00221             ts = TimeStamp()
00222         tbProxy = self.kls.GetTableProxy()
00223         dbProxy = tbProxy.GetDBProxy()
00224         for seqno,vrec in self:
00225             if len(seqnos) == 0 or seqno in seqnos: 
00226                 print "%-4s %s %s " % ( seqno, vrec.insertdate, ts )
00227                 dbProxy.ReplaceInsertDate( ts, seqno, dbno ) 
00228                 nrep +=1
00229         return nrep
00230 
00231 
00232 
00233 if __name__ == '__main__':
00234     os.environ.setdefault('DBCONF','tmp_offline_db')
00235     cfconf = 'test'
00236     cfc = CFConf("cfconf.cfg",cfconf, parse_cfg )
00237 
00238     import DybDbi
00239     DybDbi.gDbi.level = "WARNING"
00240 
00241     cv = CompareVrb()
00242     for k, d in cfc.items():
00243         kls = getattr(DybDbi, d['kln'] )
00244         vrb = Vrb(kls, d['task'], offseq=d['offseq'] )
00245         assert len(vrb) == d['count'], ("unexpected length", d, vrb ) 
00246         cv[k] = vrb
00247     cv()
00248 
00249     vrb = cv['tgt']
00250     vrec = vrb.offseq_(0)
00251     vrec_ = Vrec(vrec)
00252     print vrec_.vdict() 
00253 
00254 
00255 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 09:57:24 for DybDbi by doxygen 1.7.4