Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

hTestAppEvt.py

00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2002
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 
00010 __facility__ = "Online"
00011 __abstract__ = "Example TKR test application"
00012 __author__   = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = ("$Date: 2005/03/31 02:55:06 $").split(' ')[1]
00014 __version__  = "$Revision: 1.6 $"
00015 __release__  = "$Name: R04-12-00 $"
00016 __credits__  = "SLAC"
00017 
00018 import LATTE.copyright_SLAC
00019 
00020 
00021 import threading
00022 import sys
00023 
00024 from   LATTE.runcontrol.rcTransitions import rcTransitions
00025 from   LATTE.runcontrol.ArgumentImpl  import ArgumentImpl
00026 
00027 from   sihippo       import *
00028 import logging       as     log
00029 import                      time
00030 
00031 import LDF
00032 
00033 from support.SimpleGasuExample   import *
00034 from support.MiniGLTExample      import *
00035 
00036 
00037 def _unsigned(arg):
00038   """\brief Convert an unsigned int argument to an unsigned long
00039 
00040   This funtion exists to help format unsigned ints greater than 0x7fffffff,
00041   which in Python 2.4 and up will be displayed as signed strings.
00042   """
00043   return arg & (2L * sys.maxint + 1)
00044 
00045 
00046 class myTKRcontributionIterator(LDF.TKRcontributionIterator):
00047   def __init__(self, hists):
00048     LDF.TKRcontributionIterator.__init__(self)
00049     self.__hists = hists
00050 
00051   def strip(self, tower, layerEnd, hit):
00052     self.__hists[0].addRow([hit])
00053 
00054   def TOT(self, tower, layerEnd, tot):
00055     self.__hists[1].addRow([tot])
00056 
00057 class myLATcomponentIterator(LDF.LATcomponentIterator):
00058   def __init__(self, hists):
00059     LDF.LATcomponentIterator.__init__(self)
00060     self.__tkrIterator = myTKRcontributionIterator(hists)
00061 
00062   def CALcomponent(self, event, calContribution):
00063     return 0
00064 
00065   def TKRcomponent(self, event, contribution):
00066     self.__tkrIterator.iterateStrips(event, contribution)
00067     self.__tkrIterator.iterateTOTs(contribution)
00068 
00069     return 0
00070 
00071 
00072 #  This class puts up a GUI for inputting a value of some sort.  It is used by
00073 #  the userApplication example to get the number of self triggers to take.
00074 class userArgument(ArgumentImpl):
00075   "GUI for getting the user to input some sort of value."
00076   def __init__(self, parent = None, name = None, modal = 0, fl = 0):
00077     ArgumentImpl.__init__(self, parent, name, modal, fl)
00078     self.__value = 0
00079     self.setCaption("Hello world!")
00080 
00081   def OKButtonClicked(self):
00082     self.__value = int(self.ArgumentList.text().latin1())
00083     self.close()
00084 
00085   def getValue(self, caption):
00086     self.setCaption(caption)
00087     self.show()
00088     self.exec_loop()
00089     return self.__value
00090 
00091 class userArgText(object):
00092   "Text user interface for getting the user to input some sort of value"
00093   def __init__(self):
00094     pass
00095 
00096   def getValue(self, caption):
00097     return int(raw_input("%s: " % (caption)))
00098 
00099 
00100 #  Example application implementation.
00101 #  Note that the name of the class must be userApplication.
00102 #  Look at rcTransitions for names of other transition methods that can be used.
00103 class userApplication(rcTransitions):
00104   "Implmentation class for a user application"
00105   def __init__(self, gui, userId, debug):
00106     rcTransitions.__init__(self, gui, userId, debug)
00107     print "userApplication.__init__()"
00108     self.__eventSem    = threading.Semaphore(0)
00109     self.__cmdSynchSem = threading.Semaphore(0)
00110 
00111     self.gui.execGUImethod(self.__initHippo)
00112 
00113     self.__lci         = myLATcomponentIterator(self.__hists)
00114     self.__ldbi        = LDF.LATdataBufferIterator(self.__lci)
00115 
00116 
00117   def getName(self):
00118     return "hTestAppEvt"
00119 
00120   def setup(self):
00121     print "userApplication.setup()"
00122 
00123     if self.rc is None:
00124       self.__arg = userArgText()
00125     else:
00126       self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1)
00127 
00128     # Get a TEM instance
00129     if self.lat.TEMcnt() == 1:
00130       tem = self.lat.TEM[self.lat.TEM.keys()[0]]
00131     elif self.lat.TEMcnt() > 1:
00132       tem = self.lat.TEM.all()
00133     else:
00134       log.fatal("No TEM(s) found in the schema")
00135       return -1
00136 
00137     tcc = tem.allTCC()
00138 
00139     #
00140     # Configure GTRCs
00141     #
00142 
00143     # our board is connected CC = 2, RC = 0 and CC = 3, RC = 0
00144     # reset GTRC # required before all triggers
00145 
00146     trc = tcc.allTRC()
00147 
00148     trc.CMD_RESET = 1
00149 
00150     # number of GTFE to readout left
00151     nGTFEsLeft  = 7
00152     nGTFEsRight = 0
00153 
00154     # max hits per GTRC # 31 max
00155     maxHits = 31
00156 
00157     enMask  = 0x6
00158 
00159     dLO = (enMask << 28) | ((nGTFEsRight << 7)& 0xF80) | (maxHits & 0x7F);
00160     print "dLO=", dLO, hex(dLO)
00161 
00162     # cable controller 2, readout controller 0
00163     tcc = tem.downTCC(2)
00164     trc = tcc.downTRC(1)
00165 
00166     trc.CSR = dLO
00167 
00168     dLO = (enMask << 28) | ((nGTFEsLeft << 7)& 0xF80) | (maxHits & 0x7F);
00169     print "dLO=", dLO, hex(dLO)
00170 
00171     # cable controller 3, readout controller 0
00172     tcc = tem.downTCC(3)
00173     trc = tcc.downTRC(1)
00174 
00175     trc.CSR = dLO
00176 
00177     #
00178     # Configure GTFEs
00179     #
00180 
00181     tfe = trc.allTFE()
00182     tfe.TRIG_MASK = 0x0
00183     tfe.DATA_MASK = 0x0
00184     tfe.CALIB_MASK = 0x0
00185     tfe.DAC = 0x00001902
00186     # configure front ends # all listen to left
00187     tfe.MODE = 0
00188     #tfe = trc.downTFE(0)
00189 
00190     # configure default DACs for threshold and calibration
00191     # Calibration DAC Range and Resolution
00192     # Low Range (B6=0):  DAC output voltage in mV = 1.57 + 1.53*DAC_Value
00193     # High Range (B6=1): DAC output voltage in mV = 15.0 + 14.6*DAC_Value
00194     # Discriminator Threshold DAC Range and Resolution
00195     # Low Range (B6=0):  DAC output voltage in mV = 4.5 + 4.5*DAC_Value
00196     # High Range (B6=1): DAC output voltage in mV = 12.9 + 12.9*DAC_Value
00197 
00198 
00199     # calRng = 1
00200     # thrRng = 0
00201     # calDAC = 60
00202     # thrDAC = 10
00203 
00204     tfe.DAC = 0x00001952  # based on the above Rng and DAC values
00205 
00206     # enable GTFE for data taking # all channels
00207     tfe.TRIG_MASK = 0xffffffffffffffff
00208     tfe.DATA_MASK = 0xffffffffffffffff
00209 
00210     # Cal strobe channels 4 and 48 only
00211     tfe.CALIB_MASK = 0x0001000000000010
00212 
00213     #~ #Mask of the following Registers
00214     #~ tfe = trc.downTFE(13)
00215     #~ tfe.DATA_MASK = 0x0L
00216     #~ tfe.CALIB_MASK = 0x0L
00217     #~ tfe.TRIG_MASK = 0x0L
00218 
00219     #~ tfe = trc.downTFE(14)
00220     #~ tfe.DATA_MASK = 0x0L
00221     #~ tfe.CALIB_MASK = 0x0L
00222     #~ tfe.TRIG_MASK = 0x0L
00223 
00224     #~ tfe = trc.downTFE(19)
00225     #~ #tfe.DATA_MASK = 0x0L
00226     #~ tfe.CALIB_MASK = 0x0L
00227     #~ tfe.TRIG_MASK = 0x0L
00228 
00229     #~ tfe = trc.downTFE(20)
00230     #~ #tfe.DATA_MASK = 0x0L
00231     #~ tfe.CALIB_MASK = 0x0L
00232     #~ tfe.TRIG_MASK = 0x0L
00233 
00234     # Two choices for the trigger, GEM and MiniGLT
00235     if self.lat.existsGEM():
00236       self.trigger( SimpleGasuExample() )
00237     else:
00238       self.trigger( MiniGLTExample() )
00239 
00240     # A state transition can be rejected by not returning None
00241     return None
00242 
00243   def startRun(self):
00244     log.debug("userApplication.startRun()")
00245 
00246     caption = "Enter number of triggers to take"
00247     if self.gui is None:
00248       cnt = self.__arg.getValue(caption)
00249     else:
00250       cnt = self.gui.execGUImethod(self.__arg.getValue, caption)
00251       # Allow the C++ object to be deleted
00252       self.__arg.deleteLater()
00253 
00254     # The user pressed 'Cancel'
00255     if cnt is None:  return -1
00256     self.__cnt = cnt
00257 
00258     self.gui.execGUImethod(self.__initPlots)
00259     self.__cmdSynchQuit = False
00260 
00261     # A state transition can be rejected by not returning None
00262     return None
00263 
00264   def stopRun(self):
00265     self.setCompletionStatus(self.COMPL_STATUS_SUCCESS)
00266     self.__cmdSynchQuit = True
00267     self.__eventSem.release()
00268 
00269     # The STOP_RUN transition can not be rejected
00270 
00271   def resume(self):
00272     # Issue self trigger to make up for the one that was lost during PAUSE
00273     self.trigger().solicit()
00274 
00275     return None
00276 
00277   def stop (self):
00278     return self.stopRun()
00279 
00280   def process(self, (status, buffer)):
00281     "Method called back for each data event taken"
00282     ##log.debug("userApplication.process()")
00283 
00284     evtCli = self.evtCli
00285 
00286     if status != 0:
00287       if evtCli.isGGLTStatus():
00288         log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr()))
00289       elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR):
00290         log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr()))
00291       self.__eventSem.release()
00292       return
00293     try:
00294       # In the future this event may contain additional data
00295       if evtCli.isSweepEvent(): return
00296     except:
00297       # Event summary word inaccessible, handle the bad event here
00298       log.exception("")
00299       return
00300 
00301     self.__ldbi.iterate(buffer, len(buffer))
00302 
00303     self.__hists[2].addRow([evtCli.getEvtSize()])  #event.length()])
00304 
00305     # Get next event triggered
00306     self.__eventSem.release()
00307 
00308 
00309   def commandSynch(self):
00310     "Method called by the command synchronization task"
00311     trigger  = self.trigger()
00312     eventSem = self.__eventSem
00313     t0  = time.time()
00314     cnt = 0
00315     count = self.__cnt
00316 
00317     # Wait for START_RUN to enable triggers
00318     trigger.waitForMaskEnable()
00319 
00320     while cnt < count and not self.__cmdSynchQuit:
00321       cnt = cnt + 1
00322       trigger.solicit()                 # Issue an internal trigger
00323       eventSem.acquire()                # Wait for the event to be processed
00324       time.sleep(.001)
00325 
00326     wc = WindowController.instance()
00327     canvas = wc.currentCanvas()
00328     canvas.setIntervalEnabled ( 0 )
00329     dT = time.time() - t0
00330     if dT == 0.0:  dT = 0.000001
00331     print "%s processed %d events in %.3f seconds = %.1f events/second" % \
00332           (self.getName(), cnt, dT, self.evtCnt/dT)
00333 
00334     # Get out of waiting when in suite or standalone mode
00335     self.sync()
00336 
00337     # execute the GUI functions for stopRun, just in case
00338     if not self.__cmdSynchQuit and not self.isRunFromSuite():
00339       if self.rc is not None:
00340         self.rc.doStop()
00341 
00342   def wait(self):
00343     self.__cmdSynchSem.acquire()
00344 
00345   def sync(self):
00346     if __name__ == "__main__" or self.isRunFromSuite():
00347       self.__cmdSynchSem.release()
00348 
00349   def __initHippo(self):
00350     self.__label  = [0, 0, 0]
00351     self.__label[0] = ['Strip Hits']
00352     self.__label[1] = ['TOTs']
00353     self.__label[2] = ['Event Size']
00354     ntc = NTupleController.instance()
00355     self.__hists  = [0, 0, 0]
00356     self.__hists[0] = ntc.createNTuple(1)
00357     self.__hists[1] = ntc.createNTuple(1)
00358     self.__hists[2] = ntc.createNTuple(1)
00359     self.__hists[0].setTitle('TKR Event Strip Readout')
00360     self.__hists[1].setTitle('TKR Event TOT Readout')
00361     self.__hists[2].setTitle('Event length')
00362     self.__hists[0].setLabels(self.__label[0])
00363     self.__hists[1].setLabels(self.__label[1])
00364     self.__hists[2].setLabels(self.__label[2])
00365     if __name__ == "__main__":
00366 ##       app = HDApp()
00367 ##       canvas = app.canvas()
00368       app = QApplication ( sys.argv )
00369       canvas = CanvasWindow()
00370       canvas.show()
00371     else:
00372       wc = WindowController.instance()
00373       canvas = wc.currentCanvas()
00374 ##  already done by main applicaton:    canvas.show()
00375 ##     ntuple_list = [0.0]
00376 ##     self.__nt.addRow(ntuple_list)
00377 ##    self.__nt2.addRow(ntuple_list)
00378 
00379 ## see new way below
00380 ##     hist = Display('Histogram',self.__nt,'Strip Hits')
00381 ##     hist2 = Display('Histogram',self.__nt2,'Event
00382 
00383   def __initPlots(self):
00384     wc = WindowController.instance()
00385     canvas = wc.currentCanvas()
00386     canvas.clear()
00387     self.__hists[0].clear()
00388     self.__hists[1].clear()
00389     self.__hists[2].clear()
00390     dc = DisplayController.instance()
00391     hist1 = dc.createDisplay ( 'Histogram', self.__hists[0], self.__label[0] )
00392     hist2 = dc.createDisplay ( 'Histogram', self.__hists[1], self.__label[1] )
00393     hist3 = dc.createDisplay ( 'Histogram', self.__hists[2], self.__label[2] )
00394     canvas.addDisplay(hist1)
00395     canvas.addDisplay(hist2)
00396     canvas.addDisplay(hist3)
00397     self.__hists[0].setIntervalCount ( 2000 )
00398     self.__hists[1].setIntervalCount ( 1000 )
00399     self.__hists[2].setIntervalCount ( 400 )
00400     canvas.setIntervalEnabled ( 0 )
00401     canvas.show()
00402     canvas.setIntervalEnabled ( 1 )
00403 
00404 #Standalone mode:
00405 if __name__ == "__main__":
00406   import sys
00407   from qt import *
00408   from sihippo import *
00409 
00410   ua = userApplication(None, 321, 0)
00411   ua.rcSetup('../repos/simpleTemSchema.xml')
00412   ua.rcStartRun()
00413   ua.wait()
00414   ua.rcStopRun()
00415   ua.rcTeardown()
00416   raw_input("Press any key to end")
00417 
00418 # History:
00419 #     $Log: hTestAppEvt.py,v $
00420 #     Revision 1.6  2005/03/31 02:55:06  stuvi
00421 #     Fixed TRCs according to Selim's teststand.
00422 #
00423 #     Revision 1.5  2005/03/30 06:04:33  stuvi
00424 #     Removed configuration settings which should normally come from the schema.
00425 #
00426 #     Revision 1.4  2005/03/21 17:58:11  claus
00427 #     Modified to use the first TEM found in the schema, if only one is there, or
00428 #     broadcast to all TEMs if there are multiple.
00429 #
00430 #     Revision 1.3  2004/10/22 20:32:48  stuvi
00431 #     Fixed log.exception()
00432 #
00433 #     Revision 1.2  2004/08/18 18:00:15  stuvi
00434 #     Updated for LATTE 4.
00435 #     All hippo functions go through the Qt GUI bridge now.
00436 #
00437 #     Revision 1.1  2004/08/07 02:14:33  stuvi
00438 #     no message
00439 #
00440 #     Revision 1.8  2004/07/15 22:58:35  stuvi
00441 #     Added waitForMaskEnable
00442 #
00443 #     Revision 1.7  2004/05/03 21:19:46  stuvi
00444 #     Moved non-Runcontrol scripts to the support directory and modified imports accordingly.
00445 #
00446 #     Revision 1.6  2004/04/17 02:22:17  stuvi
00447 #     Various Hippo related fixes
00448 #     Added teardown() to delete the C++ object for the userArgument
00449 #
00450 #     Revision 1.5  2004/04/08 03:16:44  stuvi
00451 #     Added canvas clearing.
00452 #
00453 #     Revision 1.4  2004/04/08 01:48:42  claus
00454 #     Reworked to work with LDF.
00455 #
00456 #     Revision 1.3  2004/04/07 22:20:51  stuvi
00457 #     no message
00458 #
00459 #     Revision 1.2  2004/03/10 22:24:50  panetta
00460 #     Upgraded trigger interface.
00461 #     Removed dependencies on self.glt.
00462 #
00463 #     Revision 1.1  2004/01/30 04:39:53  claus
00464 #     Test application to histogram data from EBF events.
00465 #     This is not yet working.
00466 #
00467 #     Revision 1.9  2003/01/12 19:45:41  pfkeb
00468 #     Move interval counting to ntuple
00469 #
00470 #     Revision 1.8  2003/01/08 00:22:21  pfkeb
00471 #     New interface to NTupleController
00472 #
00473 #     Revision 1.7  2003/01/06 23:57:21  claus
00474 #     Merged Ric's changes with Paul's
00475 #
00476 #     Revision 1.6  2003/01/05 00:18:50  pfkeb
00477 #     Make use of new HippoDraw features
00478 #
00479 #     Revision 1.5  2002/12/23 19:00:25  pfkeb
00480 #     Add HippoDraw to RunControl
00481 #
00482 #     Revision 1.4  2002/12/19 19:59:52  claus
00483 #     Mods for Hippo
00484 #
00485 #     Revision 1.3  2002/12/11 21:18:07  stuvi
00486 #     Changed glt register assignments to bit field assignments
00487 #
00488 #     Revision 1.2  2002/12/10 02:42:03  stuvi
00489 #     Put the event size plotting outside the tracker strip look
00490 #
00491 #     Revision 1.1  2002/12/10 00:59:16  stuvi
00492 #     Runcontrol example that uses Hippo. Currently it doesn't work in GUI mode.
00493 #
00494 #     Revision 1.4  2002/12/02 17:17:09  claus
00495 #     Added provision to allow application to run stand-alone
00496 #
00497 #     Revision 1.3  2002/11/28 02:02:04  claus
00498 #     Shuffled constructor arguments
00499 #
00500 #     Revision 1.2  2002/11/27 23:49:27  claus
00501 #     Initialize semaphore with zero count
00502 #
00503 #     Revision 1.1  2002/11/27 05:02:48  claus
00504 #     Initial version of Run Control
00505 #

Generated on Fri Jul 21 13:26:30 2006 for LATTE R04-12-00 by doxygen 1.4.3