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.2 $" 00015 __credits__ = "SLAC" 00016 00017 import LATTE.copyright_SLAC 00018 00019 import threading 00020 import logging as log 00021 from LATTE.runcontrol.rcTransitions import rcTransitions 00022 from LATTE.runcontrol.ArgumentImpl import ArgumentImpl 00023 import time 00024 import math 00025 import sys 00026 from binascii import hexlify 00027 00028 from support.SimpleGasuExample import * 00029 from support.MiniGLTExample import * 00030 00031 import LDF 00032 00033 import Numeric 00034 00035 00036 def _unsigned(arg): 00037 """\brief Convert an unsigned int argument to an unsigned long 00038 00039 This funtion exists to help format unsigned ints greater than 0x7fffffff, 00040 which in Python 2.4 and up will be displayed as signed strings. 00041 """ 00042 return arg & (2L * sys.maxint + 1) 00043 00044 00045 class myLATcomponentIterator(LDF.LATcomponentIterator): 00046 def __init__(self): 00047 LDF.LATcomponentIterator.__init__(self) 00048 self.parent = None 00049 00050 def TEM(self, event, ebfContribution): 00051 cellHdr = LDF.LATPcellHeader(ebfContribution.header()) 00052 tem = cellHdr.source() # enum maps 1:1 with tower number 00053 self.parent.tem[tem] = self.parseContrib(ebfContribution) 00054 00055 return 0 00056 00057 def GEM(self, event, ebfContribution): 00058 self.parent.gem = self.parseContrib(ebfContribution) 00059 return 0 00060 00061 def AEM(self, event, ebfContribution): 00062 self.parent.aem = self.parseContrib(ebfContribution) 00063 return 0 00064 00065 def OSW(self, event, ebfContribution): 00066 self.parent.osw = self.parseContrib(ebfContribution) 00067 return 0 00068 00069 def headerStr(self, contrib): 00070 header = long(contrib.header() ) 00071 packetError = long(contrib.packetError()) 00072 sequence = long(contrib.sequence() ) 00073 length = long(contrib.length() ) 00074 00075 pack = ((packetError&0x7)<<13) | ((sequence&0x1f)<<8) | ((length>>4)&0xff) 00076 hpknum = 0L 00077 hpknum = hpknum | (header<<16|pack); 00078 rst = "" 00079 00080 # print hex(header), packetError, sequence, length, hex(summary) 00081 for i in range(4): 00082 rst = chr(hpknum&0xff) + rst 00083 hpknum = hpknum >> 8 00084 return rst 00085 00086 def summaryStr(self, contrib): 00087 summary = long(contrib.summary()) 00088 rst = "" 00089 for i in range(4): 00090 rst = chr(summary&0xff) + rst 00091 summary = summary >> 8 00092 return rst 00093 00094 def payloadStr(self, ebfContribution): 00095 pd = ebfContribution.payload() 00096 return Numeric.fromstring(pd).byteswapped().tostring() 00097 00098 def parseContrib(self, ebfContribution): 00099 str = self.headerStr(ebfContribution) 00100 str += self.summaryStr(ebfContribution) 00101 str += self.payloadStr(ebfContribution) 00102 return str 00103 00104 00105 class myLATdbIterator(LDF.LATdataBufferIterator): 00106 def __init__(self, lci, temList): 00107 LDF.LATdataBufferIterator.__init__(self, lci) 00108 self.__lci = lci 00109 lci.parent = self 00110 00111 self.ldfFiles = {} 00112 for tem in temList: 00113 fName = "tem_%x.ldf" % tem 00114 self.ldfFiles[tem] = open(fName, mode='wb') 00115 00116 00117 def iterate(self, buffer, size): 00118 hdr = buffer[0:16] 00119 hdrStr = Numeric.fromstring(hdr).byteswapped().tostring() 00120 # print "LDBI: ", hexlify(hdr) 00121 00122 # set up contrib buffers 00123 self.gem = "" 00124 self.aem = "" 00125 self.osw = "" 00126 self.tem = [""] *16 00127 00128 LDF.LATdataBufferIterator.iterate(self, buffer, size) 00129 00130 for tem, ldfFile in self.ldfFiles.items(): 00131 bufstr = "" 00132 bufstr += self.osw 00133 bufstr += self.gem 00134 bufstr += self.tem[tem] 00135 bufstr += self.aem 00136 00137 dgLength = len(hdr) + len(bufstr) 00138 evLength = dgLength - 8 00139 tmp = divmod(dgLength, 0x100) 00140 dgLenStr = chr(tmp[0]) + chr(tmp[1]) 00141 tmp = divmod(evLength, 0x100) 00142 evLenStr = chr(tmp[0]) + chr(tmp[1]) 00143 00144 newHdr = hdr[0:6] + dgLenStr + hdr[8:14] + evLenStr 00145 bufstr = newHdr + bufstr 00146 00147 ldfFile.write(bufstr) 00148 00149 00150 def closeAll(self): 00151 for tem in self.ldfFiles.values(): 00152 tem.close() 00153 00154 00155 class userArgument(ArgumentImpl): 00156 "GUI for getting the user to input some sort of value." 00157 def __init__(self, parent = None, name = None, modal = 0, fl = 0): 00158 ArgumentImpl.__init__(self, parent, name, modal, fl) 00159 self.__value = 0 00160 self.setCaption("Hello world!") 00161 00162 def OKButtonClicked(self): 00163 self.__value = int(self.ArgumentList.text().latin1()) 00164 self.close() 00165 00166 def CancelButtonClicked(self): 00167 self.__value = None 00168 self.close() 00169 00170 def getValue(self, caption): 00171 self.setCaption(caption) 00172 self.show() 00173 self.exec_loop() 00174 return self.__value 00175 00176 class userArgText(object): 00177 "Text user interface for getting the user to input some sort of value" 00178 def __init__(self): 00179 pass 00180 00181 def getValue(self, caption): 00182 return int(raw_input("%s: " % (caption))) 00183 00184 00185 class userApplication(rcTransitions): 00186 "Implmentation class for a user application" 00187 def __init__(self, rc, userId, debug): 00188 rcTransitions.__init__(self, rc, userId, debug) 00189 log.debug("userApplication.__init__()") 00190 self.__eventSem = threading.Semaphore(0) 00191 self.__cmdSynchSem = threading.Semaphore(0) 00192 00193 def getName(self): 00194 return __name__ 00195 00196 def setup(self): 00197 log.debug("userApplication.setup()") 00198 00199 if self.rc is None: 00200 self.__arg = userArgText() 00201 else: 00202 self.__arg = self.rc.createGUI(userArgument, self.rc, 'test1', 1) 00203 00204 # Split the run file into N parts, where N is the number of TEMs 00205 if self.lat.existsGEM(): 00206 self.trigger( SimpleGasuExample() ) 00207 else: 00208 self.trigger( MiniGLTExample() ) 00209 00210 return None 00211 00212 def startRun(self): 00213 log.debug("userApplication.startRun()") 00214 00215 caption = "Enter number of triggers to take" 00216 if self.rc is None: 00217 cnt = self.__arg.getValue(caption) 00218 else: 00219 cnt = self.rc.execGUImethod(self.__arg.getValue, caption) 00220 00221 # 1) Determine TEMs present in Schema 00222 temList = self.lat.TEM.keys() 00223 if temList == []: 00224 raise RuntimeError("No TEMs in schema, aborting split of LDF file") 00225 if len(temList) == 1: 00226 raise RuntimeError("Only one TEM in schema, aborting split of LDF file") 00227 00228 # 2) pass temList to routines which do the work 00229 self.__lci = myLATcomponentIterator() 00230 self.__ldbi = myLATdbIterator(self.__lci,temList) 00231 00232 if cnt is None: return -1 00233 self.__cnt = cnt 00234 00235 self.__cmdSynchQuit = False 00236 00237 return None 00238 00239 def stopRun(self): 00240 log.debug("userApplication.stopRun()") 00241 00242 self.setCompletionStatus(self.COMPL_STATUS_SUCCESS) 00243 self.__cmdSynchQuit = True 00244 self.__eventSem.release() 00245 # don't forget to close the TEM files 00246 self.__ldbi.closeAll() 00247 00248 00249 def resume(self): 00250 log.debug("userApplication.resume()") 00251 self.trigger().solicit() 00252 return None 00253 00254 def stop(self): 00255 log.debug("userApplication.stop()") 00256 return self.stopRun() 00257 00258 def teardown(self): 00259 log.debug("userApplication.teardown()") 00260 if self.rc is not None and self.__arg is not None: 00261 self.__arg.deleteLater() 00262 00263 def process(self, (status, buffer)): 00264 log.debug("userApplication.process()") 00265 00266 evtCli = self.evtCli 00267 self.__ldbi.iterate(buffer, len(buffer)) 00268 00269 if status == 0: 00270 if 0: # One _OR_ the other method, not both 00271 pass 00272 else: # Old way of doing things 00273 pass 00274 else: 00275 if evtCli.isGGLTStatus(): 00276 log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr())) 00277 elif not evtCli.checkOnlineStatus(status, evtCli.PLAYBACK_ERROR): 00278 log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr())) 00279 self.__eventSem.release() 00280 return 00281 00282 try: 00283 # In the future this event may contain additional data 00284 if evtCli.isSweepEvent(): return 00285 except: 00286 # Event summary word inaccessible, handle the bad event here 00287 log.exception("") 00288 return 00289 00290 00291 # Get next event triggered 00292 self.__eventSem.release() 00293 00294 #def __commandSynch(self, count): 00295 def commandSynch(self): 00296 "Method called by the command synchronization task" 00297 import time 00298 trigger = self.trigger() 00299 eventSem = self.__eventSem 00300 while eventSem.acquire(0): pass 00301 00302 t0 = time.time() 00303 00304 # Compensate for the extra CMD_SELF_TRIGGER below 00305 cnt = 1 00306 count = self.__cnt 00307 00308 # Wait for START_RUN to enable triggers 00309 trigger.waitForMaskEnable() 00310 00311 trigger.solicit() # Issue an internal trigger 00312 eventSem.acquire() # Wait for the event to be processed 00313 00314 while cnt < count and not self.__cmdSynchQuit: 00315 cnt += 1 00316 trigger.solicit() # Issue an internal trigger 00317 time.sleep(.0001) 00318 eventSem.acquire() # Wait for the event to be processed 00319 00320 00321 00322 # Get out of waiting when in suite or standalone mode 00323 self.sync() 00324 00325 # execute the GUI functions for stopRun, just in case 00326 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00327 if self.rc is not None: 00328 self.rc.doStop() 00329 00330 def wait(self): 00331 self.__cmdSynchSem.acquire() 00332 00333 def sync(self): 00334 if __name__ == "__main__" or self.isRunFromSuite(): 00335 self.__cmdSynchSem.release() 00336 00337