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 CAL 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.9 $" 00015 __credits__ = "SLAC" 00016 00017 import LATTE.copyright_SLAC 00018 00019 import threading 00020 import logging as log 00021 from LATTE.runcontrol.rcTransitions import rcTransitions 00022 from LATTE.runcontrol.ArgumentImpl import ArgumentImpl 00023 import time 00024 00025 from support.SimpleGasuExample import * 00026 from support.MiniGLTExample 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.isRunFromSuite(): 00078 self.__arg = None 00079 elif self.rc is None: 00080 self.__arg = userArgText() 00081 else: 00082 self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1) 00083 00084 # Get a TEM instance 00085 if self.lat.TEMcnt() == 1: 00086 tem = self.lat.TEM[self.lat.TEM.keys()[0]] 00087 elif self.lat.TEMcnt() > 1: 00088 tem = self.lat.TEM.all() 00089 else: 00090 log.fatal("No TEM(s) found in the schema") 00091 return -1 00092 00093 # clear TEM stats reg 00094 tem.COMMAND_RESPONSE = 0 00095 00096 # clear TEM status reg 00097 tem.STATUS = 0 00098 00099 ccc2 = tem.downCCC(2) # O$GCCC_02 00100 ccc2.LAYER_MASK_1 = 0x3BFD3FFFL 00101 00102 # Two choices for the trigger, GEM and MiniGLT 00103 if self.lat.existsGEM(): 00104 self.trigger( SimpleGasuExample() ) 00105 else: 00106 self.trigger( MiniGLTExample() ) 00107 00108 # A state transition can be rejected by not returning None 00109 return None 00110 00111 def startRun(self): 00112 log.debug("userApplication.startRun()") 00113 00114 if self.isRunFromSuite(): 00115 cnt = self.getSessionVar("eventCount") 00116 if cnt is None: 00117 log.error("Event count is not passed from the suite") 00118 return -1 00119 else: 00120 caption = "Enter number of triggers to take" 00121 if self.rc is None: 00122 cnt = self.__arg.getValue(caption) 00123 else: 00124 cnt = self.rc.execGUImethod(self.__arg.getValue, caption) 00125 00126 # The user pressed 'Cancel' 00127 if cnt is None: return -1 00128 self.__cnt = cnt 00129 00130 # Spawn a thread to synchronize commands with events 00131 self.__cmdSynchQuit = False 00132 00133 # A state transition can be rejected by not returning None 00134 return None 00135 00136 def stopRun(self): 00137 log.debug("userApplication.stopRun()") 00138 00139 if self.getBadEvents() == 0 and self.getErrorEvents() == 0: 00140 self.setCompletionStatus(self.COMPL_STATUS_PASSED) 00141 else: 00142 self.setCompletionStatus(self.COMPL_STATUS_FAILED) 00143 00144 self.setSessionVar("completionStatus", self.getCompletionStatus()) 00145 00146 if self.getSessionVar("test") is not None: 00147 self.setSessionVar("test", self.getSessionVar("test") + "d") 00148 00149 self.__cmdSynchQuit = True 00150 self.__eventSem.release() 00151 #self.__cmdSynch.join() 00152 00153 # The STOP_RUN transition can not be rejected 00154 00155 def resume(self): 00156 log.debug("userApplication.resume()") 00157 00158 # Issue self trigger to make up for the one that was lost during PAUSE 00159 self.trigger().solicit() 00160 00161 return None 00162 00163 def stop(self): 00164 log.debug("userApplication.stop()") 00165 00166 return self.stopRun() 00167 00168 def teardown(self): 00169 log.debug("userApplication.teardown()") 00170 # Allow the C++ object to be deleted 00171 if self.rc is not None and self.__arg is not None: 00172 self.__arg.deleteLater() 00173 00174 def process(self, (status, buffer)): 00175 "Method called back for each data event taken" 00176 ##log.debug("userApplication.process()") 00177 00178 evtCli = self.evtCli 00179 00180 if status != 0: 00181 if evtCli.isGGLTStatus(): 00182 log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr())) 00183 elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR): 00184 log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr())) 00185 self.__eventSem.release() 00186 return 00187 try: 00188 # In the future this event may contain additional data 00189 if evtCli.isSweepEvent(): return 00190 except: 00191 # Event summary word inaccessible, handle the bad event here 00192 log.exception("") 00193 return 00194 00195 ###evtCli.evDumpCAL_LogAccepts(); 00196 ###print "" 00197 ###evtCli.evDumpCAL_Logs(); 00198 #~ #print "" 00199 #~ #evtCli.evDumpTKR() 00200 ###evtCli.evDumpTEM_Error() 00201 ###evtCli.evDumpDiagnostic() 00202 ###for acc in evtCli.evt.CAL_LogAccepts: 00203 ### print "CAL Log Accept: 0x%08x" % acc.ui 00204 00205 ###for data in evtCli.evt.CAL_LogData: 00206 ### print "CAL Log Data: 0x%08x" % data.ui 00207 #~ sum = evtCli.evt.summary 00208 ###evtCli.evDumpSummary() 00209 00210 # Get next event triggered 00211 self.__eventSem.release() 00212 00213 #def __commandSynch(self, count): 00214 def commandSynch(self): 00215 "Method called by the command synchronization task" 00216 import time 00217 trigger = self.trigger() 00218 eventSem = self.__eventSem 00219 # Drain the semaphore release count 00220 # Handles the case when the stop run release collided with a trigger release 00221 while eventSem.acquire(0): pass 00222 00223 t0 = time.time() 00224 00225 # Compensate for the extra CMD_SELF_TRIGGER below 00226 cnt = 1 00227 count = self.__cnt 00228 00229 # Wait for START_RUN to enable triggers 00230 trigger.waitForMaskEnable() 00231 00232 trigger.solicit() # Issue an internal trigger 00233 eventSem.acquire() # Wait for the event to be processed 00234 00235 t1 = trigger.getEnableTime() # get the last trigger enable time from GLT 00236 00237 while cnt < count and not self.__cmdSynchQuit: 00238 cnt += 1 00239 trigger.solicit() # Issue an internal trigger 00240 time.sleep(.0001) 00241 eventSem.acquire() # Wait for the event to be processed 00242 #trigger.disable() # Disable triggers 00243 # Do stuff 00244 #trigger.enable() # Enable triggers 00245 00246 t2 = trigger.getTimeStamp() # Get the last trigger timestamp 00247 # When we get here the triggers should still be enabled. 00248 # If the glt.MASK needs to be set through any other means 00249 # then it needs to be restored to its SETUP value here. 00250 00251 if t1 is None: 00252 t1 = t0 00253 if t2 is None: 00254 t2 = time.time() 00255 dT = t2 - t1 00256 if dT == 0.0: dT = 0.000001 00257 log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \ 00258 (self.getName(), self.evtCnt, dT, self.evtCnt/dT)) 00259 00260 # Get out of waiting when in batch or standalone mode 00261 self.sync() 00262 00263 # execute the GUI functions for stopRun, just in case 00264 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00265 if self.rc is not None: 00266 self.rc.doStop() 00267 00268 def wait(self): 00269 self.__cmdSynchSem.acquire() 00270 00271 def sync(self): 00272 if __name__ == "__main__" or self.isRunFromSuite(): 00273 self.__cmdSynchSem.release() 00274 00275 00276 # Standalone mode: 00277 if __name__ == "__main__": 00278 from LATTE.runcontrol.RunControlCommon import RunControlCommon 00279 00280 rcCommon = RunControlCommon() 00281 rcCommon.initialize() 00282 rcCommon.setLoggingLevel("INFO") 00283 rcCommon.connect() 00284 ua = userApplication(None, 321, rcCommon) 00285 ua.rcSetup() 00286 ua.rcStartRun() 00287 ua.wait() 00288 ua.rcStopRun() 00289 ua.rcTeardown()