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