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

testAppAcd.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 ACD test application"
00012 __author__   = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = "11/21/2002"
00014 __version__  = "$Revision: 1.4 $"
00015 __credits__  = "SLAC"
00016 
00017 import LATTE.copyright_SLAC
00018 
00019 import                      threading
00020 import logging       as     log
00021 import                      time
00022 
00023 from   LATTE.runcontrol.rcTransitions import rcTransitions
00024 from   LATTE.runcontrol.ArgumentImpl  import ArgumentImpl
00025 
00026 from support.SimpleGasuExample   import *
00027 
00028 #  This class puts up a GUI for inputting a value of some sort.  It is used by
00029 #  the userApplication example to get the number of self triggers to take.
00030 class userArgument(ArgumentImpl):
00031   "GUI for getting the user to input some sort of value"
00032   def __init__(self, parent = None, name = None, modal = 0, fl = 0):
00033     ArgumentImpl.__init__(self, parent, name, modal, fl)
00034     self.__value = 0
00035     self.setCaption("Hello world!")
00036 
00037   def OKButtonClicked(self):
00038     self.__value = int(self.ArgumentList.text().latin1())
00039     self.close()
00040 
00041   def CancelButtonClicked(self):
00042     self.__value = None
00043     self.close()
00044 
00045   def getValue(self, caption):
00046     self.setCaption(caption)
00047     self.show()
00048     self.exec_loop()
00049     return self.__value
00050 
00051 class userArgText(object):
00052   "Text user interface for getting the user to input some sort of value"
00053   def __init__(self):
00054     pass
00055 
00056   def getValue(self, caption):
00057     return int(raw_input("%s: " % (caption)))
00058 
00059 
00060 #  Example application implementation.
00061 #  Note that the name of the class must be userApplication.
00062 #  Look at rcTransitions for names of other transition methods that can be used.
00063 class userApplication(rcTransitions):
00064   "Implmentation class for a user application"
00065   def __init__(self, rc, userId, debug):
00066     rcTransitions.__init__(self, rc, userId, debug)
00067     log.debug("userApplication.__init__()")
00068     self.__eventSem    = threading.Semaphore(0)
00069     self.__cmdSynchSem = threading.Semaphore(0)
00070 
00071   def getName(self):
00072     return __name__
00073 
00074   def setup(self):
00075     log.debug("userApplication.setup()")
00076 
00077     if self.rc is None:
00078       self.__arg = userArgText()
00079     else:
00080       self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1)
00081 
00082     aem = self.lat.downAEM()
00083 
00084     arc0 = aem.downARC(11)
00085     arc0.cmd_reset = 1
00086 
00087     # configure the AEM
00088     aem.configuration = 0x007ff
00089 
00090     # The FREE-sim simulates 4 ADCs with fixed outputs of 1112, 1113, 1114, 1115 (decimal).
00091     # The FREE-sim simulates 4 ADCs with fixed outputs of 0x458, 0x459, 0x45a, 0x45b (hex).
00092     # adjust the PHA thresholds to turn these on/off.
00093 
00094     # config all PHAs on
00095 
00096     thresh_on  = 0x20
00097     thresh_off = 0xFFF
00098 
00099     arc0.PHA_THRESHOLD_0  = thresh_on
00100     arc0.PHA_THRESHOLD_1  = thresh_on
00101     arc0.PHA_THRESHOLD_2  = thresh_on
00102     arc0.PHA_THRESHOLD_3  = thresh_on
00103     arc0.PHA_THRESHOLD_4  = thresh_on
00104     arc0.PHA_THRESHOLD_5  = thresh_on
00105     arc0.PHA_THRESHOLD_6  = thresh_on
00106     arc0.PHA_THRESHOLD_7  = thresh_on
00107     arc0.PHA_THRESHOLD_8  = thresh_on
00108     arc0.PHA_THRESHOLD_9  = thresh_on
00109     arc0.PHA_THRESHOLD_10 = thresh_on
00110     arc0.PHA_THRESHOLD_11 = thresh_on
00111     arc0.PHA_THRESHOLD_12 = thresh_on
00112     arc0.PHA_THRESHOLD_13 = thresh_on
00113     arc0.PHA_THRESHOLD_14 = thresh_on
00114     arc0.PHA_THRESHOLD_15 = thresh_on
00115     arc0.PHA_THRESHOLD_16 = thresh_on
00116     arc0.PHA_THRESHOLD_17 = thresh_on
00117     arc0.veto_width      = 5
00118 
00119     # set MAX_PHA
00120     arc0.MAX_PHA = 18
00121 
00122     # set PHA ENABLE bits
00123     arc0.PHA_EN_0 = 0xffff
00124     arc0.PHA_EN_1 = 0x3
00125 
00126     # set VETO ENABLE bits
00127     arc0.VETO_EN_0 = 0xffff
00128     arc0.VETO_EN_1 = 0x3
00129 
00130     afeb = arc0.allAFE()
00131     afeb.CONFIGURATION = 0x0032
00132     afeb.VETO_DAC = 0x20
00133     afeb.HLD_DAC = 0x30
00134     afeb.TCI_DAC = 0x20
00135     afeb.bias_dac     = 3
00136 
00137     aem.TRGSEQ = 0x5f
00138 
00139     # Two choices for the trigger, GEM and MiniGLT
00140     if self.lat.existsGEM():
00141       self.trigger( SimpleGasuExample() )
00142     else:
00143       raise AssertionError, "ACD cannot take meaningful triggers without a GEM"
00144 
00145     # A state transition can be rejected by not returning None
00146     return None
00147 
00148   def startRun(self):
00149     log.debug("userApplication.startRun()")
00150 
00151     caption = "Enter number of triggers to take"
00152     if self.rc is None:
00153       cnt = self.__arg.getValue(caption)
00154     else:
00155       cnt = self.rc.execGUImethod(self.__arg.getValue, caption)
00156 
00157     # The user pressed 'Cancel'
00158     if cnt is None:  return -1
00159     self.__cnt = cnt
00160 
00161     # Spawn a thread to synchronize commands with events
00162     self.__cmdSynchQuit = False
00163 
00164     # A state transition can be rejected by not returning None
00165     return None
00166 
00167   def stopRun(self):
00168     log.debug("userApplication.stopRun()")
00169 
00170     self.__cmdSynchQuit = True
00171     self.__eventSem.release()
00172 
00173    # The STOP_RUN transition can not be rejected
00174 
00175   def resume(self):
00176     log.debug("userApplication.resume()")
00177 
00178     # Issue self trigger to make up for the one that was lost during PAUSE
00179     self.trigger().solicit()
00180 
00181     return None
00182 
00183   def stop (self):
00184     log.debug("userApplication.stop()")
00185 
00186     return self.stopRun()
00187 
00188   def teardown(self):
00189     log.debug("userApplication.teardown()")
00190     # Allow the C++ object to be deleted
00191     if self.gui is not None and self.__arg is not None:
00192       self.__arg.deleteLater()
00193 
00194   def process(self, (status, buffer)):
00195     "Method called back for each data event taken"
00196     ###log.debug("userApplication.process()")
00197 
00198     evtCli = self.evtCli
00199 
00200     if status != 0:
00201       if evtCli.isGGLTStatus():
00202         log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr()))
00203       elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR):
00204         log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr()))
00205       self.__eventSem.release()
00206       return
00207     try:
00208       # In the future this event may contain additional data
00209       if evtCli.isSweepEvent(): return
00210     except:
00211       # Event summary word inaccessible, handle the bad event here
00212       log.exception("")
00213       return
00214 
00215     if evtCli.setCurrentContribution(evtCli.AEM) != -1:
00216       evtCli.evDumpEventAEM()
00217       print "AEM Veto Hit Vectors:"
00218       j = 0
00219       for hitVect in evtCli.evt.aem.vetoHitVectors:
00220         print "\tCable %2d Raw Data 0x%05x" % (j, hitVect)
00221         j+=1
00222       print "\nAEM Accept Hit Vectors:"
00223       j = 0
00224       for hitVect in evtCli.evt.aem.acceptHitVectors:
00225         print "\tCable %2d Raw Data 0x%05x" % (j, hitVect)
00226         j+=1
00227       print "\nAEM PHA Values:"
00228       j = 0
00229       for (cbl, phas) in evtCli.evt.aem.PHA.items():
00230         for pha in phas:
00231           print "\tCable: %02d - PHA Value: 0x%04x" % (cbl, pha.ui)
00232 
00233     # Get next event triggered
00234     self.__eventSem.release()
00235 
00236   #def __commandSynch(self, count):
00237   def commandSynch(self):
00238     "Method called by the command synchronization task"
00239     import time
00240     trigger  = self.trigger()
00241     eventSem = self.__eventSem
00242     # Drain the semaphore release count
00243     # Handles the case when the stop run release collided with a trigger release
00244     while eventSem.acquire(0):  pass
00245 
00246     t0  = time.time()
00247 
00248     # Compensate for the extra CMD_SELF_TRIGGER below
00249     cnt = 1
00250     count = self.__cnt
00251 
00252     # Wait for START_RUN to enable triggers
00253     trigger.waitForMaskEnable()
00254 
00255     trigger.solicit()                   # Issue an internal trigger
00256     eventSem.acquire()                  # Wait for the event to be processed
00257 
00258     t1 = trigger.getEnableTime()        # get the last trigger enable time from GLT
00259 
00260     while cnt < count and not self.__cmdSynchQuit:
00261       cnt += 1
00262       trigger.solicit()                 # Issue an internal trigger
00263       time.sleep(.0001)
00264       eventSem.acquire()                # Wait for the event to be processed
00265       #trigger.disable()                # Disable triggers
00266       # Do stuff
00267       #trigger.enable()                 # Enable triggers
00268 
00269     t2 = trigger.getTimeStamp()         # Get the last trigger timestamp
00270 
00271     if t1 is None:
00272       t1 = t0
00273     if t2 is None:
00274       t2 = time.time()
00275     dT = t2 - t1
00276     if dT == 0.0:  dT = 0.000001
00277     log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \
00278              (self.getName(), self.evtCnt, dT, self.evtCnt/dT))
00279 
00280     # Get out of waiting when in suite or standalone mode
00281     self.sync()
00282 
00283     # execute the GUI functions for stopRun, just in case
00284     if not self.__cmdSynchQuit and not self.isRunFromSuite():
00285       if self.rc is not None:
00286         self.rc.doStop()
00287 
00288   def wait(self):
00289     self.__cmdSynchSem.acquire()
00290 
00291   def sync(self):
00292     if __name__ == "__main__" or self.isRunFromSuite():
00293       self.__cmdSynchSem.release()
00294 
00295 
00296 # Standalone mode:
00297 if __name__ == "__main__":
00298   import os
00299   log.basicConfig()
00300   log.getLogger("").setLevel(log.DEBUG)
00301   ua = userApplication(None, 321, 0)
00302   ua.rcSetup(os.path.join(os.environ['ONLINE_ROOT'], 'repos/simpleAemSchema.xml'))
00303   ua.rcStartRun()
00304   ua.wait()
00305   ua.rcStopRun()
00306   ua.rcTeardown()
00307 
00308 # History:
00309 #     $Log: testAppAcd.py,v $
00310 #     Revision 1.4  2005/01/11 22:39:18  stuvi
00311 #     no message
00312 #
00313 #     Revision 1.3  2004/10/22 20:32:48  stuvi
00314 #     Fixed log.exception()
00315 #
00316 #     Revision 1.2  2004/08/18 18:00:15  stuvi
00317 #     Updated for LATTE 4.
00318 #     All hippo functions go through the Qt GUI bridge now.
00319 #
00320 #     Revision 1.1  2004/08/04 22:17:25  stuvi
00321 #     no message
00322 #
00323 #     Revision 1.19  2004/05/13 18:55:09  stuvi
00324 #     HLD_EN_0 and HLD_EN_1 no longer exist.
00325 #
00326 #     Revision 1.18  2004/05/03 21:19:47  stuvi
00327 #     Moved non-Runcontrol scripts to the support directory and modified imports accordingly.
00328 #
00329 #     Revision 1.17  2004/04/20 22:09:34  stuvi
00330 #     Changed ACD to AEM.
00331 #
00332 #     Revision 1.16  2004/04/17 02:22:54  stuvi
00333 #     Added teardown() to delete the C++ object for the userArgument
00334 #
00335 #     Revision 1.15  2004/04/08 01:57:39  panetta
00336 #     make testAppAcd work with GASU
00337 #
00338 #     Revision 1.14  2004/03/20 03:45:26  stuvi
00339 #     Updated code to use the new PHA object.
00340 #
00341 #     Revision 1.13  2004/03/10 22:24:50  panetta
00342 #     Upgraded trigger interface.
00343 #     Removed dependencies on self.glt.
00344 #
00345 #     Revision 1.12  2004/02/20 03:20:23  stuvi
00346 #     Added handling of the sweep events and error checking to the process() method,
00347 #
00348 #     Revision 1.11  2004/02/04 03:42:14  stuvi
00349 #     Changes required to make the scripts work with the new FSM engine.
00350 #
00351 #     Revision 1.10  2003/12/11 19:54:45  stuvi
00352 #     Suite and standalone mode modifications
00353 #
00354 #     Revision 1.9  2003/11/04 18:30:52  panetta
00355 #     Changed the commandSynch logic so that the enableMask() call would not pose a threat to snapshot taking.
00356 #
00357 #     Revision 1.8  2003/10/31 01:09:37  panetta
00358 #     1)  Moved register writes from startRun to setup
00359 #     2)  Added GLT enabling logic to __commandSynch
00360 #     3)  Gave example of getting the start/stop time from the hardware/event stream
00361 #
00362 #     Revision 1.7  2003/08/14 02:36:03  stuvi
00363 #     Fixed aem ui value access
00364 #
00365 #     Revision 1.6  2003/07/17 00:01:35  stuvi
00366 #     no message
00367 #
00368 #     Revision 1.5  2003/04/01 21:04:59  stuvi
00369 #     Fixed event count discrepancy when the run is stopped in the middle.
00370 #
00371 #     Revision 1.4  2003/03/31 19:28:53  stuvi
00372 #     Fixed name
00373 #
00374 #     Revision 1.3  2003/03/26 21:59:36  stuvi
00375 #     Fixed standalone mode
00376 #
00377 #     Revision 1.2  2003/03/25 04:53:52  stuvi
00378 #     Made sure the semaphores are drained
00379 #
00380 #     Revision 1.1  2003/03/11 21:20:55  stuvi
00381 #     Moved from RunControl directory
00382 #
00383 #     Revision 1.10  2003/02/21 04:08:03  stuvi
00384 #     Updated for G2
00385 #
00386 #     Revision 1.9  2003/02/06 05:19:38  claus
00387 #     Added resume; StopRun bug fix
00388 #
00389 #     Revision 1.8  2002/12/11 21:18:07  stuvi
00390 #     Changed glt register assignments to bit field assignments
00391 #
00392 #     Revision 1.7  2002/12/10 01:09:58  claus
00393 #     Added path and changed schema/config file for stand-alone mode
00394 #
00395 #     Revision 1.6  2002/12/04 01:59:23  claus
00396 #     Added message logging
00397 #
00398 #     Revision 1.5  2002/12/02 17:17:09  claus
00399 #     Added provision to allow application to run stand-alone
00400 #
00401 #     Revision 1.4  2002/11/28 02:02:03  claus
00402 #     Shuffled constructor arguments
00403 #
00404 #     Revision 1.3  2002/11/27 23:49:27  claus
00405 #     Initialize semaphore with zero count
00406 #
00407 #     Revision 1.2  2002/11/27 23:37:17  stuvi
00408 #     Added semaphor release
00409 #
00410 #     Revision 1.1  2002/11/27 05:02:47  claus
00411 #     Initial version of Run Control
00412 #

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