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 CAL test application" 00012 __author__ = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = ("$Date: 2005/05/17 01:32:14 $").split(' ')[1] 00014 __version__ = "$Revision: 1.12 $" 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 import time 00023 00024 from LATTE.runcontrol.rcTransitions import rcTransitions 00025 from LATTE.runcontrol.ArgumentImpl import ArgumentImpl 00026 #from rcHouseKeeping import rcHouseKeeping 00027 00028 from support.SimpleGasuExample import * 00029 from support.MiniGLTExample import * 00030 00031 00032 # This class puts up a GUI for inputting a value of some sort. It is used by 00033 # the userApplication example to get the number of self triggers to take. 00034 class userArgument(ArgumentImpl): 00035 "GUI for getting the user to input some sort of value." 00036 def __init__(self, parent = None, name = None, modal = 0, fl = 0): 00037 ArgumentImpl.__init__(self, parent, name, modal, fl) 00038 self.__value = 0 00039 self.setCaption("Hello world!") 00040 00041 def OKButtonClicked(self): 00042 self.__value = int(self.ArgumentList.text().latin1()) 00043 self.close() 00044 00045 def CancelButtonClicked(self): 00046 self.__value = None 00047 self.close() 00048 00049 def getValue(self, caption): 00050 self.setCaption(caption) 00051 self.show() 00052 self.exec_loop() 00053 return self.__value 00054 00055 class userArgText(object): 00056 "Text user interface for getting the user to input some sort of value" 00057 def __init__(self): 00058 pass 00059 00060 def getValue(self, caption): 00061 return int(raw_input("%s: " % (caption))) 00062 00063 00064 # Example application implementation. 00065 # Note that the name of the class must be userApplication. 00066 # Look at rcTransitions for names of other transition methods that can be used. 00067 class userApplication(rcTransitions): 00068 "Implmentation class for a user application" 00069 def __init__(self, rc, userId, debug): 00070 rcTransitions.__init__(self, rc, userId, debug) 00071 log.debug("userApplication.__init__()") 00072 self.__eventSem = threading.Semaphore(0) 00073 self.__cmdSynchSem = threading.Semaphore(0) 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 = 0x10FF 00106 00107 # TEM config reg # set TEM timeout 00108 #tem.CONFIGURATION = 0x00000000 # Set primary 00109 #tem.CONFIGURATION = 0x03000000 # Set redundant 00110 00111 #status = gTEMread( __GT, temId, TEM_REG_CONFIGURATION, &payload); 00112 #printf("tem config reg = 0x%08x\n", payload); 00113 00114 # enable output in our GCCCs 00115 # broadcast load of GCCC_REG_CONFIGURATION 00116 00117 # Move to schema 00118 # bcast_ccc = tem.allCCC() 00119 # bcast_ccc.CONFIGURATION = 0x80000000L 00120 00121 # # disable all GCRCs in all GCCCs via broadcast # GCCC_REG_LAYER_MASK_0, GCCC_REG_LAYER_MASK_1 00122 # bcast_ccc.LAYER_MASK_0 = 0xFFFFFFFFL 00123 # bcast_ccc.LAYER_MASK_1 = 0xFFFFFFFFL 00124 # ccc0 = tem.downCCC(0) # O$GCCC_00 00125 # ccc0.LAYER_MASK_0 = 0xFFFF0000L 00126 # ccc0.LAYER_MASK_1 = 0xFFFF000FL 00127 # ccc2 = tem.downCCC(2) # O$GCCC_02 00128 # ccc2.LAYER_MASK_0 = 0xFFFF0000L 00129 # ccc2.LAYER_MASK_1 = 0xFFFF0000L 00130 00131 # config GCFE for calibration -- range 0 first 00132 #bcast_cfe = tem.allCCC().allCRC().allCFE() 00133 #bcast_cfe.CONFIG_0 = 0x00 00134 #bcast_cfe.CONFIG_1 = 0x36 00135 #bcast_cfe.FLE_DAC = 0x55 00136 #bcast_cfe.FHE_DAC = 0x55 00137 #bcast_cfe.LOG_ACPT = 0x10 00138 #bcast_cfe.RNG_ULD_DAC = 0x7F 00139 #bcast_cfe.REF_DAC = 0x7f 00140 00141 # config GCRC for calibration 00142 #bcast_crc = tem.allCCC().allCRC() 00143 #bcast_crc.DELAY_1 = 0xFF 00144 #bcast_crc.DELAY_2 = 0xFF 00145 #bcast_crc.DELAY_3 = 0xFF 00146 #bcast_crc.DAC = 0x42FE 00147 #bcast_crc.DAC = 0x42FE 00148 00149 # large timeouts for all GCCCs 00150 # broadcast load of GCCC_REG_EVENT_TIMEOUTS 00151 # bcast_ccc.EVENT_TIMEOUTS = 0x0 00152 #status = gGCCCread( __GT, temId, 1, GCCC_REG_EVENT_TIMEOUTS, &payload); 00153 #printf("gccc register event timeouts = 0x%08x\n", payload); 00154 00155 # Register environment variables for housekeeping 00156 #hsk = self.getHSK() 00157 #regs = [tem.regs['data_masks'], ccc2.regs['layer_mask_1']] 00158 #hsk.addEnvRegs(regs) 00159 #hsk.setUpdateInterval(1) 00160 00161 # Two choices for the trigger, GEM and MiniGLT 00162 if self.lat.existsGEM(): 00163 self.trigger( SimpleGasuExample() ) 00164 else: 00165 self.trigger( MiniGLTExample() ) 00166 00167 # A state transition can be rejected by not returning None 00168 return None 00169 00170 def startRun(self): 00171 log.debug("userApplication.startRun()") 00172 00173 caption = "Enter number of triggers to take" 00174 if self.rc is None: 00175 cnt = self.__arg.getValue(caption) 00176 else: 00177 cnt = self.rc.execGUImethod(self.__arg.getValue, caption) 00178 00179 # The user pressed 'Cancel' 00180 if cnt is None: return -1 00181 self.__cnt = cnt 00182 00183 if self.rc is not None: 00184 self.getParameterVerifier().add(caption, cnt) 00185 00186 # Spawn a thread to synchronize commands with events 00187 self.__cmdSynchQuit = False 00188 00189 # A state transition can be rejected by not returning None 00190 return None 00191 00192 def stopRun(self): 00193 log.debug("userApplication.stopRun()") 00194 00195 if self.getBadEvents() == 0 and self.getErrorEvents() == 0: 00196 self.setCompletionStatus(self.COMPL_STATUS_PASSED) 00197 else: 00198 self.setCompletionStatus(self.COMPL_STATUS_FAILED) 00199 00200 self.__cmdSynchQuit = True 00201 self.__eventSem.release() 00202 00203 # The STOP_RUN transition can not be rejected 00204 00205 def resume(self): 00206 log.debug("userApplication.resume()") 00207 00208 # Issue self trigger to make up for the one that was lost during PAUSE 00209 self.trigger().solicit() 00210 00211 return None 00212 00213 def stop(self): 00214 log.debug("userApplication.stop()") 00215 00216 return self.stopRun() 00217 00218 def teardown(self): 00219 log.debug("userApplication.teardown()") 00220 # Allow the C++ object to be deleted 00221 if self.rc is not None and self.__arg is not None: 00222 self.__arg.deleteLater() 00223 00224 def process(self, (status, buffer)): 00225 "Method called back for each data event taken" 00226 #log.debug("userApplication.process()") 00227 00228 evtCli = self.evtCli 00229 00230 if status != 0: 00231 if evtCli.isGGLTStatus(): 00232 log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr())) 00233 elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR): 00234 log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr())) 00235 self.__eventSem.release() 00236 return 00237 try: 00238 # In the future this event may contain additional data 00239 if evtCli.isSweepEvent(): return 00240 except: 00241 # Event summary word inaccessible, handle the bad event here 00242 log.exception("") 00243 return 00244 00245 if self.lat.existsGEM(): 00246 if evtCli.setCurrentContribution(evtCli.GEM) != -1: 00247 evtCli.evDumpGEM() 00248 else: 00249 log.error("*******************************************") 00250 log.error("* NO GEM CONTRIBUTION PRESENT *") 00251 log.error("*******************************************") 00252 00253 if evtCli.setCurrentContribution(evtCli.TEM0) != -1: 00254 evtCli.evDumpCAL_LogAccepts() 00255 ###print "" 00256 evtCli.evDumpCAL_Logs(); 00257 #~ #print "" 00258 evtCli.evDumpTKR() 00259 evtCli.evDumpTEM_Error() 00260 evtCli.evDumpDiagnostic() 00261 #for acc in evtCli.evt.CAL_LogAccepts: 00262 # print "CAL Log Accept: 0x%08x" % acc.ui 00263 00264 #for layerLogData in evtCli.evt.CAL_LogData: 00265 # print "CAL Log Data: %s 0x%08x" % layerLogData.layer, layerLogData.data 00266 # sum = evtCli.evt.summary 00267 ###evtCli.evDumpSummary() 00268 00269 #for errorGCCC in evtCli.evt.errGCCCmsg: 00270 # errGCCC = errorGCCC.errGCCC 00271 # print "GCCC", errorGCCC.gccc, "Error:", hex(errGCCC.errParm), hex(errGCCC.sweepNum), hex(errGCCC.errType) 00272 00273 #for calDiag in evtCli.evt.diag.cal: 00274 # print calDiag.layer, calDiag.gccc, calDiag.negLayerEnd, calDiag.posLayerEnd 00275 #print 00276 #for tkrDiag in evtCli.evt.diag.tkr: 00277 # print tkrDiag.gtcc, tkrDiag.trgRequests 00278 else: 00279 log.error("*******************************************") 00280 log.error("* NO TEM 0 CONTRIBUTION PRESENT *") 00281 log.error("*******************************************") 00282 00283 # Get next event triggered 00284 self.__eventSem.release() 00285 00286 00287 #def __commandSynch(self, count): 00288 def commandSynch(self): 00289 "Method called by the command synchronization task" 00290 import time 00291 trigger = self.trigger() 00292 eventSem = self.__eventSem 00293 00294 # Drain the semaphore release count 00295 # Handles the case when the stop run release collided with a trigger release 00296 while eventSem.acquire(0): pass 00297 00298 t0 = time.time() 00299 00300 # Compensate for the extra CMD_SELF_TRIGGER below 00301 cnt = 1 00302 count = self.__cnt 00303 00304 # Wait for START_RUN to enable triggers 00305 trigger.waitForMaskEnable() 00306 00307 trigger.solicit() # Issue an internal trigger 00308 eventSem.acquire() # Wait for the event to be processed 00309 00310 t1 = trigger.getEnableTime() # get the last trigger enable time from GLT 00311 while cnt < count and not self.__cmdSynchQuit: 00312 cnt += 1 00313 trigger.solicit() # Issue an internal trigger 00314 time.sleep(.0001) 00315 eventSem.acquire() # Wait for the event to be processed 00316 #trigger.disable() # Disable triggers 00317 # Do stuff 00318 #trigger.enable() # Enable triggers 00319 00320 t2 = trigger.getTimeStamp() # Get the last trigger timestamp 00321 00322 if t1 is None: 00323 t1 = t0 00324 if t2 is None: 00325 t2 = time.time() 00326 dT = t2 - t1 00327 if dT == 0.0: dT = 0.000001 00328 log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \ 00329 (self.getName(), self.evtCnt, dT, self.evtCnt/dT)) 00330 00331 # Get out of waiting when in suite or standalone mode 00332 self.sync() 00333 00334 # execute the GUI functions for stopRun, just in case 00335 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00336 if self.rc is not None: 00337 self.rc.doStop() 00338 00339 def wait(self): 00340 self.__cmdSynchSem.acquire() 00341 00342 def sync(self): 00343 if self.rc is None or self.isRunFromSuite(): 00344 self.__cmdSynchSem.release() 00345 00346 class userApplicationCallbacks(rcTransitions.ApplicationCallbacks): 00347 def __init__(self): 00348 pass 00349 00350 def beforeSetup(self, app): 00351 log.info("Before setup") 00352 00353 def beforeStartRun(self, app): 00354 log.info("Before startRun") 00355 00356 def afterStopRun(self, app): 00357 log.info("After stopRun") 00358 00359 00360 # Standalone mode: 00361 if __name__ == "__main__": 00362 from LATTE.runcontrol.RunControlCommon import RunControlCommon 00363 00364 rcCommon = RunControlCommon() 00365 rcCommon.initialize() 00366 rcCommon.setLoggingLevel("INFO") 00367 rcCommon.connect() 00368 ua = userApplication(None, 321, rcCommon) 00369 ua.rcSetup() 00370 ua.rcStartRun() 00371 ua.wait() 00372 ua.rcStopRun() 00373 ua.rcTeardown()