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__ = "GLAST LAT Coincidence based Trigger System Interface classes" 00012 __author__ = "Jim Panetta <panetta@slac.stanford.edu> SLAC - GLAST I&T" 00013 __date__ = "2/14/04" 00014 __version__ = "$Revision: 2.11 $" 00015 __release__ = "$Name: R04-12-00 $" 00016 __credits__ = "SLAC" 00017 00018 import LATTE.copyright_SLAC 00019 00020 00021 """rcTrgGem: This class implements a 'threaded' model for enabling/disabling the trigger 00022 """ 00023 00024 from TrgGem import TrgGem 00025 from threading import Event 00026 import logging 00027 import time 00028 00029 class rcTrgGem(TrgGem): 00030 """\brief rcTrgGem class definition 00031 This class implements a 'threaded' model for enabling/disabling the trigger 00032 """ 00033 __SWEEP_TMO = 3.0 # Sweep timeout in floating point seconds 00034 00035 def __init__(self): 00036 """rcTrgGem constructor 00037 """ 00038 self.__triggersEnabled = Event() 00039 self.__enableTime = -99999999999 00040 self.__disableTime = -99999999999 00041 00042 TrgGem.__init__(self) # do this last 00043 00044 def commit(self, gem = None): 00045 """\brief public commit function 00046 00047 This function commits the configuration defined by this 00048 TrgGem object to the hardware. It does *all* the registers. 00049 This function should never be called by anyone other than Run Control. 00050 """ 00051 if gem is not None: 00052 self.GEM(gem) 00053 self._TrgGem__commit() 00054 00055 def waitForMaskEnable(self, tmo = None): 00056 """Waits until the enableMask() method is called. 00057 This is usually needed by non-self-triggering scripts where 00058 the _commandSynch thread needs to wait until RunControl 00059 actually enables the mask before continuing. 00060 00061 \param tmo Optional parameter giving the wait timeout in seconds 00062 """ 00063 self.__triggersEnabled.wait(tmo) 00064 00065 def getEnableTime(self): 00066 """ Returns the VxWorks timestamp at the time the triggers are enabled 00067 00068 \return Trigger enable time 00069 """ 00070 return self.__enableTime 00071 00072 def getDisableTime(self): 00073 """ Returns the VxWorks timestamp at the time the triggers are disabled 00074 00075 \return Trigger disable time 00076 """ 00077 return self.__disableTime 00078 00079 def getTimeStamp(self): 00080 """ Returns the VxWorks timestamp for the last time a self-trigger 00081 was asserted. 00082 \return Trigger timestamp 00083 """ 00084 ts = self.GEM().GEMC.regs['cmd_trigger'].getTimeStamp() 00085 return ts 00086 00087 def sweepOnShut(self): 00088 """ Returns whether or not shut() does a sweep event. Default true. 00089 \return a boolean 00090 """ 00091 return True 00092 00093 ############### Pure virtual function reimplementation 00094 00095 def enable(self, mask=None): 00096 """Re-implementation of the enable() function to take advantage 00097 of threading 00098 """ 00099 if mask is not None: 00100 outMask = mask 00101 elif self.conditions() is not None: 00102 outMask = self.conditions().value() 00103 else: 00104 raise AssertionError, "Attempting to enable a TrgConditionsValue of None" 00105 00106 if self.__triggersEnabled.isSet(): return # triggers already enabled 00107 00108 gemw = self.GEM().GEMW 00109 gemw.WINDOW_OPEN_MASK = outMask 00110 self.__triggersEnabled.set() 00111 00112 self.__enableTime = gemw.regs['window_open_mask'].getTimeStamp() 00113 00114 def disable(self): 00115 """Re-implementation of the disable() function to take advantage 00116 of threading 00117 """ 00118 self.__triggersEnabled.clear() 00119 gemw = self.GEM().GEMW 00120 gemw.WINDOW_OPEN_MASK = 0 00121 self.__disableTime = gemw.regs['window_open_mask'].getTimeStamp() 00122 00123 def shut(self, sweepEvent, progress = None): 00124 """Re-implementation of the shut function to take advantage of the 00125 fact that in rcTrgGem, trigger engine 15 is reserved for the marker. 00126 00127 \param sweepEvent: A sweep Event() defined by runControl 00128 \param progress: An optional function that returns a non-zero value when 00129 when events are passing through the system. If omitted 00130 a fixed timeout is used. 00131 """ 00132 00133 gemw = self.GEM().GEMW 00134 gemsc = self.GEM().GEMSC 00135 00136 #0) determine whether we are enabled or not 00137 if gemw.WINDOW_OPEN_MASK != 0: 00138 enabled = True 00139 else: 00140 enabled = False 00141 00142 #1) disable triggers 00143 goodSolicit = self.solicit 00144 self.solicit = self.__falseSolicit 00145 self.disable() 00146 sweepEvent.clear() 00147 00148 #2) Replace contents of all schedulers with solicited with (Engine) f 00149 # Doing it by hand 00150 scheduler = ( 0xffffffffL ) # Everything's f! 00151 regList = gemsc.regs.values() 00152 oldSched = {} # dictionary keyed on register names 00153 for reg in regList: 00154 oldSched[reg.getName()] = reg.get() 00155 reg.set(scheduler) 00156 00157 #2.5) Wait until we don't have progress 00158 if progress is not None: 00159 while True: 00160 if progress() == 0: 00161 break 00162 time.sleep(.5) 00163 # print "waiting for progress" 00164 00165 #3) Change conditions to be solicit only, solicit a trigger 00166 gemw.WINDOW_OPEN_MASK = TrgGem._TrgGem__SOLICIT_MASK 00167 self.GEM().downGEMC().CMD_TRIGGER = 1 00168 00169 #4) Block until the sweep is detected by rcTransitions then disable triggers 00170 tmo = rcTrgGem.__SWEEP_TMO 00171 while (tmo > 0.0): 00172 if sweepEvent.isSet(): break 00173 sweepEvent.wait(0.50) 00174 if progress is not None: 00175 if progress() != 0: 00176 tmo = rcTrgGem.__SWEEP_TMO 00177 continue 00178 tmo -= 0.50 00179 if tmo <= 0: 00180 sweepEvent.set() 00181 logging.fatal("Trigger sweep timed out before all events were drained") 00182 return False 00183 00184 self.disable() 00185 00186 #5) Put the original contents of schedulers back 00187 for reg in regList: 00188 reg.set(oldSched[reg.getName()]) 00189 00190 #6) Put the trigger conditions back. 00191 if enabled: 00192 self.enable() 00193 self.solicit = goodSolicit 00194 00195 return True 00196 00197 00198 def __falseSolicit(self): 00199 pass 00200 00201