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

testAppEvtCli.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 test script which uses the custom event client testEvtCli"
00012 __author__   = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = ("$Date: 2005/03/21 17:58:13 $").split(' ')[1]
00014 __version__  = "$Revision: 1.5 $"
00015 __release__  = "$Name: R04-12-00 $"
00016 __credits__  = "SLAC"
00017 
00018 import LATTE.copyright_SLAC
00019 
00020 import                                  threading
00021 import logging                   as     log
00022 #from   rcHouseKeeping           import rcHouseKeeping
00023 import                                  time
00024 from   support.testEvtCli        import *
00025 
00026 from   support.SimpleGasuExample import *
00027 from   support.MiniGLTExample    import *
00028 
00029 from   LATTE.runcontrol.rcTransitions import rcTransitions
00030 from   LATTE.runcontrol.ArgumentImpl  import ArgumentImpl
00031 
00032 TRUE  = (0 < 1)
00033 FALSE = not TRUE
00034 
00035 #  This class puts up a GUI for inputting a value of some sort.  It is used by
00036 #  the userApplication example to get the number of self triggers to take.
00037 class userArgument(ArgumentImpl):
00038   "GUI for getting the user to input some sort of value."
00039   def __init__(self, parent = None, name = None, modal = 0, fl = 0):
00040     ArgumentImpl.__init__(self, parent, name, modal, fl)
00041     self.__value = 0
00042     self.setCaption("Hello world!")
00043 
00044   def OKButtonClicked(self):
00045     self.__value = int(self.ArgumentList.text().latin1())
00046     self.close()
00047 
00048   def CancelButtonClicked(self):
00049     self.__value = None
00050     self.close()
00051 
00052   def getValue(self, caption):
00053     self.setCaption(caption)
00054     self.show()
00055     self.exec_loop()
00056     return self.__value
00057 
00058 class userArgText(object):
00059   "Text user interface for getting the user to input some sort of value"
00060   def __init__(self):
00061     pass
00062 
00063   def getValue(self, caption):
00064     return int(raw_input("%s: " % (caption)))
00065 
00066 
00067 #  Example application implementation.
00068 #  Note that the name of the class must be userApplication.
00069 #  Look at rcTransitions for names of other transition methods that can be used.
00070 class userApplication(rcTransitions):
00071   "Implmentation class for a user application"
00072   def __init__(self, rc, userId, debug):
00073     rcTransitions.__init__(self, rc, userId, debug)
00074     log.debug("userApplication.__init__()")
00075     self.__eventSem    = threading.Semaphore(0)
00076     self.__cmdSynchSem = threading.Semaphore(0)
00077     self.__ec = testEvtCli(debug=debug)
00078     self.setEvtCli(self.__ec)
00079 
00080   def getName(self):
00081     return __name__
00082 
00083   def setup(self):
00084     log.debug("userApplication.setup()")
00085 
00086     #self.__ec.open("c:/temp/ebf040218020523.arch")
00087 
00088     if self.rc is None:
00089       self.__arg = userArgText()
00090     else:
00091       self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1)
00092 
00093     # Get a TEM instance
00094     if self.lat.TEMcnt() == 1:
00095       tem = self.lat.TEM[self.lat.TEM.keys()[0]]
00096     elif self.lat.TEMcnt() > 1:
00097       tem = self.lat.TEM.all()
00098     else:
00099       log.fatal("No TEM(s) found in the schema")
00100       return -1
00101 
00102     # reset the TEM since we are going to modify DATA_MASKS
00103     tem.CMD_RESET = 1
00104 
00105     # clear TEM stats reg
00106     tem.COMMAND_RESPONSE = 0
00107 
00108     # clear TEM status reg
00109     tem.STATUS = 0
00110 
00111     # enable CAL, disable TKR, no diag #  0x10FF for diag
00112     tem.DATA_MASKS = 0x00FF
00113 
00114     # TEM config reg # set TEM timeout
00115     tem.CONFIGURATION = 0
00116 
00117     #status = gTEMread( __GT, temId, TEM_REG_CONFIGURATION, &payload);
00118     #printf("tem config reg = 0x%08x\n", payload);
00119 
00120     # enable output in our GCCCs
00121     # broadcast load of GCCC_REG_CONFIGURATION
00122 
00123     bcast_ccc = tem.allCCC()
00124     bcast_ccc.CONFIGURATION = 0x80000000L
00125 
00126     #  disable all GCRCs in all GCCCs via broadcast # GCCC_REG_LAYER_MASK_0, GCCC_REG_LAYER_MASK_1
00127     bcast_ccc.LAYER_MASK_0 = 0xFFFFFFFFL
00128     bcast_ccc.LAYER_MASK_1 = 0xFFFFFFFFL
00129     ccc0 = tem.downCCC(0) # O$GCCC_00
00130     ccc0.LAYER_MASK_0 = 0xFFFF0000L
00131     ccc0.LAYER_MASK_1 = 0xFFFF000FL
00132     ccc2 = tem.downCCC(2) # O$GCCC_02
00133     ccc2.LAYER_MASK_0 = 0xFFFF0000L
00134     ccc2.LAYER_MASK_1 = 0xFFFF0000L
00135 
00136     # config GCFE for calibration -- range 0 first
00137     bcast_cfe = tem.allCCC().allCRC().allCFE()
00138     bcast_cfe.CONFIG_0    = 0x00
00139     bcast_cfe.CONFIG_1    = 0x36
00140     bcast_cfe.FLE_DAC     = 0x55
00141     bcast_cfe.FHE_DAC     = 0x55
00142     bcast_cfe.LOG_ACPT    = 0x10
00143     bcast_cfe.RNG_ULD_DAC = 0x7F
00144     bcast_cfe.REF_DAC     = 0x7f
00145 
00146     # config GCRC for calibration
00147     bcast_crc = tem.allCCC().allCRC()
00148     bcast_crc.DELAY_1 = 0xFF
00149     bcast_crc.DELAY_2 = 0xFF
00150     bcast_crc.DELAY_3 = 0xFF
00151     bcast_crc.DAC = 0x42FE
00152     bcast_crc.DAC = 0x42FE
00153 
00154     # large timeouts for all GCCCs
00155     # broadcast load of GCCC_REG_EVENT_TIMEOUTS
00156     bcast_ccc.EVENT_TIMEOUTS = 0x0
00157     #status = gGCCCread( __GT, temId, 1, GCCC_REG_EVENT_TIMEOUTS, &payload);
00158     #printf("gccc register event timeouts = 0x%08x\n", payload);
00159 
00160     # Register environment variables for housekeeping
00161     #hsk = self.getHSK()
00162     #regs = [tem.regs['data_masks'], ccc2.regs['layer_mask_1']]
00163     #hsk.addEnvRegs(regs)
00164     #hsk.setUpdateInterval(1)
00165 
00166     # Two choices for the trigger, GEM and MiniGLT
00167     if self.lat.existsGEM():
00168       self.trigger( SimpleGasuExample() )
00169     else:
00170       self.trigger( MiniGLTExample() )
00171 
00172     # A state transition can be rejected by not returning None
00173     return None
00174 
00175   def startRun(self):
00176     log.debug("userApplication.startRun()")
00177 
00178     caption = "Enter number of triggers to take"
00179     if self.rc is None:
00180       cnt = self.__arg.getValue(caption)
00181     else:
00182       cnt = self.rc.execGUImethod(self.__arg.getValue, caption)
00183 
00184     # The user pressed 'Cancel'
00185     if cnt is None:  return -1
00186     self.__cnt = cnt
00187 
00188     # Spawn a thread to synchronize commands with events
00189     self.__cmdSynchQuit = FALSE
00190     #cmdSynch = threading.Thread(None, self.__commandSynch, 'CmdSynch',
00191     #                            (cnt, self.__eventSem))
00192     #cmdSynch.start()
00193     #self.__cmdSynch = cmdSynch
00194 
00195     # A state transition can be rejected by not returning None
00196     return None
00197 
00198   def stopRun(self):
00199     log.debug("userApplication.stopRun()")
00200 
00201     self.__cmdSynchQuit = TRUE
00202     self.__eventSem.release()
00203     #self.__cmdSynch.join(2.0)
00204     #if self.__cmdSynch.isAlive():
00205     #  log.error("%s.%s: cmdSynch thread did not exit when expected" % \
00206     #            (self.getName(), "stopRun"))
00207 
00208     # The STOP_RUN transition can not be rejected
00209 
00210   def resume(self):
00211     log.debug("userApplication.resume()")
00212 
00213     # Issue self trigger to make up for the one that was lost during PAUSE
00214     self.trigger().solicit()
00215 
00216     return None
00217 
00218   def stop(self):
00219     log.debug("userApplication.stop()")
00220 
00221     return self.stopRun()
00222 
00223   def process(self, (status, buffer)):
00224     "Method called back for each data event taken"
00225     #log.debug("userApplication.process()")
00226 
00227     evtCli = self.evtCli
00228 
00229     if status != 0:
00230       if evtCli.isGGLTStatus():
00231         log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr()))
00232       elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR):
00233         log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr()))
00234       self.__eventSem.release()
00235       return
00236     try:
00237       # In the future this event may contain additional data
00238       if evtCli.isSweepEvent():
00239         log.debug("SWEEP EVENT")
00240         return
00241     except:
00242       # Event summary word inaccessible, handle the bad event here
00243       log.exception("")
00244       return
00245 
00246     #evtCli.evDumpCAL_LogAccepts();
00247     ###print ""
00248     #evtCli.evDumpCAL_Logs();
00249     #~ #print ""
00250     #~ #evtCli.evDumpTKR()
00251     ###evtCli.evDumpTEM_Error()
00252     ###evtCli.evDumpDiagnostic()
00253     ###for acc in evtCli.evt.CAL_LogAccepts:
00254     ###  print "CAL Log Accept: 0x%08x" % acc.ui
00255 
00256     ###for data in evtCli.evt.CAL_LogData:
00257     ###  print "CAL Log Data: 0x%08x" % data.ui
00258     #~ sum = evtCli.evt.summary
00259     ###evtCli.evDumpSummary()
00260 
00261     # Get next event triggered
00262     self.__eventSem.release()
00263 
00264 
00265   #def __commandSynch(self, count):
00266   def commandSynch(self):
00267     "Method called by the command synchronization task"
00268     import time
00269     trigger  = self.trigger()
00270     eventSem = self.__eventSem
00271 
00272     # Drain the semaphore release count
00273     # Handles the case when the stop run release collided with a trigger release
00274     while eventSem.acquire(0):  pass
00275 
00276     t0  = time.time()
00277 
00278     # Compensate for the extra CMD_SELF_TRIGGER below
00279     cnt   = 1
00280     count = self.__cnt
00281 
00282     # Wait for START_RUN to enable triggers
00283     trigger.waitForMaskEnable()
00284 
00285     trigger.solicit()                   # Issue an internal trigger
00286     eventSem.acquire()                  # Wait for the event to be processed
00287 
00288     t1 = trigger.getEnableTime()        # get the last trigger enable time from GLT
00289 
00290     while cnt < count and not self.__cmdSynchQuit:
00291       cnt += 1
00292       trigger.solicit()                 # Issue an internal trigger
00293       time.sleep(.0001)
00294       eventSem.acquire()                # Wait for the event to be processed
00295       #trigger.disable()                # Disable triggers
00296       # Do stuff
00297       #trigger.enable()                 # Enable triggers
00298 
00299     t2 = trigger.getTimeStamp()         # Get the last trigger timestamp
00300     # When we get here the triggers should still be enabled.
00301     # If the glt.MASK needs to be set through any other means
00302     # then it needs to be restored to its SETUP value here.
00303 
00304     if t1 is None:
00305       t1 = t0
00306     if t2 is None:
00307       t2 = time.time()
00308     dT = t2 - t1
00309     if dT == 0.0:  dT = 0.000001
00310     log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \
00311              (self.getName(), self.evtCnt, dT, self.evtCnt/dT))
00312 
00313     # Get out of waiting when in suite or standalone mode
00314     self.sync()
00315 
00316     # execute the GUI functions for stopRun, just in case
00317     if not self.__cmdSynchQuit and not self.isRunFromSuite():
00318       if self.rc is not None:
00319         self.rc.doStop()
00320 
00321   def wait(self):
00322     self.__cmdSynchSem.acquire()
00323 
00324   def sync(self):
00325     if __name__ == "__main__" or self.isRunFromSuite():
00326       self.__cmdSynchSem.release()
00327 
00328 
00329 # Standalone mode:
00330 if __name__ == "__main__":
00331   import os
00332   log.basicConfig()
00333   log.getLogger("").setLevel(log.DEBUG)
00334   ua = userApplication(None, 321, 0)
00335   ua.rcSetup(os.path.join(os.environ['ONLINE_ROOT'], 'repos/simpleTemSchema.xml'))
00336   ua.rcStartRun()
00337   ua.wait()
00338   ua.rcStopRun()
00339   ua.rcTeardown()
00340 
00341 # History:
00342 #     $Log: testAppEvtCli.py,v $
00343 #     Revision 1.5  2005/03/21 17:58:13  claus
00344 #     Modified to use the first TEM found in the schema, if only one is there, or
00345 #     broadcast to all TEMs if there are multiple.
00346 #
00347 #     Revision 1.4  2004/10/22 20:32:48  stuvi
00348 #     Fixed log.exception()
00349 #
00350 #     Revision 1.3  2004/08/18 18:00:15  stuvi
00351 #     Updated for LATTE 4.
00352 #     All hippo functions go through the Qt GUI bridge now.
00353 #
00354 #     Revision 1.2  2004/08/07 02:10:27  stuvi
00355 #     no message
00356 #
00357 #     Revision 1.1  2004/08/06 18:59:26  stuvi
00358 #     Application for testing custom event client functionality
00359 #
00360 #     Revision 1.3  2004/05/03 21:19:47  stuvi
00361 #     Moved non-Runcontrol scripts to the support directory and modified imports accordingly.
00362 #
00363 #     Revision 1.2  2004/03/10 22:24:51  panetta
00364 #     Upgraded trigger interface.
00365 #     Removed dependencies on self.glt.
00366 #
00367 #     Revision 1.1  2004/02/20 00:34:37  stuvi
00368 #     Sample custom event client implementation and test app
00369 #
00370 #

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