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

In This Package:

rpchv.py
Go to the documentation of this file.
00001 """
00002 RPC HV scraping specialization 
00003 """
00004 import os, logging
00005 log = logging.getLogger(__name__)
00006 from datetime import datetime, timedelta
00007 
00008 from base import Regime, Scraper, Faker, DCS, SourceContext
00009 from GaudiPython import gbl
00010 SiteFromString = gbl.Site.FromString
00011 
00012 class RpcHv(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     srcs    = property( lambda self:RpcHvSource( DCS(self['source']) ))
00019     scraper = property( lambda self:RpcHvScraper(self.srcs, self.target, self ))
00020     faker   = property( lambda self:RpcHvFaker(self.srcs,self ))
00021 
00022 
00023 
00024 class RpcHvSource(list):
00025     def __init__(self, srcdb):    
00026         """
00027         :param srcdb: source DB instance of :py:class:`Scraper.base.DCS` 
00028 
00029         List of source SA classes that map tables/joins in srcdb 
00030         Three sites for RPC HVs
00031         
00032         """
00033         dtn = SourceContext(table="DBNS_RPC_HV_Vmon",ksite="kDayaBay",ksubsite="kRPC")
00034         self.append(srcdb.kls(dtn) ) 
00035         dtn = SourceContext(table="LANS_RPC_HV_Vmon",ksite="kLingAo",ksubsite="kRPC")
00036         self.append(srcdb.kls(dtn) ) 
00037         dtn = SourceContext(table="FARS_RPC_HV_Vmon",ksite="kFar",ksubsite="kRPC")
00038         self.append(srcdb.kls(dtn) ) 
00039 
00040         
00041 class RpcHvScraper(Scraper):
00042 
00043     def changed(self, sv  ):
00044         """
00045         :param sv: source vector instance :py:class:`Scraper.base.sourcevector.SourceVector` 
00046 
00047         Decide if sufficient change to propagate based on differences between the first and last elements of `SourceVector` instance argument
00048         """
00049 
00050         p = self._detectordict( sv[0] )
00051         c = self._detectordict( sv[-1] )
00052         site = p.pop('site')
00053         det = p.pop('det')['det']
00054         for label in sorted(p.keys()):
00055             pv = p[label]
00056             cv = c[label]
00057             if abs(pv['voltage']-cv['voltage']) > self.threshold:
00058                 return True
00059         return False
00060 
00061     def propagate(self, sv ):
00062         """
00063         :param sv: source vector instance :py:class:`Scraper.base.sourcevector.SourceVector` 
00064 
00065         Yield write ready DybDbi target dicts to base class, note that a single source vector
00066         instance is yielding multiple target dicts. The keys of the target dict must match
00067         the specified attributes of the ``DybDbi`` target class. 
00068 
00069         Here the output is based entirely on the last element of the source vector. A smarter
00070         implementation might average the first and last to smooth variations.
00071         The python ``yield`` command makes it possible to iterate over a what is returned by 
00072         a function/method.
00073 
00074         ETW Aug 2012: write voltage from sv[0], NOT sv[-1]
00075         """
00076 
00077         dd = self._detectordict(sv[0])
00078         n = 0
00079         site = dd.pop('site')
00080         siteval = site['site'] 
00081         det = dd.pop('det')
00082         detval = det['det']
00083         ksite = self._getsite(siteval)
00084         detnum = 7
00085         for (label,sign),v in sorted(dd.items()):
00086             if (sign > 0):
00087                 vp = dd[label,1]
00088                 vn = dd[label,-1]
00089                 vpos = vp['voltage']
00090                 vneg = vn['voltage']
00091                 d = dict(LocationId=label,VoltagePos=vpos,VoltageNeg=vneg)
00092                 log.info("Writing out LocationId={}, VoltagePos={}, VoltageNeg={}".format(label,vpos,vneg))
00093                 n += 1
00094                 yield d
00095                 log.debug("yielded %s target dicts for  %s " % ( n, sv ))
00096 
00097 
00098     def seed(self, sc):
00099         """
00100         Used for seeding target DB when testing into empty tables
00101 
00102         :param sc: source class, potentially different seeds will be needed 
00103                    for each source that feeds into a single target
00104         """
00105 
00106         scstr = str(sc)
00107         
00108         if scstr.find("DBNS_RPC") > 0:
00109             return dict(LocationId="F00",VoltagePos=0,VoltageNeg=0)
00110         if scstr.find("LANS_RPC") > 0:
00111             return dict(LocationId="F00",VoltagePos=0,VoltageNeg=0)
00112         if scstr.find("FARS_RPC") > 0:
00113             return dict(LocationId="F00",VoltagePos=0,VoltageNeg=0)
00114 
00115     def _detectordict(self,inst):
00116         """
00117         :param inst: SQLAlchemy source instance
00118 
00119         Examines source instance, extracting detector name, DCS detector id, and values into a dict.
00120         """
00121 
00122         dd={}
00123         inststr = str(inst)
00124         sitestr = inststr[1:4]
00125         detstr = inststr[6:9]
00126         dd['site'] = {'site':sitestr}
00127         dd['det'] = {'det':detstr}
00128 
00129         for k,v in inst.asdict.items():
00130             if k in 'id date_time'.split():
00131                 continue
00132             if v is None:
00133                 v = -999
00134             sign = k.find("P")
00135             if (sign > 0):
00136                 kp = 1
00137             else:
00138                 kp = -1
00139             if (k[5] == 'F'):
00140                 kshort = k[5:6]+k[7:9]
00141             else:
00142                 kshort = 'T'+k[8:10]
00143             kk = (kshort,kp)
00144             qty,kk = ('voltage',kk)
00145             if dd.has_key(kk):
00146                 dd[kk].update({qty:v})
00147             else:
00148                 dd[kk] = {qty:v}
00149         return dd
00150 
00151     def _getsite(self,site):
00152         """
00153         Returns ksite number given string input
00154         """
00155 
00156         if site == 'DBN':
00157             return SiteFromString("DayaBay")
00158         elif site == 'LAN':
00159             return SiteFromString("LingAo")
00160         elif site == 'FAR':
00161             return SiteFromString("Far")
00162         else:
00163             msg = "Do not recognize site...must be DBNS, LANS, or FARS"
00164             log.fatal(msg)
00165             raise Exception(msg)
00166             return -1
00167 
00168 class RpcHvFaker(Faker):
00169     """
00170     Creates fake instances and inserts them into sourcedb   
00171     """
00172     def fake(self, inst, id , dt ):
00173         """
00174         Invoked from base class call method, 
00175         set attributes of source instance to form a fake 
00176 
00177         :param inst: source instance
00178         :param id: id to assign to the instance instance
00179         """
00180 #         fakefn=lambda (l,c,r),qty:l*100 + c*10 + r if qty == "voltage" else 1 
00181 #         for k,v in inst.asdict.items():
00182 #             if k in 'id P_id'.split():
00183 #                  setattr( inst, k, id )
00184 #             elif k in 'date_time P_date_time'.split():
00185 #                  setattr( inst, k, dt )
00186 #             else:
00187 #                 qty,kk = ('pw',k[2:]) if k.startswith('P_') else ('voltage',k)
00188 #                 lcr = self.lcr_matcher(kk)    
00189 #                 setattr( inst , k, fakefn( lcr, qty) )
00190 
00191 
00192 # if __name__ == '__main__':
00193 #     pass
00194 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 09:50:03 for Scraper by doxygen 1.7.4