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