/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 """ 00002 Muon Calibration scraping specialization 00003 """ 00004 import os, logging,time 00005 log = logging.getLogger(__name__) 00006 from datetime import datetime 00007 00008 from base import Regime, Scraper, Target, Faker, DCS, SourceContext 00009 from dcs import LCR,NSF 00010 00011 00012 class MuCalCopy(Regime): 00013 """ 00014 Regime frontend class with simple prescribed interface, 00015 takes the cfg argument into this dict and no args in call. 00016 This allows the frontend to be entirely generic. 00017 """ 00018 00019 srcs = property( lambda self:MuCalCopySource( DCS(self['source']) )) 00020 scraper = property( lambda self:MuCalCopyScraper(self.srcs, self.target, self )) 00021 faker = property( lambda self:MuCalCopyFaker(self.srcs,self )) 00022 00023 00024 00025 class MuCalCopySource(list): 00026 def __init__(self, srcdb): 00027 """ 00028 :param srcdb: source DB instance of :py:class:`Scraper.base.DCS` 00029 00030 List of source SA classes that map tables/joins in srcdb 00031 """ 00032 dtn = SourceContext(name="DBNS_MUCAL_IWS",table="DBNS_MUCAL",ksite="kDayaBay",ksubsite="kIWS") 00033 self.append( srcdb.kls(dtn) ) 00034 dtn = SourceContext(name="DBNS_MUCAL_OWS",table="DBNS_MUCAL",ksite="kDayaBay",ksubsite="kOWS") 00035 self.append( srcdb.kls(dtn) ) 00036 dtn = SourceContext(name="LANS_MUCAL_IWS",table="LANS_MUCAL",ksite="kLingAo",ksubsite="kIWS") 00037 self.append( srcdb.kls(dtn) ) 00038 dtn = SourceContext(name="LANS_MUCAL_OWS",table="LANS_MUCAL",ksite="kLingAo",ksubsite="kOWS") 00039 self.append( srcdb.kls(dtn) ) 00040 dtn = SourceContext(name="FARS_MUCAL_IWS",table="FARS_MUCAL",ksite="kFar",ksubsite="kIWS") 00041 self.append( srcdb.kls(dtn) ) 00042 dtn = SourceContext(name="FARS_MUCAL_OWS",table="FARS_MUCAL",ksite="kFar",ksubsite="kOWS") 00043 self.append( srcdb.kls(dtn) ) 00044 00045 class MuCalCopyScraper(Scraper): 00046 lcr_matcher = LCR() 00047 nsf_matcher = NSF() 00048 00049 def __call__(self): 00050 """ 00051 Spin the scrape infinite loop, sleeping at each pass. 00052 Within each pass loop over source vectors and check for propagate readyiness 00053 00054 Local copy to pick up local copy of output writer 00055 """ 00056 i,w = 0,0 00057 while i<self.maxiter or self.maxiter==0: 00058 i += 1 00059 log.debug("i %s " % i ) 00060 for sv in self: 00061 proceed = sv() 00062 if not proceed: 00063 continue 00064 00065 wrt = self.writer( sv ) 00066 #log.debug("wrt %r " % wrt ) 00067 00068 for td in self.propagate( sv ): ## iterate over "yield" supplier of target dicts 00069 log.debug("td %r " % td ) 00070 tdi = self.target.instance(**td) ## may fail with type errors 00071 log.debug("tdi %r " % tdi ) 00072 wrt.Write(tdi) ## RuntimeError basic_string::_S_construct NULL not valid (C++ exception) here 00073 00074 if wrt.Close(): ## hits target DB here 00075 log.debug("write %s succeeded %s " % ( w, sv) ) 00076 timeend = wrt.ctx.contextrange.timeend ## UTC TimeStamp 00077 sv.tcursor = timeend.UTCtoNaiveLocalDatetime + self.interval 00078 self.tunesleep(w) 00079 w += 1 00080 else: 00081 log.fatal("writing failed %s " % sv ) 00082 assert 0 00083 self.handle_signal() 00084 time.sleep(self.sleep.seconds) ## uncomfortable with common sleep here ... 00085 pass 00086 00087 00088 def changed(self, sv ): 00089 """ 00090 Always copy new entries, but only IWS/OWS for IWS/OWS valididy 00091 """ 00092 inststr= str(sv[-1]) 00093 for k,v in sv[-1].asdict.items(): 00094 if k == 'IOW_CAL_LED_ID': 00095 ledid=v 00096 checkpool = int((ledid - 10000*int(ledid/10000))/1000) 00097 if ((checkpool == 0) and (inststr.find("OWS") > 0)): 00098 return True 00099 elif ((checkpool != 0) and (inststr.find("IWS") > 0)): 00100 return True 00101 else: 00102 return False 00103 00104 def propagate(self, sv ): 00105 """ 00106 Copy values directly from sourcevector 00107 """ 00108 00109 for k,v in sv[-1].asdict.items(): 00110 if k == 'IOW_CAL_LED_ID': 00111 ledid=v 00112 if k == 'IOW_CAL_LED_ID_Voltage': 00113 voltage=v 00114 if k == 'IOW_CAL_LED_ID_Frequency': 00115 frequency=v 00116 if k == 'IOW_CAL_Channel_ID': 00117 chanid=v 00118 if k == 'IOW_CAL_ErrorCode': 00119 error=v 00120 d = dict(LedId=ledid,Voltage=voltage,Frequency=frequency,ChannelId=chanid,ErrorCode=error) 00121 yield d 00122 00123 def seed(self, sc): 00124 """ 00125 Used for seeding target DB when testing into empty tables 00126 00127 :param sc: source class, potentially different seeds will be needed 00128 for each source that feeds into a single target 00129 """ 00130 return dict(LedId=1,Voltage=0.0,Frequency=0.0,ChannelId=1,ErrorCode=0) 00131 00132 def writer(self, sv , localstart=None, localend=None ): 00133 """ 00134 Prepare DybDbi writer for target class, with contextrange/subsite appropriate for the source instance 00135 00136 Local copy for writing MuCal table - want the validity to be based on the LED 00137 start and stop times from the DCS table 00138 00139 :param sv: source vector instance that contains instances of an SA mapped class 00140 :param localstart: default of `None` corresponds to `sv[0].date_time` 00141 :param localend: default of `None` corresponds to `sv[-1].date_time` 00142 """ 00143 00144 for k,v in sv[-1].asdict.items(): 00145 if k == 'IOW_CAL_LED_ID_timestamp_begin': 00146 start=v 00147 if k == 'IOW_CAL_LED_ID_timestamp_end': 00148 end=v 00149 00150 return Target._wrt( sv[0].__class__ , self.target.kls , start, end ) 00151 00152 class MuCalCopyFaker(Faker): 00153 """ 00154 Creates fake instances and inserts them into sourcedb 00155 """ 00156 lcr_matcher = LCR() 00157 def fake(self, inst, id , dt ): 00158 """ 00159 Invoked from base class call method, 00160 set attributes of source instance to form a fake 00161 00162 :param inst: source instance 00163 :param id: id to assign to the instance instance 00164 """ 00165 fakefn=lambda (l,c,r),qty:l*100 + c*10 + r if qty == "voltage" else 1 00166 for k,v in inst.asdict.items(): 00167 if k in 'id P_id'.split(): 00168 setattr( inst, k, id ) 00169 elif k in 'date_time P_date_time'.split(): 00170 setattr( inst, k, dt ) 00171 else: 00172 qty,kk = ('pw',k[2:]) if k.startswith('P_') else ('voltage',k) 00173 lcr = self.lcr_matcher(kk) 00174 setattr( inst , k, fakefn( lcr, qty) ) 00175 00176 00177 if __name__ == '__main__': 00178 pass 00179