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