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

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

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