00001 #!/usr/local/bin/python 00002 # 00003 # Copyright 2003 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 EBF event handling test application" 00012 __author__ = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = "2/25/2003" 00014 __version__ = "$Revision: 1.3 $" 00015 __credits__ = "SLAC" 00016 00017 import LATTE.copyright_SLAC 00018 00019 import threading 00020 import logging as log 00021 00022 from LATTE.runcontrol.rcTransitions import rcTransitions 00023 from LATTE.runcontrol.ArgumentImpl import ArgumentImpl 00024 00025 from support.SimpleGasuExample import * 00026 from support.MiniGLTExample import * 00027 00028 import LDF 00029 import LDFdumper as LD 00030 00031 class LATcomponentIterator(LD.LATcomponentIterator): 00032 def __init__(self): 00033 LDF.LATcomponentIterator.__init__(self) 00034 self.__calSrc = None 00035 self.__tkrContributionIterator = None 00036 print "LATcomponentIterator.__init__" 00037 00038 def UDFcomponent(self, event, ebfContribution): 00039 print "" 00040 print "Undefined EBF component" 00041 LD.EBFcontribution(event, ebfContribution).dumpCommon(" ") 00042 LD.EBFcontribution(event, ebfContribution).dump(" ") 00043 return 0 00044 00045 def OSWcomponent(self, event, oswContribution): 00046 # Assuming this is always the first component seen, dump the event 00047 print "" 00048 LD.EBFevent(event).dump() 00049 print "" 00050 print "OSW:" 00051 LD.EBFcontribution(event, oswContribution).dumpCommon(" ") 00052 oswContribIter = LD.OSWcontributionIterator(event, oswContribution) 00053 print " OSW:" 00054 oswContribIter.dump(" ") 00055 return 0 00056 00057 def GLTcomponent(self, event, gltContribution): 00058 print "" 00059 print "GLT:" 00060 LD.EBFcontribution(event, gltContribution).dumpCommon(" ") 00061 LD.GLTcontribution(event, gltContribution).dump(" ") 00062 return 0 00063 00064 def GEMcomponent(self, event, gemContribution): 00065 print "" 00066 print "GEM:" 00067 LD.EBFcontribution(event, gemContribution).dumpCommon(" ") 00068 LD.GEMcontribution(event, gemContribution).dump(" ") 00069 return 0 00070 00071 def ACDcomponent(self, event, aemContribution): 00072 print "" 00073 print "AEM:" 00074 LD.EBFcontribution(event, aemContribution).dumpCommon(" ") 00075 aemContribIter = LD.AEMcontributionIterator(event, aemContribution) 00076 print " ACD:" 00077 aemContribIter.dump(" ") 00078 return 0 00079 00080 def CALcomponent(self, event, calContribution): 00081 self.__calSrc = LD.LATPcellHeader.source(calContribution.header()) 00082 print "" 00083 print "TEM %2d:" % (self.__calSrc) 00084 LD.EBFcontribution(event, calContribution).dumpCommon(" ") 00085 calContribIter = LD.CALcontributionIterator(event,calContribution) 00086 calContribIter.dump(" ") 00087 self.CALend(calContribIter.CALend()) 00088 return 0 00089 00090 def TKRcomponent(self, event, tkrContribution): 00091 if self.__calSrc != LD.LATPcellHeader.source(tkrContribution.header()): 00092 print "" 00093 print "TEM %2d:" % (LD.LATPcellHeader.source(tkrContribution.header())) 00094 LD.EBFcontribution(event, tkrContribution).dumpCommon(" ") 00095 tkrContribIter = LD.TKRcontributionIterator(event, tkrContribution) 00096 tkrContribIter.dump(" ") 00097 self.__tkrContributionIterator = tkrContribIter 00098 if tkrContribIter.diagnostic() is not None: 00099 self.TKRend(tkrContribIter.diagnostic()) 00100 return 0 00101 00102 # This class puts up a GUI for inputting a value of some sort. It is used by 00103 # the userApplication example to get the number of self triggers to take. 00104 class userArgument(ArgumentImpl): 00105 "GUI for getting the user to input some sort of value." 00106 def __init__(self, parent = None, name = None, modal = 0, fl = 0): 00107 ArgumentImpl.__init__(self, parent, name, modal, fl) 00108 self.__value = 0 00109 self.setCaption("Hello world!") 00110 00111 def OKButtonClicked(self): 00112 self.__value = int(self.ArgumentList.text().latin1()) 00113 self.close() 00114 00115 def getValue(self, caption): 00116 self.setCaption(caption) 00117 self.show() 00118 self.exec_loop() 00119 return self.__value 00120 00121 class userArgText(object): 00122 "Text user interface for getting the user to input some sort of value" 00123 def __init__(self): 00124 pass 00125 00126 def getValue(self, caption): 00127 return int(raw_input("%s: " % (caption))) 00128 00129 00130 # Example application implementation. 00131 # Note that the name of the class must be userApplication. 00132 # Look at rcTransitions for names of other transition methods that can be used. 00133 class userApplication(rcTransitions): 00134 "Implmentation class for a user application" 00135 def __init__(self, gui, userId, debug): 00136 rcTransitions.__init__(self, gui, userId, debug) 00137 log.debug("userApplication.__init__()") 00138 self.__eventSem = threading.Semaphore(0) 00139 self.__cmdSynchSem = threading.Semaphore(0) 00140 self.__lci = LATcomponentIterator() 00141 self.__ldbi = LDF.LATdataBufferIterator(self.__lci) 00142 00143 def getName(self): 00144 return __name__ 00145 00146 def setup(self): 00147 log.debug("userApplication.setup()") 00148 00149 if self.rc is None: 00150 self.__arg = userArgText() 00151 else: 00152 self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1) 00153 00154 # Get a TEM instance 00155 if self.lat.TEMcnt() == 1: 00156 tem = self.lat.TEM[self.lat.TEM.keys()[0]] 00157 elif self.lat.TEMcnt() > 1: 00158 tem = self.lat.TEM.all() 00159 else: 00160 log.fatal("No TEM(s) found in the schema") 00161 return -1 00162 00163 # reset the TEM since we are going to modify DATA_MASKS 00164 tem.CMD_RESET = 1 00165 00166 # clear TEM stats reg 00167 tem.COMMAND_RESPONSE = 0 00168 00169 # clear TEM status reg 00170 tem.STATUS = 0 00171 00172 # enable CAL, disable TKR, no diag # 0x10FF for diag 00173 tem.DATA_MASKS = 0x00FF 00174 00175 # TEM config reg # set TEM timeout 00176 tem.CONFIGURATION = 0 00177 00178 #status = gTEMread( __GT, temId, TEM_REG_CONFIGURATION, &payload); 00179 #printf("tem config reg = 0x%08x\n", payload); 00180 00181 # enable output in our GCCCs 00182 # broadcast load of GCCC_REG_CONFIGURATION 00183 00184 bcast_ccc = tem.allCCC() 00185 bcast_ccc.CONFIGURATION = 0x80000000L 00186 00187 # disable all GCRCs in all GCCCs via broadcast # GCCC_REG_LAYER_MASK_0, GCCC_REG_LAYER_MASK_1 00188 bcast_ccc.LAYER_MASK_0 = 0xFFFFFFFFL 00189 bcast_ccc.LAYER_MASK_1 = 0xFFFFFFFFL 00190 ccc2 = tem.downCCC(2) # O$GCCC_02 00191 ccc2.LAYER_MASK_1 = 0x3BFD3FFF 00192 00193 # large timeouts for all GCCCs 00194 # broadcast load of GCCC_REG_EVENT_TIMEOUTS 00195 bcast_ccc.EVENT_TIMEOUTS = 0x0 00196 #status = gGCCCread( __GT, temId, 1, GCCC_REG_EVENT_TIMEOUTS, &payload); 00197 #printf("gccc register event timeouts = 0x%08x\n", payload); 00198 00199 # Two choices for the trigger, GEM and MiniGLT 00200 if self.lat.existsGEM(): 00201 self.trigger( SimpleGasuExample() ) 00202 else: 00203 self.trigger( MiniGLTExample() ) 00204 00205 # A state transition can be rejected by not returning None 00206 return None 00207 00208 def startRun(self): 00209 log.debug("userApplication.startRun()") 00210 00211 caption = "Enter number of triggers to take" 00212 if self.rc is None: 00213 cnt = self.__arg.getValue(caption) 00214 else: 00215 cnt = self.rc.execGUImethod(self.__arg.getValue, caption) 00216 00217 # The user pressed 'Cancel' 00218 if cnt is None: return -1 00219 self.__cnt = cnt 00220 00221 # Spawn a thread to synchronize commands with events 00222 # This must happen after triggers are enabled 00223 self.__cmdSynchQuit = False 00224 00225 # A state transition can be rejected by not returning None 00226 return None 00227 00228 def stopRun(self): 00229 self.setCompletionStatus(self.COMPL_STATUS_SUCCESS) 00230 self.__cmdSynchQuit = True 00231 self.__eventSem.release() 00232 00233 # The STOP_RUN transition can not be rejected 00234 00235 def resume(self): 00236 # Issue self trigger to make up for the one that was lost during PAUSE 00237 self.trigger().solicit() 00238 00239 return None 00240 00241 def stop(self): 00242 return self.stopRun() 00243 00244 def process(self, (status, buffer)): 00245 "Method called back for each data event taken" 00246 ###log.debug("userApplication.process()") 00247 00248 evtCli = self.evtCli 00249 00250 if status != 0: 00251 if evtCli.isGGLTStatus(): 00252 log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr())) 00253 elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR): 00254 log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr())) 00255 self.__eventSem.release() 00256 return 00257 00258 try: 00259 # In the future this event may contain additional data 00260 if evtCli.isSweepEvent(): return 00261 except: 00262 # Event summary word inaccessible, handle the bad event here 00263 import gutil 00264 gutil.logException() 00265 return 00266 00267 self.__ldbi.iterate(buffer, len(buffer)) 00268 00269 # Get next event triggered 00270 self.__eventSem.release() 00271 00272 def commandSynch(self): 00273 "Method called by the command synchronization task" 00274 import time 00275 trigger = self.trigger() 00276 eventSem = self.__eventSem 00277 00278 # Drain the semaphore release count 00279 # Handles the case when the stop run release collided with a trigger release 00280 while eventSem.acquire(0): pass 00281 00282 t0 = time.time() 00283 00284 # Compensate for the extra CMD_SELF_TRIGGER below 00285 cnt = 1 00286 count = self.__cnt 00287 00288 # Wait for START_RUN to enable triggers 00289 trigger.waitForMaskEnable() 00290 00291 trigger.solicit() # Issue an internal trigger 00292 eventSem.acquire() # Wait for the event to be processed 00293 00294 t1 = trigger.getEnableTime() # get the last trigger enable time from GLT 00295 00296 while cnt < count and not self.__cmdSynchQuit: 00297 cnt += 1 00298 trigger.solicit() # Issue an internal trigger 00299 time.sleep(.0001) 00300 eventSem.acquire() # Wait for the event to be processed 00301 #trigger.disable() # Disable triggers 00302 # Do stuff 00303 #trigger.enable() # Enable triggers 00304 00305 t2 = trigger.getTimeStamp() # Get the last trigger timestamp 00306 00307 if t1 is None: 00308 t1 = t0 00309 if t2 is None: 00310 t2 = time.time() 00311 dT = t2 - t1 00312 if dT == 0.0: dT = 0.000001 00313 log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \ 00314 (self.getName(), self.evtCnt, dT, self.evtCnt/dT)) 00315 00316 # Get out of waiting when in standalone mode 00317 self.sync() 00318 00319 # execute the GUI functions for stopRun, just in case 00320 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00321 if self.gui is not None: 00322 self.gui.doStopRun() 00323 00324 def wait(self): 00325 self.__cmdSynchSem.acquire() 00326 00327 def sync(self): 00328 if __name__ == "__main__" or self.isRunFromSuite(): 00329 self.__cmdSynchSem.release() 00330 00331 00332 # Standalone mode: 00333 if __name__ == "__main__": 00334 import os 00335 log.basicConfig() 00336 log.getLogger("").setLevel(log.DEBUG) 00337 ua = userApplication(None, 321, 1) 00338 ua.rcSetup(os.path.join(os.environ['ONLINE_ROOT'], 'repos/simpleTemSchema.xml')) 00339 ua.rcStartRun() 00340 ua.wait() 00341 ua.rcStopRun() 00342 ua.rcTeardown() 00343 00344 # History: 00345 # $Log: testAppLDFdump.py,v $ 00346 # Revision 1.3 2006/04/05 15:40:30 perazzo 00347 # LDFdumper is now in PYTHONPATH 00348 # 00349 # Revision 1.2 2005/03/21 17:58:13 claus 00350 # Modified to use the first TEM found in the schema, if only one is there, or 00351 # broadcast to all TEMs if there are multiple. 00352 # 00353 # Revision 1.1 2004/08/18 18:00:15 stuvi 00354 # Updated for LATTE 4. 00355 # All hippo functions go through the Qt GUI bridge now. 00356 # 00357 # Revision 1.3 2004/05/03 21:19:47 stuvi 00358 # Moved non-Runcontrol scripts to the support directory and modified imports accordingly. 00359 # 00360 # Revision 1.2 2004/04/02 23:57:53 claus 00361 # xxxComponent methods must return a status value. 00362 # 00363 # Revision 1.1 2004/04/02 22:31:46 claus 00364 # Event dumper using the LDF library and the new LATdataBufferIterator class. 00365 # 00366 # Revision 1.8 2004/03/10 22:24:51 panetta 00367 # Upgraded trigger interface. 00368 # Removed dependencies on self.glt. 00369 # 00370 # Revision 1.7 2003/11/04 18:30:53 panetta 00371 # Changed the commandSynch logic so that the enableMask() call would not pose a threat to snapshot taking. 00372 # 00373 # Revision 1.6 2003/10/31 01:09:37 panetta 00374 # 1) Moved register writes from startRun to setup 00375 # 2) Added GLT enabling logic to __commandSynch 00376 # 3) Gave example of getting the start/stop time from the hardware/event stream 00377 # 00378 # Revision 1.5 2003/06/13 23:26:24 stuvi 00379 # Added TEM reset 00380 # 00381 # Revision 1.4 2003/04/01 21:04:59 stuvi 00382 # Fixed event count discrepancy when the run is stopped in the middle. 00383 # 00384 # Revision 1.3 2003/03/26 21:59:36 stuvi 00385 # Fixed standalone mode 00386 # 00387 # Revision 1.2 2003/03/13 00:06:34 claus 00388 # Interface changes plus diagnostic and error dumps 00389 # 00390 # Revision 1.1 2003/03/10 21:49:56 claus 00391 # RunControl example of an event dumper 00392 # 00393 #