| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

OnlineOfflineTestRefactored.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 # Plot some stuff with MDR data - This is a refactoring of Dan's
00004 # DataQuality.OnlineOfflineTest.  Here, we make some "Histograms"
00005 # objects which handle booking and filling certain types of histograms
00006 # (per readout, per channel, channel summary).  Then the algorithm
00007 # code calls their one or more of their fill*() methods at the
00008 # appropriate time.  Each histogram object saves itself into a lookup
00009 # table held by the class in order to facilitate doing post
00010 # processing.  Instead of using the statistics service store as a
00011 # lookup for histograms by name, each Histograms object makes its
00012 # histograms available directly as data members.  This better
00013 # decouples I/O and memory.
00014 
00015 # This could be further refined to make a set of Histograms subclasses
00016 # that have well defined fill() semantics.  Then the user would not
00017 # have to look at so much code and just focus on implementing book()
00018 # and fill().
00019 
00020 # Module which makes Online/Offline Test Histograms
00021 #
00022 #  Usage:
00023 #   nuwa.py -n -1 OnlineOfflineTestRefactored daq_spliced.data
00024 
00025 # Load DybPython
00026 from DybPython.DybPythonAlg import DybPythonAlg
00027 from GaudiPython import SUCCESS, FAILURE
00028 from GaudiPython import gbl
00029 from DybPython.Util import irange
00030 import GaudiKernel.SystemOfUnits as units
00031 
00032 # Make shortcuts to any ROOT classes you want to use
00033 TH1F = gbl.TH1F
00034 TimeStamp = gbl.TimeStamp
00035 FeeChannelId = gbl.DayaBay.FeeChannelId
00036 Detector = gbl.DayaBay.Detector
00037 
00038 #change default ROOT style
00039 gbl.gStyle.SetHistLineColor(4)
00040 gbl.gStyle.SetHistLineWidth(2)
00041 gbl.gStyle.SetMarkerColor(4)
00042 gbl.gStyle.SetMarkerStyle(8)
00043 gbl.gStyle.SetPalette(1)
00044 
00045 def channel_index(chid):
00046     return chid.board()*16 + chid.connector()
00047 
00048 class Histograms(object):
00049     def __init__(self,alg,detector):
00050         self.alg = alg
00051         self.detector = Detector(detector.fullPackedData())
00052         return
00053 
00054     def _make_hist(self, name, title, nbins, vmin, vmax,xtitle=None,ytitle=None):
00055         'Make and return TH1F with given parameters'
00056         hist = TH1F(name,title,nbins,vmin,vmax)
00057         if xtitle: hist.GetXaxis().SetTitle(xtitle)
00058         if ytitle: hist.GetYaxis().SetTitle(ytitle)
00059         return hist
00060 
00061     def _place_hist(self, hist, path, member):
00062         '''Place hist in file and as data member.
00063         path is relative to /file1/detName/
00064         member is name to use for member
00065         '''
00066         path = "/file1/" + self.detector.detName() + "/" + path
00067         self.alg.stats[path] = hist
00068         self.__dict__[member] = hist
00069         return hist
00070 
00071     def hist(self, name, title, nbins, vmin, vmax,xtitle=None,ytitle=None):
00072         'Make and register a simple, top level, uniquely named histogram'
00073         hist = self._make_hist(name, title, nbins, vmin, vmax,xtitle,ytitle)
00074         return self._place_hist(hist,name,name)
00075 
00076     def container_hist(self, container, name, title, nbins, vmin, vmax,xtitle=None,ytitle=None):
00077         'Make and register a non-uniquely named histogram that lives in a container'
00078         hist = self._make_hist(name, title, nbins, vmin, vmax,xtitle,ytitle)
00079         return self._place_hist(hist,container+'/'+name,name,container)
00080 
00081     pass
00082 
00083 class PerChannelHistograms(Histograms):
00084 
00085     hists = {}
00086 
00087     def __init__(self,alg,detector,channelId):
00088         super(PerChannelHistograms,self).__init__(alg,detector)
00089         chanint = channelId.fullPackedData()
00090         self.chanint = chanint
00091         self.name = "board_%d_connector_%d" % (channelId.board(),
00092                                                channelId.connector())
00093         self._book()
00094         PerChannelHistograms.hists[chanint] = self
00095         alg.info('Making a PerChannelHistograms: %x'%chanint)
00096         return
00097 
00098     def hist(self, name, title, nbins, vmin, vmax,xtitle=None,ytitle=None):
00099         'Override to place at unique subdirectory in file'
00100         hist = self._make_hist(name, title, nbins, vmin, vmax,xtitle,ytitle)
00101         return self._place_hist(hist,self.name+'/'+name,name)
00102 
00103     def _book(self):
00104         # Prepare the empty histograms for this channel
00105 
00106         self.hist('tdc', "TDC Values", 4096,0,4096,
00107                   "TDC value","Number of TDCs")
00108         
00109         # ADC data by channel
00110         self.hist('adc', "ADC Values", 4096,0,4096,
00111                   "ADC value","Number of ADCs")
00112 
00113         return
00114 
00115     def fill(self,channel):
00116         for tdc in channel.tdc():
00117             self.tdc.Fill(tdc)
00118         for adcPair in channel.adc():
00119             #adcClock = adcPair.first
00120             adc = adcPair.second
00121             self.adc.Fill(adc)
00122         return
00123 
00124 class ChannelSummaryHistograms(Histograms):
00125 
00126     hists = {}
00127 
00128     def __init__(self,alg,detector):
00129         super(ChannelSummaryHistograms,self).__init__(alg,detector)
00130         self._book()
00131         ChannelSummaryHistograms.hists[detector.fullPackedData()] = self
00132         return
00133 
00134     def _book(self):
00135         # Summary Histograms
00136         # Mean ADC by channel
00137         self.hist("meanAdc", "Mean ADC by channel", 300,0,300,
00138                    "Channel Index (Board*16 + Connector)","Mean ADC value")
00139         
00140         # RMS ADC by channel
00141         self.hist("rmsAdc", "RMS ADC by channel (board*16 + connector)", 300,0,300,
00142                    "Channel Index (Board*16 + Connector)","RMS of ADC values")
00143         return
00144 
00145     def fill(self,chanint,adc):
00146         ci = float(channel_index(FeeChannelId(chanint)))
00147         self.alg.info('ChannelSummary: %f %f %f'%(ci,adc.GetMean(),adc.GetRMS()))
00148         self.meanAdc.Fill(ci,adc.GetMean())
00149         self.rmsAdc.Fill(ci,adc.GetRMS())
00150         return
00151     
00152     pass
00153 
00154 class PerReadoutHistograms(Histograms):
00155 
00156     hists = {}
00157 
00158     def __init__(self,alg,detector):
00159         super(PerReadoutHistograms,self).__init__(alg,detector)
00160         self.lastReadoutTime = None
00161         self._book()
00162         PerReadoutHistograms.hists[detector.fullPackedData()] = self
00163         return
00164 
00165     def _book(self):
00166         'Internal: book all histograms'
00167 
00168         # Number of hit channels in each readout
00169         self.hist("nChannels", "Number of Hit Channels", 250,0,250,
00170                    "Number of Hit Channels","Number of Triggered Readouts")
00171 
00172         # Number of Triggers by type
00173         self.hist("triggerType", "Trigger Type", 4096,0,4096,
00174                    "Trigger Type","Number of Triggered Readouts")
00175 
00176         # Time Between Triggered Readout
00177         self.hist("dT_trigger", "Time between triggers [s]", 1000,0,1,
00178                    "Time Between Triggered Readouts [s]","Number of Triggered Readouts / 1 ms")
00179         
00180         # Hit Rate by channel
00181         self.hist("hitRate", "Hit Rate by channel", 300,0,300,
00182                    "Channel Index (Board*16 + Connector)", "Number of Hits / Number of Triggered Readouts")
00183         return
00184 
00185     def fill_channelId(self,channelId):
00186         ci = channel_index(channelId)
00187         self.hitRate.Fill(ci)
00188 
00189     def fill_readout(self,readout):
00190         self.nChannels.Fill(len(readout.channelReadout()))
00191         self.triggerType.Fill(readout.triggerType())
00192 
00193         triggerTime = readout.triggerTime()
00194         if self.lastReadoutTime != None:
00195             dt = TimeStamp(triggerTime)
00196             dt.Subtract( self.lastReadoutTime )
00197             self.dT_trigger.Fill(dt.GetSeconds())
00198             pass
00199         self.lastReadoutTime = TimeStamp(triggerTime)
00200         return
00201 
00202     def norm(self):
00203         self.hitRate.Scale(1.0 / self.nChannels.GetEntries())
00204 
00205     pass
00206 
00207                             
00208 
00209 
00210 # Make your algorithm
00211 class OnlineOfflineAlg(DybPythonAlg):
00212     "Online/Offline Test Algorithm"
00213     def __init__(self,name):
00214         DybPythonAlg.__init__(self,name)
00215         self.eventnum = 0
00216         return
00217 
00218     def initialize(self):
00219         status = DybPythonAlg.initialize(self)
00220         if status.isFailure(): return status
00221         self.info("initializing")
00222         return SUCCESS
00223 
00224     def execute(self):
00225         self.eventnum += 1              # for debuggin
00226         self.debug("executing event %d"%self.eventnum)
00227         
00228         # Access current data
00229         evt = self.evtSvc()
00230         readoutHdr = evt["/Event/Readout/ReadoutHeader"]
00231         if readoutHdr == None:
00232             self.error("Failed to get current readout header")
00233             return FAILURE
00234 
00235         readout = readoutHdr.readout()
00236         if readout == None:
00237             self.error("Failed to get readout from header")
00238             return FAILURE
00239 
00240         detector = readout.detector()
00241         detint = detector.fullPackedData()
00242 
00243         # Fill per-detector hists
00244         try:
00245             prh = PerReadoutHistograms.hists[detint]
00246         except KeyError:
00247             prh = PerReadoutHistograms(self,detector)
00248         prh.fill_readout(readout)
00249 
00250 
00251         # Loop over channel data
00252         self.verbose('Event %d with %d channels'%(self.eventnum,len(readout.channelReadout())))
00253         for channelPair in readout.channelReadout():
00254             channel = channelPair.second
00255             channelId = channel.channelId()
00256             chanint = channelId.fullPackedData()
00257             try:
00258                 pch = PerChannelHistograms.hists[chanint]
00259             except KeyError:
00260                 pch = PerChannelHistograms(self,detector,channelId)
00261             pch.fill(channel)
00262             prh.fill_channelId(channelId)
00263             continue
00264 
00265         return SUCCESS
00266         
00267     def finalize(self):
00268         self.info("finalizing")
00269         # Fill summary histograms
00270         for id,pch in PerChannelHistograms.hists.iteritems():
00271             detint = pch.detector.fullPackedData()
00272             try:
00273                 csh = ChannelSummaryHistograms.hists[detint]
00274             except KeyError:
00275                 csh = ChannelSummaryHistograms(self,pch.detector)
00276 
00277             csh.fill(pch.chanint,pch.adc)
00278             continue
00279 
00280         for prh in PerReadoutHistograms.hists.itervalues():
00281             prh.norm()
00282             continue
00283 
00284         status = DybPythonAlg.finalize(self)
00285         return status
00286 
00287 
00288 #####  Job Configuration for nuwa.py ########################################
00289 
00290 def configure(argv=None):
00291     from StatisticsSvc.StatisticsSvcConf import StatisticsSvc
00292     statsSvc = StatisticsSvc()
00293     histfile = "onlineOfflineResult.root"
00294     if argv: histfile = argv[0]
00295     statsSvc.Output ={"file1":histfile}
00296     return
00297 
00298 def run(app):
00299     '''
00300     Configure and add an algorithm to job
00301     '''
00302     app.ExtSvc += ["StaticCableSvc", "StatisticsSvc"]
00303     myAlg = OnlineOfflineAlg("OnlineOfflineTestRefactored")
00304     app.addAlgorithm(myAlg)
00305     pass
00306 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:33:30 2011 for DataQuality by doxygen 1.4.7