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 ACD test application" 00012 __author__ = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = "11/21/2002" 00014 __version__ = "$Revision: 1.4 $" 00015 __credits__ = "SLAC" 00016 00017 import LATTE.copyright_SLAC 00018 00019 import threading 00020 import logging as log 00021 import time 00022 00023 from LATTE.runcontrol.rcTransitions import rcTransitions 00024 from LATTE.runcontrol.ArgumentImpl import ArgumentImpl 00025 00026 from support.SimpleGasuExample 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 def getName(self): 00072 return __name__ 00073 00074 def setup(self): 00075 log.debug("userApplication.setup()") 00076 00077 if self.rc is None: 00078 self.__arg = userArgText() 00079 else: 00080 self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1) 00081 00082 aem = self.lat.downAEM() 00083 00084 arc0 = aem.downARC(11) 00085 arc0.cmd_reset = 1 00086 00087 # configure the AEM 00088 aem.configuration = 0x007ff 00089 00090 # The FREE-sim simulates 4 ADCs with fixed outputs of 1112, 1113, 1114, 1115 (decimal). 00091 # The FREE-sim simulates 4 ADCs with fixed outputs of 0x458, 0x459, 0x45a, 0x45b (hex). 00092 # adjust the PHA thresholds to turn these on/off. 00093 00094 # config all PHAs on 00095 00096 thresh_on = 0x20 00097 thresh_off = 0xFFF 00098 00099 arc0.PHA_THRESHOLD_0 = thresh_on 00100 arc0.PHA_THRESHOLD_1 = thresh_on 00101 arc0.PHA_THRESHOLD_2 = thresh_on 00102 arc0.PHA_THRESHOLD_3 = thresh_on 00103 arc0.PHA_THRESHOLD_4 = thresh_on 00104 arc0.PHA_THRESHOLD_5 = thresh_on 00105 arc0.PHA_THRESHOLD_6 = thresh_on 00106 arc0.PHA_THRESHOLD_7 = thresh_on 00107 arc0.PHA_THRESHOLD_8 = thresh_on 00108 arc0.PHA_THRESHOLD_9 = thresh_on 00109 arc0.PHA_THRESHOLD_10 = thresh_on 00110 arc0.PHA_THRESHOLD_11 = thresh_on 00111 arc0.PHA_THRESHOLD_12 = thresh_on 00112 arc0.PHA_THRESHOLD_13 = thresh_on 00113 arc0.PHA_THRESHOLD_14 = thresh_on 00114 arc0.PHA_THRESHOLD_15 = thresh_on 00115 arc0.PHA_THRESHOLD_16 = thresh_on 00116 arc0.PHA_THRESHOLD_17 = thresh_on 00117 arc0.veto_width = 5 00118 00119 # set MAX_PHA 00120 arc0.MAX_PHA = 18 00121 00122 # set PHA ENABLE bits 00123 arc0.PHA_EN_0 = 0xffff 00124 arc0.PHA_EN_1 = 0x3 00125 00126 # set VETO ENABLE bits 00127 arc0.VETO_EN_0 = 0xffff 00128 arc0.VETO_EN_1 = 0x3 00129 00130 afeb = arc0.allAFE() 00131 afeb.CONFIGURATION = 0x0032 00132 afeb.VETO_DAC = 0x20 00133 afeb.HLD_DAC = 0x30 00134 afeb.TCI_DAC = 0x20 00135 afeb.bias_dac = 3 00136 00137 aem.TRGSEQ = 0x5f 00138 00139 # Two choices for the trigger, GEM and MiniGLT 00140 if self.lat.existsGEM(): 00141 self.trigger( SimpleGasuExample() ) 00142 else: 00143 raise AssertionError, "ACD cannot take meaningful triggers without a GEM" 00144 00145 # A state transition can be rejected by not returning None 00146 return None 00147 00148 def startRun(self): 00149 log.debug("userApplication.startRun()") 00150 00151 caption = "Enter number of triggers to take" 00152 if self.rc is None: 00153 cnt = self.__arg.getValue(caption) 00154 else: 00155 cnt = self.rc.execGUImethod(self.__arg.getValue, caption) 00156 00157 # The user pressed 'Cancel' 00158 if cnt is None: return -1 00159 self.__cnt = cnt 00160 00161 # Spawn a thread to synchronize commands with events 00162 self.__cmdSynchQuit = False 00163 00164 # A state transition can be rejected by not returning None 00165 return None 00166 00167 def stopRun(self): 00168 log.debug("userApplication.stopRun()") 00169 00170 self.__cmdSynchQuit = True 00171 self.__eventSem.release() 00172 00173 # The STOP_RUN transition can not be rejected 00174 00175 def resume(self): 00176 log.debug("userApplication.resume()") 00177 00178 # Issue self trigger to make up for the one that was lost during PAUSE 00179 self.trigger().solicit() 00180 00181 return None 00182 00183 def stop (self): 00184 log.debug("userApplication.stop()") 00185 00186 return self.stopRun() 00187 00188 def teardown(self): 00189 log.debug("userApplication.teardown()") 00190 # Allow the C++ object to be deleted 00191 if self.gui is not None and self.__arg is not None: 00192 self.__arg.deleteLater() 00193 00194 def process(self, (status, buffer)): 00195 "Method called back for each data event taken" 00196 ###log.debug("userApplication.process()") 00197 00198 evtCli = self.evtCli 00199 00200 if status != 0: 00201 if evtCli.isGGLTStatus(): 00202 log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr())) 00203 elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR): 00204 log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr())) 00205 self.__eventSem.release() 00206 return 00207 try: 00208 # In the future this event may contain additional data 00209 if evtCli.isSweepEvent(): return 00210 except: 00211 # Event summary word inaccessible, handle the bad event here 00212 log.exception("") 00213 return 00214 00215 if evtCli.setCurrentContribution(evtCli.AEM) != -1: 00216 evtCli.evDumpEventAEM() 00217 print "AEM Veto Hit Vectors:" 00218 j = 0 00219 for hitVect in evtCli.evt.aem.vetoHitVectors: 00220 print "\tCable %2d Raw Data 0x%05x" % (j, hitVect) 00221 j+=1 00222 print "\nAEM Accept Hit Vectors:" 00223 j = 0 00224 for hitVect in evtCli.evt.aem.acceptHitVectors: 00225 print "\tCable %2d Raw Data 0x%05x" % (j, hitVect) 00226 j+=1 00227 print "\nAEM PHA Values:" 00228 j = 0 00229 for (cbl, phas) in evtCli.evt.aem.PHA.items(): 00230 for pha in phas: 00231 print "\tCable: %02d - PHA Value: 0x%04x" % (cbl, pha.ui) 00232 00233 # Get next event triggered 00234 self.__eventSem.release() 00235 00236 #def __commandSynch(self, count): 00237 def commandSynch(self): 00238 "Method called by the command synchronization task" 00239 import time 00240 trigger = self.trigger() 00241 eventSem = self.__eventSem 00242 # Drain the semaphore release count 00243 # Handles the case when the stop run release collided with a trigger release 00244 while eventSem.acquire(0): pass 00245 00246 t0 = time.time() 00247 00248 # Compensate for the extra CMD_SELF_TRIGGER below 00249 cnt = 1 00250 count = self.__cnt 00251 00252 # Wait for START_RUN to enable triggers 00253 trigger.waitForMaskEnable() 00254 00255 trigger.solicit() # Issue an internal trigger 00256 eventSem.acquire() # Wait for the event to be processed 00257 00258 t1 = trigger.getEnableTime() # get the last trigger enable time from GLT 00259 00260 while cnt < count and not self.__cmdSynchQuit: 00261 cnt += 1 00262 trigger.solicit() # Issue an internal trigger 00263 time.sleep(.0001) 00264 eventSem.acquire() # Wait for the event to be processed 00265 #trigger.disable() # Disable triggers 00266 # Do stuff 00267 #trigger.enable() # Enable triggers 00268 00269 t2 = trigger.getTimeStamp() # Get the last trigger timestamp 00270 00271 if t1 is None: 00272 t1 = t0 00273 if t2 is None: 00274 t2 = time.time() 00275 dT = t2 - t1 00276 if dT == 0.0: dT = 0.000001 00277 log.info("%s processed %d events in %.3f seconds = %.1f events/second" % \ 00278 (self.getName(), self.evtCnt, dT, self.evtCnt/dT)) 00279 00280 # Get out of waiting when in suite or standalone mode 00281 self.sync() 00282 00283 # execute the GUI functions for stopRun, just in case 00284 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00285 if self.rc is not None: 00286 self.rc.doStop() 00287 00288 def wait(self): 00289 self.__cmdSynchSem.acquire() 00290 00291 def sync(self): 00292 if __name__ == "__main__" or self.isRunFromSuite(): 00293 self.__cmdSynchSem.release() 00294 00295 00296 # Standalone mode: 00297 if __name__ == "__main__": 00298 import os 00299 log.basicConfig() 00300 log.getLogger("").setLevel(log.DEBUG) 00301 ua = userApplication(None, 321, 0) 00302 ua.rcSetup(os.path.join(os.environ['ONLINE_ROOT'], 'repos/simpleAemSchema.xml')) 00303 ua.rcStartRun() 00304 ua.wait() 00305 ua.rcStopRun() 00306 ua.rcTeardown() 00307 00308 # History: 00309 # $Log: testAppAcd.py,v $ 00310 # Revision 1.4 2005/01/11 22:39:18 stuvi 00311 # no message 00312 # 00313 # Revision 1.3 2004/10/22 20:32:48 stuvi 00314 # Fixed log.exception() 00315 # 00316 # Revision 1.2 2004/08/18 18:00:15 stuvi 00317 # Updated for LATTE 4. 00318 # All hippo functions go through the Qt GUI bridge now. 00319 # 00320 # Revision 1.1 2004/08/04 22:17:25 stuvi 00321 # no message 00322 # 00323 # Revision 1.19 2004/05/13 18:55:09 stuvi 00324 # HLD_EN_0 and HLD_EN_1 no longer exist. 00325 # 00326 # Revision 1.18 2004/05/03 21:19:47 stuvi 00327 # Moved non-Runcontrol scripts to the support directory and modified imports accordingly. 00328 # 00329 # Revision 1.17 2004/04/20 22:09:34 stuvi 00330 # Changed ACD to AEM. 00331 # 00332 # Revision 1.16 2004/04/17 02:22:54 stuvi 00333 # Added teardown() to delete the C++ object for the userArgument 00334 # 00335 # Revision 1.15 2004/04/08 01:57:39 panetta 00336 # make testAppAcd work with GASU 00337 # 00338 # Revision 1.14 2004/03/20 03:45:26 stuvi 00339 # Updated code to use the new PHA object. 00340 # 00341 # Revision 1.13 2004/03/10 22:24:50 panetta 00342 # Upgraded trigger interface. 00343 # Removed dependencies on self.glt. 00344 # 00345 # Revision 1.12 2004/02/20 03:20:23 stuvi 00346 # Added handling of the sweep events and error checking to the process() method, 00347 # 00348 # Revision 1.11 2004/02/04 03:42:14 stuvi 00349 # Changes required to make the scripts work with the new FSM engine. 00350 # 00351 # Revision 1.10 2003/12/11 19:54:45 stuvi 00352 # Suite and standalone mode modifications 00353 # 00354 # Revision 1.9 2003/11/04 18:30:52 panetta 00355 # Changed the commandSynch logic so that the enableMask() call would not pose a threat to snapshot taking. 00356 # 00357 # Revision 1.8 2003/10/31 01:09:37 panetta 00358 # 1) Moved register writes from startRun to setup 00359 # 2) Added GLT enabling logic to __commandSynch 00360 # 3) Gave example of getting the start/stop time from the hardware/event stream 00361 # 00362 # Revision 1.7 2003/08/14 02:36:03 stuvi 00363 # Fixed aem ui value access 00364 # 00365 # Revision 1.6 2003/07/17 00:01:35 stuvi 00366 # no message 00367 # 00368 # Revision 1.5 2003/04/01 21:04:59 stuvi 00369 # Fixed event count discrepancy when the run is stopped in the middle. 00370 # 00371 # Revision 1.4 2003/03/31 19:28:53 stuvi 00372 # Fixed name 00373 # 00374 # Revision 1.3 2003/03/26 21:59:36 stuvi 00375 # Fixed standalone mode 00376 # 00377 # Revision 1.2 2003/03/25 04:53:52 stuvi 00378 # Made sure the semaphores are drained 00379 # 00380 # Revision 1.1 2003/03/11 21:20:55 stuvi 00381 # Moved from RunControl directory 00382 # 00383 # Revision 1.10 2003/02/21 04:08:03 stuvi 00384 # Updated for G2 00385 # 00386 # Revision 1.9 2003/02/06 05:19:38 claus 00387 # Added resume; StopRun bug fix 00388 # 00389 # Revision 1.8 2002/12/11 21:18:07 stuvi 00390 # Changed glt register assignments to bit field assignments 00391 # 00392 # Revision 1.7 2002/12/10 01:09:58 claus 00393 # Added path and changed schema/config file for stand-alone mode 00394 # 00395 # Revision 1.6 2002/12/04 01:59:23 claus 00396 # Added message logging 00397 # 00398 # Revision 1.5 2002/12/02 17:17:09 claus 00399 # Added provision to allow application to run stand-alone 00400 # 00401 # Revision 1.4 2002/11/28 02:02:03 claus 00402 # Shuffled constructor arguments 00403 # 00404 # Revision 1.3 2002/11/27 23:49:27 claus 00405 # Initialize semaphore with zero count 00406 # 00407 # Revision 1.2 2002/11/27 23:37:17 stuvi 00408 # Added semaphor release 00409 # 00410 # Revision 1.1 2002/11/27 05:02:47 claus 00411 # Initial version of Run Control 00412 #