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 test script which uses the custom event client testEvtCli" 00012 __author__ = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = ("$Date: 2005/03/21 17:58:13 $").split(' ')[1] 00014 __version__ = "$Revision: 1.5 $" 00015 __release__ = "$Name: R04-12-00 $" 00016 __credits__ = "SLAC" 00017 00018 import LATTE.copyright_SLAC 00019 00020 import threading 00021 import logging as log 00022 #from rcHouseKeeping import rcHouseKeeping 00023 import time 00024 from support.testEvtCli import * 00025 00026 from support.SimpleGasuExample import * 00027 from support.MiniGLTExample import * 00028 00029 from LATTE.runcontrol.rcTransitions import rcTransitions 00030 from LATTE.runcontrol.ArgumentImpl import ArgumentImpl 00031 00032 TRUE = (0 < 1) 00033 FALSE = not TRUE 00034 00035 # This class puts up a GUI for inputting a value of some sort. It is used by 00036 # the userApplication example to get the number of self triggers to take. 00037 class userArgument(ArgumentImpl): 00038 "GUI for getting the user to input some sort of value." 00039 def __init__(self, parent = None, name = None, modal = 0, fl = 0): 00040 ArgumentImpl.__init__(self, parent, name, modal, fl) 00041 self.__value = 0 00042 self.setCaption("Hello world!") 00043 00044 def OKButtonClicked(self): 00045 self.__value = int(self.ArgumentList.text().latin1()) 00046 self.close() 00047 00048 def CancelButtonClicked(self): 00049 self.__value = None 00050 self.close() 00051 00052 def getValue(self, caption): 00053 self.setCaption(caption) 00054 self.show() 00055 self.exec_loop() 00056 return self.__value 00057 00058 class userArgText(object): 00059 "Text user interface for getting the user to input some sort of value" 00060 def __init__(self): 00061 pass 00062 00063 def getValue(self, caption): 00064 return int(raw_input("%s: " % (caption))) 00065 00066 00067 # Example application implementation. 00068 # Note that the name of the class must be userApplication. 00069 # Look at rcTransitions for names of other transition methods that can be used. 00070 class userApplication(rcTransitions): 00071 "Implmentation class for a user application" 00072 def __init__(self, rc, userId, debug): 00073 rcTransitions.__init__(self, rc, userId, debug) 00074 log.debug("userApplication.__init__()") 00075 self.__eventSem = threading.Semaphore(0) 00076 self.__cmdSynchSem = threading.Semaphore(0) 00077 self.__ec = testEvtCli(debug=debug) 00078 self.setEvtCli(self.__ec) 00079 00080 def getName(self): 00081 return __name__ 00082 00083 def setup(self): 00084 log.debug("userApplication.setup()") 00085 00086 #self.__ec.open("c:/temp/ebf040218020523.arch") 00087 00088 if self.rc is None: 00089 self.__arg = userArgText() 00090 else: 00091 self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1) 00092 00093 # Get a TEM instance 00094 if self.lat.TEMcnt() == 1: 00095 tem = self.lat.TEM[self.lat.TEM.keys()[0]] 00096 elif self.lat.TEMcnt() > 1: 00097 tem = self.lat.TEM.all() 00098 else: 00099 log.fatal("No TEM(s) found in the schema") 00100 return -1 00101 00102 # reset the TEM since we are going to modify DATA_MASKS 00103 tem.CMD_RESET = 1 00104 00105 # clear TEM stats reg 00106 tem.COMMAND_RESPONSE = 0 00107 00108 # clear TEM status reg 00109 tem.STATUS = 0 00110 00111 # enable CAL, disable TKR, no diag # 0x10FF for diag 00112 tem.DATA_MASKS = 0x00FF 00113 00114 # TEM config reg # set TEM timeout 00115 tem.CONFIGURATION = 0 00116 00117 #status = gTEMread( __GT, temId, TEM_REG_CONFIGURATION, &payload); 00118 #printf("tem config reg = 0x%08x\n", payload); 00119 00120 # enable output in our GCCCs 00121 # broadcast load of GCCC_REG_CONFIGURATION 00122 00123 bcast_ccc = tem.allCCC() 00124 bcast_ccc.CONFIGURATION = 0x80000000L 00125 00126 # disable all GCRCs in all GCCCs via broadcast # GCCC_REG_LAYER_MASK_0, GCCC_REG_LAYER_MASK_1 00127 bcast_ccc.LAYER_MASK_0 = 0xFFFFFFFFL 00128 bcast_ccc.LAYER_MASK_1 = 0xFFFFFFFFL 00129 ccc0 = tem.downCCC(0) # O$GCCC_00 00130 ccc0.LAYER_MASK_0 = 0xFFFF0000L 00131 ccc0.LAYER_MASK_1 = 0xFFFF000FL 00132 ccc2 = tem.downCCC(2) # O$GCCC_02 00133 ccc2.LAYER_MASK_0 = 0xFFFF0000L 00134 ccc2.LAYER_MASK_1 = 0xFFFF0000L 00135 00136 # config GCFE for calibration -- range 0 first 00137 bcast_cfe = tem.allCCC().allCRC().allCFE() 00138 bcast_cfe.CONFIG_0 = 0x00 00139 bcast_cfe.CONFIG_1 = 0x36 00140 bcast_cfe.FLE_DAC = 0x55 00141 bcast_cfe.FHE_DAC = 0x55 00142 bcast_cfe.LOG_ACPT = 0x10 00143 bcast_cfe.RNG_ULD_DAC = 0x7F 00144 bcast_cfe.REF_DAC = 0x7f 00145 00146 # config GCRC for calibration 00147 bcast_crc = tem.allCCC().allCRC() 00148 bcast_crc.DELAY_1 = 0xFF 00149 bcast_crc.DELAY_2 = 0xFF 00150 bcast_crc.DELAY_3 = 0xFF 00151 bcast_crc.DAC = 0x42FE 00152 bcast_crc.DAC = 0x42FE 00153 00154 # large timeouts for all GCCCs 00155 # broadcast load of GCCC_REG_EVENT_TIMEOUTS 00156 bcast_ccc.EVENT_TIMEOUTS = 0x0 00157 #status = gGCCCread( __GT, temId, 1, GCCC_REG_EVENT_TIMEOUTS, &payload); 00158 #printf("gccc register event timeouts = 0x%08x\n", payload); 00159 00160 # Register environment variables for housekeeping 00161 #hsk = self.getHSK() 00162 #regs = [tem.regs['data_masks'], ccc2.regs['layer_mask_1']] 00163 #hsk.addEnvRegs(regs) 00164 #hsk.setUpdateInterval(1) 00165 00166 # Two choices for the trigger, GEM and MiniGLT 00167 if self.lat.existsGEM(): 00168 self.trigger( SimpleGasuExample() ) 00169 else: 00170 self.trigger( MiniGLTExample() ) 00171 00172 # A state transition can be rejected by not returning None 00173 return None 00174 00175 def startRun(self): 00176 log.debug("userApplication.startRun()") 00177 00178 caption = "Enter number of triggers to take" 00179 if self.rc is None: 00180 cnt = self.__arg.getValue(caption) 00181 else: 00182 cnt = self.rc.execGUImethod(self.__arg.getValue, caption) 00183 00184 # The user pressed 'Cancel' 00185 if cnt is None: return -1 00186 self.__cnt = cnt 00187 00188 # Spawn a thread to synchronize commands with events 00189 self.__cmdSynchQuit = FALSE 00190 #cmdSynch = threading.Thread(None, self.__commandSynch, 'CmdSynch', 00191 # (cnt, self.__eventSem)) 00192 #cmdSynch.start() 00193 #self.__cmdSynch = cmdSynch 00194 00195 # A state transition can be rejected by not returning None 00196 return None 00197 00198 def stopRun(self): 00199 log.debug("userApplication.stopRun()") 00200 00201 self.__cmdSynchQuit = TRUE 00202 self.__eventSem.release() 00203 #self.__cmdSynch.join(2.0) 00204 #if self.__cmdSynch.isAlive(): 00205 # log.error("%s.%s: cmdSynch thread did not exit when expected" % \ 00206 # (self.getName(), "stopRun")) 00207 00208 # The STOP_RUN transition can not be rejected 00209 00210 def resume(self): 00211 log.debug("userApplication.resume()") 00212 00213 # Issue self trigger to make up for the one that was lost during PAUSE 00214 self.trigger().solicit() 00215 00216 return None 00217 00218 def stop(self): 00219 log.debug("userApplication.stop()") 00220 00221 return self.stopRun() 00222 00223 def process(self, (status, buffer)): 00224 "Method called back for each data event taken" 00225 #log.debug("userApplication.process()") 00226 00227 evtCli = self.evtCli 00228 00229 if status != 0: 00230 if evtCli.isGGLTStatus(): 00231 log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr())) 00232 elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR): 00233 log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr())) 00234 self.__eventSem.release() 00235 return 00236 try: 00237 # In the future this event may contain additional data 00238 if evtCli.isSweepEvent(): 00239 log.debug("SWEEP EVENT") 00240 return 00241 except: 00242 # Event summary word inaccessible, handle the bad event here 00243 log.exception("") 00244 return 00245 00246 #evtCli.evDumpCAL_LogAccepts(); 00247 ###print "" 00248 #evtCli.evDumpCAL_Logs(); 00249 #~ #print "" 00250 #~ #evtCli.evDumpTKR() 00251 ###evtCli.evDumpTEM_Error() 00252 ###evtCli.evDumpDiagnostic() 00253 ###for acc in evtCli.evt.CAL_LogAccepts: 00254 ### print "CAL Log Accept: 0x%08x" % acc.ui 00255 00256 ###for data in evtCli.evt.CAL_LogData: 00257 ### print "CAL Log Data: 0x%08x" % data.ui 00258 #~ sum = evtCli.evt.summary 00259 ###evtCli.evDumpSummary() 00260 00261 # Get next event triggered 00262 self.__eventSem.release() 00263 00264 00265 #def __commandSynch(self, count): 00266 def commandSynch(self): 00267 "Method called by the command synchronization task" 00268 import time 00269 trigger = self.trigger() 00270 eventSem = self.__eventSem 00271 00272 # Drain the semaphore release count 00273 # Handles the case when the stop run release collided with a trigger release 00274 while eventSem.acquire(0): pass 00275 00276 t0 = time.time() 00277 00278 # Compensate for the extra CMD_SELF_TRIGGER below 00279 cnt = 1 00280 count = self.__cnt 00281 00282 # Wait for START_RUN to enable triggers 00283 trigger.waitForMaskEnable() 00284 00285 trigger.solicit() # Issue an internal trigger 00286 eventSem.acquire() # Wait for the event to be processed 00287 00288 t1 = trigger.getEnableTime() # get the last trigger enable time from GLT 00289 00290 while cnt < count and not self.__cmdSynchQuit: 00291 cnt += 1 00292 trigger.solicit() # Issue an internal trigger 00293 time.sleep(.0001) 00294 eventSem.acquire() # Wait for the event to be processed 00295 #trigger.disable() # Disable triggers 00296 # Do stuff 00297 #trigger.enable() # Enable triggers 00298 00299 t2 = trigger.getTimeStamp() # Get the last trigger timestamp 00300 # When we get here the triggers should still be enabled. 00301 # If the glt.MASK needs to be set through any other means 00302 # then it needs to be restored to its SETUP value here. 00303 00304 if t1 is None: 00305 t1 = t0 00306 if t2 is None: 00307 t2 = time.time() 00308 dT = t2 - t1 00309 if dT == 0.0: dT = 0.000001 00310 log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \ 00311 (self.getName(), self.evtCnt, dT, self.evtCnt/dT)) 00312 00313 # Get out of waiting when in suite or standalone mode 00314 self.sync() 00315 00316 # execute the GUI functions for stopRun, just in case 00317 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00318 if self.rc is not None: 00319 self.rc.doStop() 00320 00321 def wait(self): 00322 self.__cmdSynchSem.acquire() 00323 00324 def sync(self): 00325 if __name__ == "__main__" or self.isRunFromSuite(): 00326 self.__cmdSynchSem.release() 00327 00328 00329 # Standalone mode: 00330 if __name__ == "__main__": 00331 import os 00332 log.basicConfig() 00333 log.getLogger("").setLevel(log.DEBUG) 00334 ua = userApplication(None, 321, 0) 00335 ua.rcSetup(os.path.join(os.environ['ONLINE_ROOT'], 'repos/simpleTemSchema.xml')) 00336 ua.rcStartRun() 00337 ua.wait() 00338 ua.rcStopRun() 00339 ua.rcTeardown() 00340 00341 # History: 00342 # $Log: testAppEvtCli.py,v $ 00343 # Revision 1.5 2005/03/21 17:58:13 claus 00344 # Modified to use the first TEM found in the schema, if only one is there, or 00345 # broadcast to all TEMs if there are multiple. 00346 # 00347 # Revision 1.4 2004/10/22 20:32:48 stuvi 00348 # Fixed log.exception() 00349 # 00350 # Revision 1.3 2004/08/18 18:00:15 stuvi 00351 # Updated for LATTE 4. 00352 # All hippo functions go through the Qt GUI bridge now. 00353 # 00354 # Revision 1.2 2004/08/07 02:10:27 stuvi 00355 # no message 00356 # 00357 # Revision 1.1 2004/08/06 18:59:26 stuvi 00358 # Application for testing custom event client functionality 00359 # 00360 # Revision 1.3 2004/05/03 21:19:47 stuvi 00361 # Moved non-Runcontrol scripts to the support directory and modified imports accordingly. 00362 # 00363 # Revision 1.2 2004/03/10 22:24:51 panetta 00364 # Upgraded trigger interface. 00365 # Removed dependencies on self.glt. 00366 # 00367 # Revision 1.1 2004/02/20 00:34:37 stuvi 00368 # Sample custom event client implementation and test app 00369 # 00370 #