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

testErrorPropogation.py

00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2003
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__ = "Test application for inducing and detecting event errors"
00012 __author__   = "J. Panetta <panetta@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = "2005/03/22"
00014 __version__  = "$Revision: 1.2 $"
00015 __credits__  = "SLAC"
00016 
00017 import LATTE.copyright_SLAC
00018 
00019 import threading
00020 import logging       as     log
00021 
00022 from   LATTE.runcontrol.rcTransitions import rcTransitions
00023 from   LATTE.runcontrol.ArgumentImpl  import ArgumentImpl
00024 
00025 from support.SimpleGasuExample   import *
00026 from support.MiniGLTExample      import *
00027 
00028 
00029 #  This class puts up a GUI for inputting a value of some sort.  It is used by
00030 #  the userApplication example to get the number of self triggers to take.
00031 class userArgument(ArgumentImpl):
00032   "GUI for getting the user to input some sort of value."
00033   def __init__(self, parent = None, name = None, modal = 0, fl = 0):
00034     ArgumentImpl.__init__(self, parent, name, modal, fl)
00035     self.__value = 0
00036     self.setCaption("Hello world!")
00037 
00038   def OKButtonClicked(self):
00039     self.__value = int(self.ArgumentList.text().latin1())
00040     self.close()
00041 
00042   def CancelButtonClicked(self):
00043     self.__value = None
00044     self.close()
00045 
00046   def getValue(self, caption):
00047     self.setCaption(caption)
00048     self.show()
00049     self.exec_loop()
00050     return self.__value
00051 
00052 class userArgText(object):
00053   "Text user interface for getting the user to input some sort of value"
00054   def __init__(self):
00055     pass
00056 
00057   def getValue(self, caption):
00058     return int(raw_input("%s: " % (caption)))
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, gui, userId, debug):
00066     rcTransitions.__init__(self, gui, 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     # Two choices for the trigger, GEM and MiniGLT
00083     if self.lat.existsGEM():
00084       self.trigger( SimpleGasuExample() )
00085     else:
00086       self.trigger( MiniGLTExample() )
00087 
00088     # A state transition can be rejected by not returning None
00089     return None
00090 
00091   def startRun(self):
00092     log.debug("userApplication.startRun()")
00093 
00094     caption = "Enter number of triggers to take"
00095     if self.rc is None:
00096       cnt = self.__arg.getValue(caption)
00097     else:
00098       cnt = self.rc.execGUImethod(self.__arg.getValue, caption)
00099 
00100     # The user pressed 'Cancel'
00101     if cnt is None:  return -1
00102     self.__cnt = cnt
00103     
00104     if self.rc is not None:
00105       self.getParameterVerifier().add(caption, cnt)
00106       
00107     # Spawn a thread to synchronize commands with events
00108     # This must happen after triggers are enabled
00109     self.__cmdSynchQuit = False
00110 
00111     # turn on the prescaler to infinite:
00112     self.ocs.evtHandlerSendPrescaled(-1)    
00113     
00114     # A state transition can be rejected by not returning None
00115     return None
00116 
00117   def stopRun(self):
00118 
00119     # Success is defined if we found one and only one trigger parity error
00120     # and one and only one packet error
00121     if self.getBadEvents() == 0 and self.getErrorEvents() == 0:
00122       self.setCompletionStatus(self.COMPL_STATUS_PASSED)
00123     else:
00124       self.setCompletionStatus(self.COMPL_STATUS_FAILED)
00125 
00126     self.__cmdSynchQuit = True
00127     self.__eventSem.release()
00128 
00129     # The STOP_RUN transition can not be rejected
00130 
00131   def resume(self):
00132     # Issue self trigger to make up for the one that was lost during PAUSE
00133     self.trigger().solicit()
00134 
00135     return None
00136 
00137   def stop(self):
00138     return self.stopRun()
00139 
00140   def process(self, (status, buffer)):
00141     "Method called back for each data event taken"
00142     # log.debug("userApplication.process()")
00143 
00144     evtCli = self.evtCli
00145 
00146     if status != 0:
00147       print "status = ", status
00148       if evtCli.isGGLTStatus():
00149         log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr()))
00150       elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR):
00151         log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr()))
00152       self.__eventSem.release()
00153       return
00154 
00155     try:
00156       # In the future this event may contain additional data
00157       if evtCli.isSweepEvent(): 
00158         return
00159     except:
00160       # Event summary word inaccessible, handle the bad event here
00161       import gutil
00162       gutil.logException()
00163       return
00164 
00165     if evtCli.isTrgParityErrorEvent():
00166       log.debug( "Found a trigger parity error")
00167     elif evtCli.isPacketErrorEvent():
00168       log.debug( "Found a packet error")
00169     else:
00170       log.debug( "Found a normal event")
00171     # Get next event triggered
00172     self.__eventSem.release()
00173 
00174   def commandSynch(self):
00175     "Method called by the command synchronization task"
00176     import time
00177     trigger  = self.trigger()
00178     eventSem = self.__eventSem
00179 
00180     # Drain the semaphore release count
00181     # Handles the case when the stop run release collided with a trigger release
00182     while eventSem.acquire(0):  pass
00183 
00184     t0  = time.time()
00185 
00186     # Compensate for the extra CMD_SELF_TRIGGER below
00187     cnt   = 1
00188     count = self.__cnt
00189 
00190     # bitmask in GEM config to cause trigger parity error
00191     TPE = 0x20
00192     # bitmask in GEM config to cause packet error  (suppress bit)
00193     PKTE = 0x40
00194 
00195     log.info(" commandSync")
00196     # Wait for START_RUN to enable triggers
00197     trigger.waitForMaskEnable()
00198 
00199     # Cause a trigger parity error for GEM event
00200     log.info( "buggering gem configuration to create trigger parity errors")
00201     trigger.disable()
00202     gemc = trigger.GEM().GEMC
00203     gemcfg = gemc.CONFIGURATION
00204     gemcfg |= TPE
00205     gemc.configuration = gemcfg
00206     trigger.enable()
00207 
00208     trigger.solicit()                   # Issue an internal trigger
00209     eventSem.acquire()                  # Wait for the event to be processed
00210 
00211     
00212     t1 = trigger.getEnableTime()        # get the last trigger enable time from GLT
00213     while cnt < count and not self.__cmdSynchQuit:
00214       cnt += 1
00215       trigger.solicit()                 # Issue an internal trigger
00216       time.sleep(.0001)
00217       eventSem.acquire()                # Wait for the event to be processed
00218       #trigger.disable()                # Disable triggers
00219       # Do stuff
00220       #trigger.enable()                 # Enable triggers
00221 
00222     # Reset the GEM to remove the trigger parity error bit.
00223     trigger.disable()
00224     log.info( "unbuggering gem configuration")
00225     gemc = trigger.GEM().GEMC
00226     gemcfg = gemc.CONFIGURATION
00227     gemcfg &= ~TPE
00228     gemc.configuration = gemcfg
00229 
00230     t2 = trigger.getTimeStamp()                 # Get the last trigger timestamp
00231 
00232              
00233     # Get out of waiting when in standalone mode
00234     self.sync()
00235 
00236     # execute the GUI functions for stopRun, just in case
00237     if not self.__cmdSynchQuit and not self.isRunFromSuite():
00238       if self.gui is not None:
00239         self.gui.doStopRun()
00240 
00241   def wait(self):
00242     self.__cmdSynchSem.acquire()
00243 
00244   def sync(self):
00245     if __name__ == "__main__" or self.isRunFromSuite():
00246       self.__cmdSynchSem.release()
00247 
00248 
00249 # Standalone mode:
00250 if __name__ == "__main__":
00251   import os
00252   log.basicConfig()
00253   log.getLogger("").setLevel(log.DEBUG)
00254   ua = userApplication(None, 321, 1)
00255   ua.rcSetup(os.path.join(os.environ['ONLINE_ROOT'], 'repos/simpleTemSchema.xml'))
00256   ua.rcStartRun()
00257   ua.wait()
00258   ua.rcStopRun()
00259   ua.rcTeardown()
00260 

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