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