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

sweepRejectTest.py

00001 #!/usr/local/bin/python
00002 #
00003 #  sweepRejectTest.py
00004 #      Test code to test what happens when sweeps never appear in RC.
00005 #      Sweeps are disabled by reimplementing the shut() method.
00006 #      DO NOT use this code as a basis for any user code.  --Jim
00007 #
00008 #
00009 #
00010 #                               Copyright 2004
00011 #                                     by
00012 #                        The Board of Trustees of the
00013 #                     Leland Stanford Junior University.
00014 #                            All rights reserved.
00015 #
00016 
00017 
00018 
00019 
00020 __facility__ = "Online"
00021 __abstract__ = "Application to test Bad or Timed out SWEEP events."
00022 __author__   = "J. Panetta <panetta@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00023 __date__     = ("$Date: 2005/03/21 17:58:11 $").split(' ')[1]
00024 __version__  = "$Revision: 1.2 $"
00025 __release__  = "$Name: R04-12-00 $"
00026 __credits__  = "SLAC"
00027 
00028 import LATTE.copyright_SLAC
00029 
00030 import            threading
00031 import logging as log
00032 import            time
00033 
00034 from   LATTE.runcontrol.rcTransitions  import rcTransitions
00035 from   LATTE.runcontrol.ArgumentImpl   import ArgumentImpl
00036 
00037 from support.SimpleGasuExample   import *
00038 from support.MiniGLTExample      import *
00039 
00040 
00041 #  This class puts up a GUI for inputting a value of some sort.  It is used by
00042 #  the userApplication example to get the number of self triggers to take.
00043 class userArgument(ArgumentImpl):
00044   "GUI for getting the user to input some sort of value."
00045   def __init__(self, parent = None, name = None, modal = 0, fl = 0):
00046     ArgumentImpl.__init__(self, parent, name, modal, fl)
00047     self.__value = 0
00048     self.setCaption("Hello world!")
00049 
00050   def OKButtonClicked(self):
00051     self.__value = int(self.ArgumentList.text().latin1())
00052     self.close()
00053 
00054   def CancelButtonClicked(self):
00055     self.__value = None
00056     self.close()
00057 
00058   def getValue(self, caption):
00059     self.setCaption(caption)
00060     self.show()
00061     self.exec_loop()
00062     return self.__value
00063 
00064 class userArgText(object):
00065   "Text user interface for getting the user to input some sort of value"
00066   def __init__(self):
00067     pass
00068 
00069   def getValue(self, caption):
00070     return int(raw_input("%s: " % (caption)))
00071 
00072 
00073 #  Example application implementation.
00074 #  Note that the name of the class must be userApplication.
00075 #  Look at rcTransitions for names of other transition methods that can be used.
00076 class userApplication(rcTransitions):
00077   "Implmentation class for a user application"
00078   def __init__(self, rc, userId, debug):
00079     rcTransitions.__init__(self, rc, userId, debug)
00080     log.debug("userApplication.__init__()")
00081     self.__eventSem    = threading.Semaphore(0)
00082     self.__cmdSynchSem = threading.Semaphore(0)
00083 
00084   def getName(self):
00085     return __name__
00086 
00087   def setup(self):
00088     log.debug("userApplication.setup()")
00089 
00090     if self.rc is None:
00091       self.__arg = userArgText()
00092     else:
00093       self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1)
00094 
00095     # Get a TEM instance
00096     if self.lat.TEMcnt() == 1:
00097       tem = self.lat.TEM[self.lat.TEM.keys()[0]]
00098     elif self.lat.TEMcnt() > 1:
00099       tem = self.lat.TEM.all()
00100     else:
00101       log.fatal("No TEM(s) found in the schema")
00102       return -1
00103 
00104     # clear TEM stats reg
00105     tem.COMMAND_RESPONSE = 0
00106 
00107     # clear TEM status reg
00108     tem.STATUS = 0
00109 
00110     # enable output in our GCCCs
00111     # broadcast load of GCCC_REG_CONFIGURATION
00112 
00113     bcast_ccc = tem.allCCC()
00114     bcast_ccc.CONFIGURATION = 0x80000000L
00115 
00116     #  disable all GCRCs in all GCCCs via broadcast # GCCC_REG_LAYER_MASK_0, GCCC_REG_LAYER_MASK_1
00117     bcast_ccc.LAYER_MASK_0 = 0xFFFFFFFFL
00118     bcast_ccc.LAYER_MASK_1 = 0xFFFFFFFFL
00119     ccc0 = tem.downCCC(0) # O$GCCC_00
00120     ccc0.LAYER_MASK_0 = 0xFFFF0000L
00121     ccc0.LAYER_MASK_1 = 0xFFFF000FL
00122     ccc2 = tem.downCCC(2) # O$GCCC_02
00123     ccc2.LAYER_MASK_0 = 0xFFFF0000L
00124     ccc2.LAYER_MASK_1 = 0xFFFF0000L
00125 
00126     # large timeouts for all GCCCs
00127     # broadcast load of GCCC_REG_EVENT_TIMEOUTS
00128     bcast_ccc.EVENT_TIMEOUTS = 0x0
00129 
00130     # Two choices for the trigger, GEM and MiniGLT
00131     if self.lat.existsGEM():
00132       self.trigger( BadGasuExample() )
00133     else:
00134       self.trigger( BadGLTExample() )
00135 
00136     # A state transition can be rejected by not returning None
00137     return None
00138 
00139   def startRun(self):
00140     log.debug("userApplication.startRun()")
00141 
00142     caption = "Enter number of triggers to take"
00143     if self.rc is None:
00144       cnt = self.__arg.getValue(caption)
00145     else:
00146       cnt = self.rc.execGUImethod(self.__arg.getValue, caption)
00147 
00148     # The user pressed 'Cancel'
00149     if cnt is None:  return -1
00150     self.__cnt = cnt
00151 
00152     if self.rc is not None:
00153       self.getParameterVerifier().add(caption, cnt)
00154 
00155     # Spawn a thread to synchronize commands with events
00156     self.__cmdSynchQuit = False
00157 
00158     # A state transition can be rejected by not returning None
00159     return None
00160 
00161   def stopRun(self):
00162     log.debug("userApplication.stopRun()")
00163 
00164     if self.getBadEvents() == 0 and self.getErrorEvents() == 0:
00165       self.setCompletionStatus(self.COMPL_STATUS_PASSED)
00166     else:
00167       self.setCompletionStatus(self.COMPL_STATUS_FAILED)
00168 
00169     self.__cmdSynchQuit = True
00170     self.__eventSem.release()
00171 
00172     # The STOP_RUN transition can not be rejected
00173 
00174   def resume(self):
00175     log.debug("userApplication.resume()")
00176 
00177     # Issue self trigger to make up for the one that was lost during PAUSE
00178     self.trigger().solicit()
00179 
00180     return None
00181 
00182   def stop(self):
00183     log.debug("userApplication.stop()")
00184 
00185     return self.stopRun()
00186 
00187   def teardown(self):
00188     log.debug("userApplication.teardown()")
00189     # Allow the C++ object to be deleted
00190     if self.rc is not None and self.__arg is not None:
00191       self.__arg.deleteLater()
00192 
00193   def process(self, (status, buffer)):
00194     "Method called back for each data event taken"
00195     #log.debug("userApplication.process()")
00196 
00197     evtCli = self.evtCli
00198 
00199     if status != 0:
00200       if evtCli.isGGLTStatus():
00201         log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr()))
00202       elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR):
00203         log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr()))
00204       self.__eventSem.release()
00205       return
00206     try:
00207       # In the future this event may contain additional data
00208       if evtCli.isSweepEvent(): return
00209     except:
00210       # Event summary word inaccessible, handle the bad event here
00211       log.exception("")
00212       return
00213 
00214 
00215     # Get next event triggered
00216     self.__eventSem.release()
00217 
00218 
00219   def commandSynch(self):
00220     "Method called by the command synchronization task"
00221     import time
00222     trigger  = self.trigger()
00223     eventSem = self.__eventSem
00224 
00225     # Drain the semaphore release count
00226     # Handles the case when the stop run release collided with a trigger release
00227     while eventSem.acquire(0):  pass
00228 
00229     t0  = time.time()
00230 
00231     # Compensate for the extra CMD_SELF_TRIGGER below
00232     cnt   = 1
00233     count = self.__cnt
00234 
00235     # Wait for START_RUN to enable triggers
00236     trigger.waitForMaskEnable()
00237 
00238     trigger.solicit()                   # Issue an internal trigger
00239     eventSem.acquire()                  # Wait for the event to be processed
00240 
00241     t1 = trigger.getEnableTime()        # get the last trigger enable time from GLT
00242     while cnt < count and not self.__cmdSynchQuit:
00243       cnt += 1
00244       trigger.solicit()                 # Issue an internal trigger
00245       time.sleep(.0001)
00246       eventSem.acquire()                # Wait for the event to be processed
00247 
00248     t2 = trigger.getTimeStamp()                 # Get the last trigger timestamp
00249 
00250     if t1 is None:
00251       t1 = t0
00252     if t2 is None:
00253       t2 = time.time()
00254     dT = t2 - t1
00255     if dT == 0.0:  dT = 0.000001
00256     log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \
00257              (self.getName(), self.evtCnt, dT, self.evtCnt/dT))
00258 
00259     # Get out of waiting when in suite or standalone mode
00260     self.sync()
00261 
00262     # execute the GUI functions for stopRun, just in case
00263     if not self.__cmdSynchQuit and not self.isRunFromSuite():
00264       if self.rc is not None:
00265         self.rc.doStop()
00266 
00267   def wait(self):
00268     self.__cmdSynchSem.acquire()
00269 
00270   def sync(self):
00271     if __name__ == "__main__" or self.isRunFromSuite():
00272       self.__cmdSynchSem.release()
00273 
00274 from LATTE.trigger.rcTrgGem     import *
00275 from LATTE.trigger.rcTrgMiniGLT import *
00276 class BadGasuExample(SimpleGasuExample):
00277   """\brief BadGasuExample
00278   """
00279   def __init__(self):
00280     """\brief BadGasuExample constructor
00281     """
00282     SimpleGasuExample.__init__(self)
00283   def shut(self, sweepEvent, progress = None):
00284     """Re-implementation of the shut function to NEVER send a sweep
00285 
00286     NEVER EVER EVER use this code in a real trigger system.  --Jim Panetta
00287     This code is only to test a particular bug in sweep timeouts.
00288     """
00289 
00290     gemw = self.GEM().GEMW
00291     gemsc = self.GEM().GEMSC
00292 
00293     #0) determine whether we are enabled or not
00294     if gemw.WINDOW_OPEN_MASK != 0:
00295       enabled = True
00296     else:
00297       enabled = False
00298 
00299     #1) disable triggers
00300     goodSolicit  = self.solicit
00301     # self.solicit = self.__falseSolicit
00302     self.disable()
00303     sweepEvent.clear()
00304 
00305     #2) Replace contents of all schedulers with solicited with (Engine) f
00306     #   Doing it by hand
00307     oldSched = [ gemsc.CONDITIONS_40_47,
00308                  gemsc.CONDITIONS_48_4F,
00309                  gemsc.CONDITIONS_50_57,
00310                  gemsc.CONDITIONS_58_5F,
00311                  gemsc.CONDITIONS_60_67,
00312                  gemsc.CONDITIONS_68_6F,
00313                  gemsc.CONDITIONS_70_77,
00314                  gemsc.CONDITIONS_78_7F ]
00315     scheduler = ( 0xffffffffL )               # Everything's f!
00316     gemsc.CONDITIONS_40_47 = scheduler
00317     gemsc.CONDITIONS_48_4F = scheduler
00318     gemsc.CONDITIONS_50_57 = scheduler
00319     gemsc.CONDITIONS_58_5F = scheduler
00320     gemsc.CONDITIONS_60_67 = scheduler
00321     gemsc.CONDITIONS_68_6F = scheduler
00322     gemsc.CONDITIONS_70_77 = scheduler
00323     gemsc.CONDITIONS_78_7F = scheduler
00324 
00325     #2.5) Wait until we don't have progress
00326     if progress is not None:
00327       while True:
00328         if progress() == 0:
00329           break
00330         time.sleep(.5)
00331         # print "waiting for progress"
00332 
00333     #3) Change conditions to be solicit only, solicit a trigger
00334     gemw.WINDOW_OPEN_MASK = TrgGem._TrgGem__SOLICIT_MASK
00335     # self.GEM().downGEMC().CMD_TRIGGER = 1
00336 
00337     #4) Block until the sweep is detected by rcTransitions then disable triggers
00338     tmo = self._rcTrgGem__SWEEP_TMO
00339     while (tmo > 0.0):
00340       if sweepEvent.isSet():  break
00341       sweepEvent.wait(0.50)
00342       if progress is not None:
00343         if progress() != 0:
00344           tmo = self._rcTrgGem__SWEEP_TMO
00345           continue
00346       tmo -= 0.50
00347     if tmo <= 0:
00348       sweepEvent.set()
00349       logging.fatal("Trigger sweep timed out before all events were drained")
00350       return False
00351 
00352     self.disable()
00353 
00354     #5) Put the original contents of schedulers back
00355     gemsc.CONDITIONS_40_47 = oldSched[0]
00356     gemsc.CONDITIONS_48_4F = oldSched[1]
00357     gemsc.CONDITIONS_50_57 = oldSched[2]
00358     gemsc.CONDITIONS_58_5F = oldSched[3]
00359     gemsc.CONDITIONS_60_67 = oldSched[4]
00360     gemsc.CONDITIONS_68_6F = oldSched[5]
00361     gemsc.CONDITIONS_70_77 = oldSched[6]
00362     gemsc.CONDITIONS_78_7F = oldSched[7]
00363 
00364     #6) Put the trigger conditions back.
00365     if enabled:
00366       self.enable()
00367     self.solicit = goodSolicit
00368 
00369     return True
00370 
00371 
00372 class BadGLTExample(MiniGLTExample):
00373   """\brief MiniTower example interface to MiniGLT
00374   """
00375   def __init__(self):
00376     """\brief AcdTriggerExample constructor
00377     """
00378     MiniGLTExample.__init__(self)
00379   def shut(self, sweepEvent, progress = None):
00380     """Re-implementation of the shut function to NEVER send a sweep
00381 
00382     NEVER EVER EVER use this code in a real trigger system.  --Jim Panetta
00383     This code is only to test a particular bug in sweep timeouts.
00384     """
00385 
00386     glt = self.GLT()
00387 
00388     #0) disable triggers
00389     if not glt.triggersDisabled():
00390       enabled = True
00391     else:
00392       enabled = False
00393     goodSolicit  = self.solicit
00394     # self.solicit = self.__falseSolicit
00395 
00396     self.disable()
00397     sweepEvent.clear()
00398 
00399     #1) Set up marker logic
00400     mask           = glt.MASK           # Cache Mask, CalStrobe and Tack
00401     calStrobe      = glt.CAL_STROBE
00402     tack           = glt.TACK
00403     zeroSuppress   = glt.ZERO_SUPPRESS
00404     fourRange      = glt.FOUR_RANGE_READOUT
00405     marker         = glt.MARKER
00406 
00407     glt.MASK       = TrgMiniGLT._TrgMiniGLT__SOLICIT_MASK # Enable internal trigger only
00408     glt.MARKER     = rcTrgMiniGLT._rcTrgMiniGLT__SWEEP_MARKER          # Signal that we're sweeping
00409     glt.CAL_STROBE = 0                  # Don't inject charge
00410     glt.TACK       = 1                  # Force a readout
00411     glt.ZERO_SUPPRESS       = 1         # Yes to zero suppression
00412     glt.FOUR_RANGE_READOUT  = 0         # No to four range readout
00413 
00414     #2) enable and solicit
00415     glt.enableMask()
00416     self.waitForMaskEnable()
00417     # self.GLT().CMD_SELF_TRIGGER = 1     # Solicit a trigger
00418 
00419     #3) Block until the sweep is detected by rcTransitions then disable triggers
00420     tmo = self._rcTrgMiniGLT__SWEEP_TMO
00421     while (tmo > 0.0):
00422       if sweepEvent.isSet():  break
00423       sweepEvent.wait(0.5)
00424       if progress is not None:
00425         if progress() != 0:
00426           tmo = self._rcTrgMiniGLT__SWEEP_TMO
00427           continue
00428       tmo -= 0.5
00429     if tmo <= 0:
00430       sweepEvent.set()
00431       logging.fatal("Trigger sweep timed out before all events were drained")
00432       return False
00433     self.disable()
00434 
00435     #4) Put the original contents of scheduler 0x40 back, and put the TAM back
00436     glt.CAL_STROBE         = calStrobe
00437     glt.TACK               = tack
00438     glt.MARKER             = marker
00439     glt.ZERO_SUPPRESS      = zeroSuppress
00440     glt.FOUR_RANGE_READOUT = fourRange
00441     glt.MASK               = mask
00442 
00443     #5) Put the trigger conditions back
00444     if enabled:
00445       glt.enableMask()
00446     self.solicit = goodSolicit
00447 
00448     return True

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