/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 import os, logging 00002 from rst import TabularData, rst_title 00003 from scan import Scan 00004 from datetime import datetime 00005 00006 00007 __all__ = ('Scan', 'Vlut', ) 00008 log = logging.getLogger(__name__) 00009 00010 00011 class Vlut(list): 00012 def special_compare( cls, avs, bvs , nominalspec=None ): 00013 """ 00014 :param avs: `VlutSpec` instance 00015 :param bvs: `VlutSpec` instance 00016 :param nominalspec: a naming `VlutSpec` instance 00017 00018 Special case comparisons such as cross comparing different dbconf AND 00019 different option variations. 00020 """ 00021 spec = nominalspec if nominalspec else [avs,bvs] 00022 asc = Scan.get_or_create( avs ) 00023 bsc = Scan.get_or_create( bvs ) 00024 00025 csc = Scan.compare_( asc , bsc ) 00026 cvl = Vlut.create( csc , spec=spec ) 00027 cvl.write() 00028 return cvl 00029 special_compare = classmethod( special_compare ) 00030 00031 def get_or_create( cls, vs ): 00032 scan = Scan.get_or_create( vs ) 00033 vlut = Vlut.create( scan, spec=vs ) 00034 vlut.write() 00035 return vlut 00036 get_or_create = classmethod( get_or_create ) 00037 00038 def create( cls , scan , fn=lambda _:_['rvs'], spec=None ): 00039 """ 00040 Create validity look up table from a dbiscan 00041 """ 00042 00043 if not scan: 00044 log.fatal("undefined scan " ) 00045 raise Exception("Vlut.create undefined scan") 00046 00047 vlut = cls() 00048 alltimes = [] 00049 allseqno = [] 00050 ambipairs = [] 00051 00052 def insertdates_only(ik): 00053 """ 00054 Skip the _stat dict but cannot just pluck datetimes 00055 as in disparate comparison case labels are used inplace of insertdates 00056 """ 00057 if type(ik) == datetime: 00058 return True 00059 if ik.startswith('_'): 00060 return False 00061 return True 00062 00063 iks = sorted(filter(insertdates_only,scan.keys())) 00064 log.debug("Vlut.create %s " % iks ) 00065 00066 # rollback outer loop 00067 for insertdate in iks: 00068 lod = scan[insertdate] # list-of-dict with the TIMESTART results 00069 t = map(lambda d:d['t'], lod ) 00070 rvs = map(lambda d:d['rvs'], lod ) 00071 00072 alltimes.extend(t) 00073 allseqno.extend(rvs) 00074 00075 # converts lod into tabular data row dict 00076 thead = ["insertdate"] + map(str,t) 00077 tbody = [ insertdate ] + map(fn,lod ) 00078 vlut.append(dict(zip(thead,tbody))) 00079 pass 00080 00081 alltimes = sorted(list(set(alltimes))) 00082 vlut.alltimes = alltimes 00083 vlut.allseqno = sorted(list(set(allseqno))) 00084 vlut.order = ["insertdate"] + map(str,alltimes) 00085 vlut.ambipairs = ambipairs 00086 vlut.spec = spec 00087 vlut.scan = scan 00088 vlut.meta = vlut._meta() 00089 return vlut 00090 create = classmethod( create ) 00091 00092 def __init__(self): 00093 list.__init__(self) 00094 00095 stat = property(lambda self:self.scan.get('_stat',{})) 00096 ndif = property(lambda self:self.stat.get('ndif',-1)) 00097 00098 def _meta(self): 00099 meta = dict() 00100 meta['insertdates'] = len(self) 00101 meta['timestarts'] = len(self.order) 00102 meta['ndif'] = self.ndif 00103 return meta 00104 00105 def __str__(self): 00106 td = TabularData(self) ## tabulates a list of dicts with each row corresponding to each dict 00107 return td.as_rst(cols=self.order) 00108 00109 def extras(self, _vs=None ): 00110 if not _vs:_vs = self.spec 00111 vl = "" 00112 for pair in self.ambipairs: 00113 vl += rst_title(str(pair)) 00114 vl += ".. dbivld:: %s %s %s\n\n" % ( _vs.dbconf , _vs['tn'] , ",".join(map(str,pair)) ) 00115 vl += rst_title(str(self.allseqno)) 00116 vl += ".. dbivld:: %s %s %s\n\n" % ( _vs.dbconf , _vs['tn'], ",".join(map(str,self.allseqno)) ) 00117 return vl 00118 00119 def write(self, _vs=None): 00120 if not _vs: 00121 _vs = self.spec 00122 vs = _vs.copy(category='vlut') 00123 titl = vs.title_() 00124 mtitl = " ".join("%s:%s" % kv for kv in filter(lambda kv:not kv[0].startswith("_"),self.meta.items()) ) 00125 titl += " ``%s``" % mtitl 00126 path = vs.path 00127 if os.path.exists(path) and not vs.force: 00128 log.debug("skip prexisting %s " % path ) 00129 else: 00130 log.info("writing %s " % path ) 00131 with open(path,"w") as fp: 00132 fp.write(rst_title(titl)) 00133 fp.write(str(self)) 00134 if not vs.plain: 00135 fp.write(self.extras(vs)) 00136 return path 00137 00138 00139 if __name__ == '__main__': 00140 pass 00141 logging.basicConfig(level=logging.INFO) 00142 from vlutspec import VlutSpec 00143 vs = VlutSpec( dbconf="tmp_offline_db".split() , tn="HardwareID" , ctx=dict(aggno=-1, simflag=2, site=1, subsite=2, task=0 ), opts=dict(_rescan=True,_force=True) ) 00144 vlut = vs.make_vlut() 00145 log.info("vlut..\n%s\n" % vlut ) 00146 00147 00148