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 that tests event timeouts" 00012 __author__ = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = "11/21/2002" 00014 __version__ = "$Revision: 1.3 $" 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 #from rcHouseKeeping import rcHouseKeeping 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 00072 def getName(self): 00073 return __name__ 00074 00075 def setup(self): 00076 log.debug("userApplication.setup()") 00077 00078 if self.rc is None: 00079 self.__arg = userArgText() 00080 else: 00081 self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1) 00082 00083 # Get a TEM instance 00084 if self.lat.TEMcnt() == 1: 00085 tem = self.lat.TEM[self.lat.TEM.keys()[0]] 00086 elif self.lat.TEMcnt() > 1: 00087 tem = self.lat.TEM.all() 00088 else: 00089 log.fatal("No TEM(s) found in the schema") 00090 return -1 00091 00092 # reset the TEM since we are going to modify DATA_MASKS 00093 #tem.CMD_RESET = 1 00094 00095 # clear TEM stats reg 00096 tem.COMMAND_RESPONSE = 0 00097 00098 # clear TEM status reg 00099 tem.STATUS = 0 00100 00101 # enable CAL, disable TKR, no diag # 0x10FF for diag 00102 #tem.DATA_MASKS = 0x00FF 00103 00104 # TEM config reg # set TEM timeout 00105 #tem.CONFIGURATION = 0 00106 00107 #status = gTEMread( __GT, temId, TEM_REG_CONFIGURATION, &payload); 00108 #printf("tem config reg = 0x%08x\n", payload); 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 #ccc2 = tem.downCCC(2) # O$GCCC_02 00120 #ccc2.LAYER_MASK_1 = 0x3BFD3FFFL 00121 00122 # large timeouts for all GCCCs 00123 # broadcast load of GCCC_REG_EVENT_TIMEOUTS 00124 #bcast_ccc.EVENT_TIMEOUTS = 0xFFFFFFFFL 00125 #status = gGCCCread( __GT, temId, 1, GCCC_REG_EVENT_TIMEOUTS, &payload); 00126 #printf("gccc register event timeouts = 0x%08x\n", payload); 00127 00128 # Register environment variables for housekeeping 00129 #hsk = self.getHSK() 00130 #regs = [tem.regs['data_masks'], ccc2.regs['layer_mask_1']] 00131 #hsk.addEnvRegs(regs) 00132 #hsk.setUpdateInterval(1) 00133 00134 # Two choices for the trigger, GEM and MiniGLT 00135 if self.lat.existsGEM(): 00136 self.trigger( SimpleGasuExample() ) 00137 else: 00138 self.trigger( MiniGLTExample() ) 00139 00140 self.evtCli.setTimeoutEnabled(1) 00141 00142 # A state transition can be rejected by not returning None 00143 return None 00144 00145 def startRun(self): 00146 log.debug("userApplication.startRun()") 00147 00148 caption = "Enter number of triggers to take" 00149 if self.rc is None: 00150 cnt = self.__arg.getValue(caption) 00151 else: 00152 cnt = self.rc.execGUImethod(self.__arg.getValue, caption) 00153 00154 # The user pressed 'Cancel' 00155 if cnt is None: return -1 00156 self.__cnt = cnt 00157 00158 # Spawn a thread to synchronize commands with events 00159 self.__cmdSynchQuit = False 00160 00161 # A state transition can be rejected by not returning None 00162 return None 00163 00164 def stopRun(self): 00165 log.debug("userApplication.stopRun()") 00166 00167 self.setCompletionStatus(self.COMPL_STATUS_PASSED) 00168 self.__cmdSynchQuit = True 00169 self.__eventSem.release() 00170 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 import gutil 00212 gutil.logException() 00213 return 00214 00215 ###evtCli.evDumpCAL_LogAccepts(); 00216 ###print "" 00217 ###evtCli.evDumpCAL_Logs(); 00218 #~ #print "" 00219 #~ #evtCli.evDumpTKR() 00220 ###evtCli.evDumpTEM_Error() 00221 ###evtCli.evDumpDiagnostic() 00222 ###for acc in evtCli.evt.CAL_LogAccepts: 00223 ### print "CAL Log Accept: 0x%08x" % acc.ui 00224 00225 ###for data in evtCli.evt.CAL_LogData: 00226 ### print "CAL Log Data: 0x%08x" % data.ui 00227 #~ sum = evtCli.evt.summary 00228 ###evtCli.evDumpSummary() 00229 00230 # Get next event triggered 00231 self.__eventSem.release() 00232 00233 00234 #def __commandSynch(self, count): 00235 def commandSynch(self): 00236 "Method called by the command synchronization task" 00237 import time 00238 trigger = self.trigger() 00239 eventSem = self.__eventSem 00240 00241 # Drain the semaphore release count 00242 # Handles the case when the stop run release collided with a trigger release 00243 while eventSem.acquire(0): pass 00244 00245 t0 = time.time() 00246 00247 # Compensate for the extra CMD_SELF_TRIGGER below 00248 cnt = 1 00249 count = self.__cnt 00250 00251 # Wait for START_RUN to enable triggers 00252 trigger.waitForMaskEnable() 00253 00254 trigger.solicit() # Issue an internal trigger 00255 eventSem.acquire() # Wait for the event to be processed 00256 00257 t1 = trigger.getEnableTime() # get the last trigger enable time from GLT 00258 00259 while cnt < count and not self.__cmdSynchQuit: 00260 cnt += 1 00261 trigger.solicit() # Issue an internal trigger 00262 time.sleep(.0001) 00263 eventSem.acquire() # Wait for the event to be processed 00264 #trigger.disable() # Disable triggers 00265 # Do stuff 00266 #trigger.enable() # Enable triggers 00267 00268 t2 = trigger.getTimeStamp() # Get the last trigger timestamp 00269 00270 if t1 is None: 00271 t1 = t0 00272 if t2 is None: 00273 t2 = time.time() 00274 dT = t2 - t1 00275 if dT == 0.0: dT = 0.000001 00276 log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \ 00277 (self.getName(), self.evtCnt, dT, self.evtCnt/dT)) 00278 00279 # Get out of waiting when in suite or standalone mode 00280 self.sync() 00281 00282 # execute the GUI functions for stopRun, just in case 00283 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00284 if self.rc is not None: 00285 self.rc.doStop() 00286 00287 def wait(self): 00288 self.__cmdSynchSem.acquire() 00289 00290 def sync(self): 00291 if __name__ == "__main__" or self.isRunFromSuite(): 00292 self.__cmdSynchSem.release() 00293 00294 00295 # Standalone mode: 00296 if __name__ == "__main__": 00297 log.basicConfig() 00298 log.getLogger("").setLevel(log.DEBUG) 00299 ua = userApplication(None, 321, 0) 00300 ua.rcSetup('../repos/simpleTemSchema.xml') # Use env var later: kludge for now 00301 ua.rcStartRun() 00302 ua.wait() 00303 ua.rcStopRun() 00304 ua.rcTeardown()