Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

EnvMonImpl.py

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__ = "Environmental Monitoring implementation GUI class"
00012 __author__   = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = ("$Date: 2006/07/17 19:08:59 $").split(' ')[1]
00014 __version__  = "$Revision: 2.20 $"
00015 __release__  = "$Name: R04-12-00 $"
00016 __credits__  = "SLAC"
00017 
00018 import LATTE.copyright_SLAC
00019 
00020 import                     sys
00021 import                     os
00022 import                     threading
00023 import                     time
00024 from qt             import *
00025 from sihippo        import *
00026 import                     atexit
00027 import                     copy
00028 
00029 from EnvMon                        import EnvMon
00030 from EnvMonSetRange                import EnvMonSetRange
00031 from LATTE.database.gSchemaConfig  import *
00032 from LATTE.database.gLAT           import GLAT
00033 from LATTE.database.gXBR           import GXBRD
00034 from LATTE.tools.taskEngine        import TaskEngine
00035 from LATTE.tools.guiBridges        import GUIbridge
00036 
00037 
00038 class EnvMonImpl(EnvMon):
00039 
00040   DEADTIME_RATE_IN_MHZ = 20.0
00041   TIMEBASE_RATE_IN_MHZ = 16.6666667
00042 
00043   def __init__(self, common, parent = None, name = None, fl = 0):
00044     EnvMon.__init__(self, None, name, fl)
00045     if not name:
00046       self.setName("EnvMon")
00047     self.fontPsize= QApplication.font().pointSize()
00048 
00049     self.splitEnvMon.setOpaqueResize(1)
00050     self.DBN = common.getDBN()
00051     #self.__lat = common.getLAT()
00052     self.scrPlotView = ScrollablePlotView(self.DBN, self.frameOuterPlots,"PlotScrollView")
00053     if self.DBN != {}:
00054       self.scrPlotView.initEventPlot()
00055     self.__rate = 50
00056     self.sldRate.setValue(self.__rate)
00057     self.oldVal = None
00058     self.initDisplays()
00059     self.inShutdown = False
00060     atexit.register(self.quitApp)
00061     QObject.connect(self.bgDataTakingPlot,  SIGNAL('clicked(int)'),      self.toggleDataTakingPlot)
00062     QObject.connect(self.bgDataTakingMon,   SIGNAL('clicked(int)'),      self.toggleDataTakingMon)
00063     QObject.connect(self.bgChan0Plot,       SIGNAL('clicked(int)'),      self.toggleChan0Plot)
00064     QObject.connect(self.bgChan0Mon,        SIGNAL('clicked(int)'),      self.toggleChan0Mon)
00065     QObject.connect(self.bgChan1Plot,       SIGNAL('clicked(int)'),      self.toggleChan1Plot)
00066     QObject.connect(self.bgChan1Mon,        SIGNAL('clicked(int)'),      self.toggleChan1Mon)
00067     QObject.connect(self.bgChan2Plot,       SIGNAL('clicked(int)'),      self.toggleChan2Plot)
00068     QObject.connect(self.bgChan2Mon,        SIGNAL('clicked(int)'),      self.toggleChan2Mon)
00069     QObject.connect(self.bgChan3Plot,       SIGNAL('clicked(int)'),      self.toggleChan3Plot)
00070     QObject.connect(self.bgChan3Mon,        SIGNAL('clicked(int)'),      self.toggleChan3Mon)
00071     QObject.connect(self.bgChan4Plot,       SIGNAL('clicked(int)'),      self.toggleChan4Plot)
00072     QObject.connect(self.bgChan4Mon,        SIGNAL('clicked(int)'),      self.toggleChan4Mon)
00073     QObject.connect(self.bgAcdEnv1Plot,     SIGNAL('clicked(int)'),      self.toggleAcdEnv1Plot)
00074     QObject.connect(self.bgAcdEnv1Mon,      SIGNAL('clicked(int)'),      self.toggleAcdEnv1Mon)
00075     QObject.connect(self.bgPDUPlot,         SIGNAL('clicked(int)'),      self.togglePDUPlot)
00076     QObject.connect(self.bgPDUMon,          SIGNAL('clicked(int)'),      self.togglePDUMon)
00077     QObject.connect(self.cmbBlock,          SIGNAL("activated(int)"),    self.changeBlock)
00078     QObject.connect(self.cmbFreeBoard,      SIGNAL("activated(int)"),    self.changeFreeBoard)
00079     QObject.connect(self.sldRate,           SIGNAL("valueChanged(int)"), self.changeRate)
00080     QObject.connect(self.btnClear,          SIGNAL("clicked()"),         self.clearPlots)
00081     QObject.connect(self.btnRaw,            SIGNAL("toggled(bool)"),     self.toggleRaw)
00082 
00083     cmd = common.getCmdCli()
00084     self.__lat = GLAT(cmd)
00085     envMonFile = os.path.join(os.environ['ONLINE_ROOT'],
00086                             'LATTE/repos/envMonSchema.xml')
00087 
00088     self.__xbrd = GXBRD(cmd)
00089     self.__xbrd.readSchema(envMonFile)
00090     self.__lat.readSchema(envMonFile)
00091 
00092 
00093     self.DataTakingRegList = [
00094                           'event_size',
00095                           'sat_deadtime_lrs_ctr',
00096                           'sat_cal_lrs_ctr_0',
00097                           'sat_cal_lrs_ctr_1',
00098                           'sat_tkr_lrs_ctr_0',
00099                           'sat_tkr_lrs_ctr_1',
00100                           'sat_tkr_lrs_ctr_2',
00101                           'sat_tkr_lrs_ctr_3'
00102                         ]
00103 
00104     self.chan2RegList = [
00105                           'adc_afee0_t0',
00106                           'adc_afee0_t1',
00107                           'adc_afee1_t0',
00108                           'adc_afee1_t1',
00109                           'adc_afee2_t0',
00110                           'adc_afee2_t1',
00111                           'adc_afee3_t0',
00112                           'adc_afee3_t1'
00113                         ]
00114 
00115     self.chan3RegList = [
00116                           'adc_tkr_c0_t0',
00117                           'adc_tkr_c0_t1',
00118                           'adc_tkr_c1_t0',
00119                           'adc_tkr_c1_t1',
00120                           'adc_tkr_c2_t0',
00121                           'adc_tkr_c2_t1',
00122                           'adc_tkr_c3_t0',
00123                           'adc_tkr_c3_t1'
00124                         ]
00125 
00126     self.chan4RegList = [
00127                           'adc_tkr_c4_t0',
00128                           'adc_tkr_c4_t1',
00129                           'adc_tkr_c5_t0',
00130                           'adc_tkr_c5_t1',
00131                           'adc_tkr_c6_t0',
00132                           'adc_tkr_c6_t1',
00133                           'adc_tkr_c7_t0',
00134                           'adc_tkr_c7_t1'
00135                         ]
00136 
00137     self.acdEnv1RegList = [
00138                           'env_vdd_',
00139                           'env_temp_',
00140                           'env_hv1_',
00141                           'env_hv2_',
00142                           'env_dac_digital_3_3i',
00143                           'env_dac_temp',
00144                           'env_dac_hv_i',
00145                           'env_dac_v',
00146                         ]
00147 
00148     self.acdEnv2RegList = [
00149                           'env_free_4LA',
00150                           'env_free_4LB',
00151                           'env_free_4RA',
00152                           'env_free_4RB',
00153                           'env_daq',
00154                         ]
00155 
00156     self.pduRegList = [
00157                         'adc_ps_temp_0',
00158                         'adc_ps_temp_1',
00159                         'adc_tem_temp_0',
00160                         'adc_tem_temp_1',
00161                         'adc_tem_voltage_0',
00162                         'adc_tem_voltage_1',
00163                       ]
00164 
00165     self.acdPlotCheckList = {}
00166     self.acdMonitorCheckList = {}
00167     for i in range(12):
00168       self.acdPlotCheckList[i] = [0] * 8
00169       self.acdMonitorCheckList[i] = [0] * 8
00170 
00171     self.monitorList = {}
00172     #self.vArrayList = {}
00173     self.__block = 'TEM 0'
00174     self.changeFreeBoard(0)
00175     self.cmbBlock.setCurrentText(self.__block)
00176     self.changeBlock(-1) # First time caller
00177     self.__threadQuit = 0
00178     self.__bypass = 0
00179     #self.__dictSem = threading.Semaphore(1) # used for controlling dictionary access
00180 
00181     self.__guiThread    = threading.currentThread()
00182     self.__guiBridge    = GUIbridge(self.__guiThread)
00183 
00184     #self.threadReadEnv = threading.Thread(target=self.readEnvValues, name='EnvMon', args=())
00185     #self.threadReadEnv.start()
00186     self.threadReadEnv = TaskEngine('EnvMon')
00187     self.threadReadEnv.start()
00188     self.threadReadEnv.spawn(self.readEnvValues)
00189 
00190   def setupLabels(self, newTem):
00191     if newTem:
00192                # (channel, adc)
00193       labels = {  (0,1): 'TKR Bias (I)',
00194                   (0,3): 'CAL Bias (I)',
00195                   (0,5): 'TEM (I)',
00196                   (0,6): 'TKR Bias V0',
00197                   (0,7): '',
00198                   (1,1): 'TKR Bias V1',
00199                   (1,3): 'CAL Bias V1',
00200                   (1,4): 'CAL Bias V0',
00201                   (1,5): '28 V0',
00202                   (1,7): '28 V1'
00203                 }
00204 
00205       self.disableEntries = ['TKRBiasI']
00206 
00207       self.chan0RegList = [
00208                             'adc_tkr_digital_2_5v',
00209                             'psd_tkr_bias_i',
00210                             'adc_tkr_analog_a_1_5v',
00211                             'psd_cal_bias_i',
00212                             'adc_tkr_analog_b_2_5v',
00213                             'psd_tem_i',
00214                             'adc_tkr_bias_v0',
00215                             ''
00216                           ]
00217 
00218       self.chan1RegList = [
00219                             'adc_cal_digital_3_3v',
00220                             'adc_tkr_bias_v1',
00221                             'adc_cal_analog_3_3v',
00222                             'adc_cal_bias_v1',
00223                             'adc_cal_bias_v0',
00224                             'adc_28_v0',
00225                             'adc_tem_digital_3_3v',
00226                             'adc_28_v1'
00227                           ]
00228 
00229     else:
00230                # (channel, adc)
00231       labels = {  (0,1): 'TKR Digital (2.5I)',
00232                   (0,3): 'TKR Analog A (1.5I)',
00233                   (0,5): 'TKR Analog B (2.5I)',
00234                   (0,6): 'TKR Bias (V)',
00235                   (0,7): 'TKR Bias (I)',
00236                   (1,1): 'CAL Digital (3.3I)',
00237                   (1,3): 'CAL Analog (3.3I)',
00238                   (1,4): 'CAL Bias (V)',
00239                   (1,5): 'CAL Bias (I)',
00240                   (1,7): 'TEM Digital (3.3I)'
00241                 }
00242       self.disableEntries = []
00243 
00244       self.chan0RegList = [
00245                             'adc_tkr_digital_2_5v',
00246                             'adc_tkr_digital_2_5i',
00247                             'adc_tkr_analog_a_1_5v',
00248                             'adc_tkr_analog_a_1_5i',
00249                             'adc_tkr_analog_b_2_5v',
00250                             'adc_tkr_analog_b_2_5i',
00251                             'adc_tkr_bias_v',
00252                             'adc_tkr_bias_i'
00253                           ]
00254 
00255       self.chan1RegList = [
00256                             'adc_cal_digital_3_3v',
00257                             'adc_cal_digital_3_3i',
00258                             'adc_cal_analog_3_3v',
00259                             'adc_cal_analog_3_3i',
00260                             'adc_cal_bias_v',
00261                             'adc_cal_bias_i',
00262                             'adc_tem_digital_3_3v',
00263                             'adc_tem_digital_3_3i'
00264                           ]
00265 
00266     for ((ch,adc), label) in labels.items():
00267       txtLabel = eval("self.textLabelCh%dAdc%d" % (ch,adc))
00268       if label != "": label += ":"
00269       txtLabel.setText(label)
00270     for suffix in self.disableEntries:
00271       eval("self.txt"+suffix).setEnabled(0)
00272       eval("self.chkPlot"+suffix).setEnabled(0)
00273       eval("self.chkMon"+suffix).setEnabled(0)
00274 
00275 
00276   def setFont(self, font):
00277     self.fontPsize= font.pointSize()
00278     EnvMon.setFont(self, font)
00279     for regName in self.monitorList:
00280       self.adjustMonitorTextFont(self.monitorList[regName])
00281 
00282   def adjustMonitorTextFont(self, monTxt):
00283     font = monTxt.font()
00284     font.setPointSize(self.fontPsize)
00285     monTxt.setFont(font)
00286 
00287   def toggleRaw(self, raw):
00288     self.__bypass = raw
00289 
00290   def changeBlock(self, block):
00291     if block == -1:
00292       block = 0
00293       suppressError = 1
00294     else:
00295       suppressError = 0
00296     blockText = str(self.cmbBlock.text(block))
00297     if blockText.startswith('TEM'):
00298       try:
00299         self.selectTEM(blockText)
00300       except:
00301         # Either the TEM doesn't exist or running with a G2 or G3 setup
00302         if not suppressError:
00303           QMessageBox.critical(self, "Environmental Quantity Monitor",
00304                               "Invalid block " + blockText +
00305                               ", doesn't exist in this hardware configuration.")
00306         else:
00307           self.selectAEM()
00308       else:
00309         self.envMonStack.raiseWidget(0)
00310       self.cmbBlock.setCurrentText(self.__block)
00311     else:
00312       self.selectAEM()
00313 
00314   def selectAEM(self):
00315     self.__block = "AEM"
00316     self.__lat.applyConfig(2)
00317     self.__gaeq = self.__lat.AEM.AEQ
00318     self.envMonStack.raiseWidget(1)
00319 
00320   def selectTEM(self, blockText):
00321     temId = int(blockText.split()[1])
00322     tem = self.__lat.TEM[temId]
00323     temVer = int((tem.status >> 16) & 0x3F)
00324     self.__block = blockText
00325     self.__gtic = tem.TIC
00326     self.__gtwr = self.__xbrd.TWR[temId]
00327     if temVer < 8:
00328       self.__lat.applyConfig(0, self.__xbrd)
00329       self.setupLabels(0)
00330     else:
00331       self.__lat.applyConfig(1, self.__xbrd)
00332       self.setupLabels(1)
00333 
00334   def changeFreeBoard(self, boardId):
00335     self.__board = boardId
00336     self.__freeBoard = str(self.cmbFreeBoard.currentText())
00337     self.populateACDchecks(boardId)
00338 
00339   def populateACDchecks(self, boardId):
00340     checkList = self.acdMonitorCheckList[boardId]
00341     for i in range(8):
00342       chkState = checkList[i]
00343       chkBox = self.bgAcdEnv1Mon.find(i)
00344       if chkState:
00345         chkBox.setChecked(1)
00346       else:
00347         chkBox.setChecked(0)
00348         eval("self.txt" + chkBox.name()[6:]).setText("")
00349     checkList = self.acdPlotCheckList[boardId]
00350     for i in range(8):
00351       chkState = checkList[i]
00352       chkBox = self.bgAcdEnv1Plot.find(i)
00353       if chkState:
00354         chkBox.setChecked(1)
00355       else:
00356         chkBox.setChecked(0)
00357 
00358 
00359   def toggleDataTakingPlot(self, id):
00360     chk = self.bgDataTakingPlot.find(id)
00361     if chk.isChecked():
00362       if not self.DataTakingRegList[id] in self.scrPlotView.getPlotList():
00363         if self.DataTakingRegList[id] == "event_size":
00364           self.scrPlotView.addEventPlot(self.DataTakingRegList[id])
00365         else:
00366           columns = ['Time', 'Counter']
00367           self.scrPlotView.addPlot(name=self.DataTakingRegList[id],
00368                                           title=self.DataTakingRegList[id],
00369                                           sizeX=250,
00370                                           sizeY=300,
00371                                           labels=columns)
00372     else:
00373       self.scrPlotView.removePlot(self.DataTakingRegList[id])
00374 
00375   def toggleDataTakingMon(self, id):
00376     chk = self.bgDataTakingMon.find(id)
00377     if chk.isChecked():
00378       if not self.DataTakingRegList[id] in self.monitorList:
00379         #self.__dictSem.acquire()
00380         self.monitorList[self.DataTakingRegList[id]] = eval("self.txt" + chk.name()[6:])
00381         self.adjustMonitorTextFont(self.monitorList[self.DataTakingRegList[id]])
00382         #self.__dictSem.release()
00383     else:
00384       if self.DataTakingRegList[id] in self.monitorList:
00385         self.monitorList[self.DataTakingRegList[id]].setText('')
00386         #self.__dictSem.acquire()
00387         self.monitorList.__delitem__(self.DataTakingRegList[id])
00388         #self.__dictSem.release()
00389 
00390 
00391   def toggleChan0Plot(self, id):
00392     chk = self.bgChan0Plot.find(id)
00393     if chk.isChecked():
00394       if not self.chan0RegList[id] in self.scrPlotView.getPlotList():
00395         reg = self.__gtic.regs[self.chan0RegList[id]]
00396         if reg.getEGU().units() == '':
00397           strUnits = ""
00398         else:
00399           strUnits = " (" + reg.getEGU().units() + ")"
00400         if chk.name()[-1] == 'V':
00401           columns = ['Time', 'Voltage' + strUnits]
00402         else:
00403           columns = ['Time', 'Current' + strUnits]
00404         #self.vArrayList[self.chan0RegList[id]] = [0.0] * 100
00405         self.scrPlotView.addPlot(name=self.chan0RegList[id],
00406                                         title=self.chan0RegList[id],
00407                                         sizeX=250,
00408                                         sizeY=300,
00409                                         labels=columns)
00410     else:
00411       self.scrPlotView.removePlot(self.chan0RegList[id])
00412 
00413 
00414   def toggleChan0Mon(self, id):
00415     chk = self.bgChan0Mon.find(id)
00416     if chk.isChecked():
00417       if not self.chan0RegList[id] in self.monitorList:
00418         #self.__dictSem.acquire()
00419         self.monitorList[self.chan0RegList[id]] = eval("self.txt" + chk.name()[6:])
00420         self.adjustMonitorTextFont(self.monitorList[self.chan0RegList[id]])
00421         #self.__dictSem.release()
00422     else:
00423       if self.chan0RegList[id] in self.monitorList:
00424         self.monitorList[self.chan0RegList[id]].setText('')
00425         #self.__dictSem.acquire()
00426         self.monitorList.__delitem__(self.chan0RegList[id])
00427         #self.__dictSem.release()
00428 
00429   def toggleChan1Plot(self, id):
00430     chk = self.bgChan1Plot.find(id)
00431     if chk.isChecked():
00432       if not self.chan1RegList[id] in self.scrPlotView.getPlotList():
00433         reg = self.__gtic.regs[self.chan1RegList[id]]
00434         if reg.getEGU().units() == '':
00435           strUnits = ""
00436         else:
00437           strUnits = " (" + reg.getEGU().units() + ")"
00438         if chk.name()[-1] == 'V':
00439           columns = ['Time', 'Voltage' + strUnits]
00440         else:
00441           columns = ['Time', 'Current' + strUnits]
00442         #self.vArrayList[self.chan1RegList[id]] = [0.0] * 100
00443         self.scrPlotView.addPlot(name=self.chan1RegList[id],
00444                                         title=self.chan1RegList[id],
00445                                         sizeX=250,
00446                                         sizeY=300,
00447                                         labels=columns)
00448     else:
00449       self.scrPlotView.removePlot(self.chan1RegList[id])
00450 
00451 
00452   def toggleChan1Mon(self, id):
00453     chk = self.bgChan1Mon.find(id)
00454     if chk.isChecked():
00455       if not self.chan1RegList[id] in self.monitorList:
00456         #self.__dictSem.acquire()
00457         self.monitorList[self.chan1RegList[id]] = eval("self.txt" + chk.name()[6:])
00458         self.adjustMonitorTextFont(self.monitorList[self.chan1RegList[id]])
00459         #self.__dictSem.release()
00460     else:
00461       if self.chan1RegList[id] in self.monitorList:
00462         self.monitorList[self.chan1RegList[id]].setText('')
00463         #self.__dictSem.acquire()
00464         self.monitorList.__delitem__(self.chan1RegList[id])
00465         #self.__dictSem.release()
00466 
00467   def toggleChan2Plot(self, id):
00468     chk = self.bgChan2Plot.find(id)
00469     if chk.isChecked():
00470       if not self.chan2RegList[id] in self.scrPlotView.getPlotList():
00471         reg = self.__gtic.regs[self.chan2RegList[id]]
00472         if reg.getEGU().units() == '':
00473           strUnits = ""
00474         else:
00475           strUnits = " (" + reg.getEGU().units() + ")"
00476         columns = ['Time', 'Temperature' + strUnits]
00477         #self.vArrayList[self.chan2RegList[id]] = [0.0] * 100
00478         self.scrPlotView.addPlot(name=self.chan2RegList[id],
00479                                         title=self.chan2RegList[id],
00480                                         sizeX=250,
00481                                         sizeY=300,
00482                                         labels=columns)
00483     else:
00484       self.scrPlotView.removePlot(self.chan2RegList[id])
00485 
00486 
00487   def toggleChan2Mon(self, id):
00488     chk = self.bgChan2Mon.find(id)
00489     if chk.isChecked():
00490       if not self.chan2RegList[id] in self.monitorList:
00491         #self.__dictSem.acquire()
00492         self.monitorList[self.chan2RegList[id]] = eval("self.txt" + chk.name()[6:])
00493         self.adjustMonitorTextFont(self.monitorList[self.chan2RegList[id]])
00494         #self.__dictSem.release()
00495     else:
00496       if self.chan2RegList[id] in self.monitorList:
00497         self.monitorList[self.chan2RegList[id]].setText('')
00498         #self.__dictSem.acquire()
00499         self.monitorList.__delitem__(self.chan2RegList[id])
00500         #self.__dictSem.release()
00501 
00502   def toggleChan3Plot(self, id):
00503     chk = self.bgChan3Plot.find(id)
00504     if chk.isChecked():
00505       if not self.chan3RegList[id] in self.scrPlotView.getPlotList():
00506         reg = self.__gtic.regs[self.chan3RegList[id]]
00507         if reg.getEGU().units() == '':
00508           strUnits = ""
00509         else:
00510           strUnits = " (" + reg.getEGU().units() + ")"
00511         columns = ['Time', 'Temperature' + strUnits]
00512         #self.vArrayList[self.chan3RegList[id]] = [0.0] * 100
00513         self.scrPlotView.addPlot(name=self.chan3RegList[id],
00514                                         title=self.chan3RegList[id],
00515                                         sizeX=250,
00516                                         sizeY=300,
00517                                         labels=columns)
00518     else:
00519       self.scrPlotView.removePlot(self.chan3RegList[id])
00520 
00521 
00522   def toggleChan3Mon(self, id):
00523     chk = self.bgChan3Mon.find(id)
00524     if chk.isChecked():
00525       if not self.chan3RegList[id] in self.monitorList:
00526         #self.__dictSem.acquire()
00527         self.monitorList[self.chan3RegList[id]] = eval("self.txt" + chk.name()[6:])
00528         self.adjustMonitorTextFont(self.monitorList[self.chan3RegList[id]])
00529         #self.__dictSem.release()
00530     else:
00531       if self.chan3RegList[id] in self.monitorList:
00532         self.monitorList[self.chan3RegList[id]].setText('')
00533         #self.__dictSem.acquire()
00534         self.monitorList.__delitem__(self.chan3RegList[id])
00535         #self.__dictSem.release()
00536 
00537   def toggleChan4Plot(self, id):
00538     chk = self.bgChan4Plot.find(id)
00539     if chk.isChecked():
00540       if not self.chan4RegList[id] in self.scrPlotView.getPlotList():
00541         reg = self.__gtic.regs[self.chan4RegList[id]]
00542         if reg.getEGU().units() == '':
00543           strUnits = ""
00544         else:
00545           strUnits = " (" + reg.getEGU().units() + ")"
00546         columns = ['Time', 'Temperature' + strUnits]
00547         #self.vArrayList[self.chan4RegList[id]] = [0.0] * 100
00548         self.scrPlotView.addPlot(name=self.chan4RegList[id],
00549                                         title=self.chan4RegList[id],
00550                                         sizeX=250,
00551                                         sizeY=300,
00552                                         labels=columns)
00553     else:
00554       self.scrPlotView.removePlot(self.chan4RegList[id])
00555 
00556 
00557   def toggleChan4Mon(self, id):
00558     chk = self.bgChan4Mon.find(id)
00559     if chk.isChecked():
00560       if not self.chan4RegList[id] in self.monitorList:
00561         #self.__dictSem.acquire()
00562         self.monitorList[self.chan4RegList[id]] = eval("self.txt" + chk.name()[6:])
00563         self.adjustMonitorTextFont(self.monitorList[self.chan4RegList[id]])
00564         #self.__dictSem.release()
00565     else:
00566       if self.chan4RegList[id] in self.monitorList:
00567         self.monitorList[self.chan4RegList[id]].setText('')
00568         #self.__dictSem.acquire()
00569         self.monitorList.__delitem__(self.chan4RegList[id])
00570         #self.__dictSem.release()
00571 
00572   def toggleAcdEnv1Plot(self, id):
00573     chk = self.bgAcdEnv1Plot.find(id)
00574     if chk.isChecked():
00575       reg = self.acdEnv1RegList[id]
00576       if reg.startswith('env_dac'):
00577         for i in range(12):
00578           self.acdPlotCheckList[i][id] = 1
00579       else:
00580         self.acdPlotCheckList[self.__board][id] = 1
00581       if reg.endswith('_'):
00582         reg += str(self.cmbFreeBoard.currentText())
00583       if not reg in self.scrPlotView.getPlotList():
00584         regAttr = self.__gaeq.regs[reg]
00585         if regAttr.getEGU().units() == '':
00586           strUnits = ""
00587         else:
00588           strUnits = " (" + regAttr.getEGU().units() + ")"
00589         columns = ['Time', strUnits]
00590         #self.vArrayList[self.acdEnv1RegList[id]] = [0.0] * 100
00591         self.scrPlotView.addPlot(name=reg,
00592                                         title=reg,
00593                                         sizeX=250,
00594                                         sizeY=300,
00595                                         labels=columns)
00596     else:
00597       reg = self.acdEnv1RegList[id]
00598       if reg.startswith('env_dac'):
00599         for i in range(12):
00600           self.acdPlotCheckList[i][id] = 0
00601       else:
00602         self.acdPlotCheckList[self.__board][id] = 0
00603       if reg.endswith('_'):
00604         reg += str(self.cmbFreeBoard.currentText())
00605       self.scrPlotView.removePlot(reg)
00606 
00607   def toggleAcdEnv1Mon(self, id):
00608     chk = self.bgAcdEnv1Mon.find(id)
00609     if chk.isChecked():
00610       reg = self.acdEnv1RegList[id]
00611       if reg.startswith('env_dac'):
00612         for i in range(12):
00613           self.acdMonitorCheckList[i][id] = 1
00614       else:
00615         self.acdMonitorCheckList[self.__board][id] = 1
00616       if reg.endswith('_'):
00617         reg += str(self.cmbFreeBoard.currentText())
00618       if not reg in self.monitorList:
00619         #self.__dictSem.acquire()
00620         self.monitorList[reg] = eval("self.txt" + chk.name()[6:])
00621         self.adjustMonitorTextFont(self.monitorList[reg])
00622         #self.__dictSem.release()
00623     else:
00624       reg = self.acdEnv1RegList[id]
00625       if reg.startswith('env_dac'):
00626         for i in range(12):
00627           self.acdMonitorCheckList[i][id] = 0
00628       else:
00629         self.acdMonitorCheckList[self.__board][id] = 0
00630       if reg.endswith('_'):
00631         reg += str(self.cmbFreeBoard.currentText())
00632       if reg in self.monitorList:
00633         self.monitorList[reg].setText('')
00634         #self.__dictSem.acquire()
00635         self.monitorList.__delitem__(reg)
00636         #self.__dictSem.release()
00637 
00638   def togglePDUPlot(self, id):
00639     chk = self.bgPDUPlot.find(id)
00640     if chk.isChecked():
00641       if not self.pduRegList[id] in self.scrPlotView.getPlotList():
00642         reg = self.__gtwr.regs[self.pduRegList[id]]
00643         if reg.getEGU().units() == '':
00644           strUnits = ""
00645         else:
00646           strUnits = " (" + reg.getEGU().units() + ")"
00647         if chk.name()[-1] == 'V':
00648           columns = ['Time', 'Voltage' + strUnits]
00649         else:
00650           columns = ['Time', 'Temperature' + strUnits]
00651         self.scrPlotView.addPlot(name=self.pduRegList[id],
00652                                         title=self.pduRegList[id],
00653                                         sizeX=250,
00654                                         sizeY=300,
00655                                         labels=columns)
00656     else:
00657       self.scrPlotView.removePlot(self.pduRegList[id])
00658 
00659   def togglePDUMon(self, id):
00660     chk = self.bgPDUMon.find(id)
00661     if chk.isChecked():
00662       if not self.pduRegList[id] in self.monitorList:
00663         #self.__dictSem.acquire()
00664         self.monitorList[self.pduRegList[id]] = eval("self.txt" + chk.name()[6:])
00665         self.adjustMonitorTextFont(self.monitorList[self.pduRegList[id]])
00666         #self.__dictSem.release()
00667     else:
00668       if self.pduRegList[id] in self.monitorList:
00669         self.monitorList[self.pduRegList[id]].setText('')
00670         #self.__dictSem.acquire()
00671         self.monitorList.__delitem__(self.pduRegList[id])
00672         #self.__dictSem.release()
00673 
00674 
00675   def clearPlots(self):
00676     #self.__dictSem.acquire()
00677     for txt in self.monitorList.values():
00678       txt.setText('')
00679     self.monitorList.clear()
00680     for chkId in self.scrPlotView.getPlotList().keys():
00681       self.scrPlotView.removePlot(chkId)
00682     for chkId in range(self.bgDataTakingMon.count()):
00683       self.bgDataTakingMon.find(chkId).setChecked(0)
00684       self.bgDataTakingPlot.find(chkId).setChecked(0)
00685     for chkId in range(self.bgChan0Mon.count()):
00686       self.bgChan0Mon.find(chkId).setChecked(0)
00687       self.bgChan0Plot.find(chkId).setChecked(0)
00688     for chkId in range(self.bgChan1Mon.count()):
00689       self.bgChan1Mon.find(chkId).setChecked(0)
00690       self.bgChan1Plot.find(chkId).setChecked(0)
00691     for chkId in range(self.bgChan2Mon.count()):
00692       self.bgChan2Mon.find(chkId).setChecked(0)
00693       self.bgChan2Plot.find(chkId).setChecked(0)
00694     for chkId in range(self.bgChan3Mon.count()):
00695       self.bgChan3Mon.find(chkId).setChecked(0)
00696       self.bgChan3Plot.find(chkId).setChecked(0)
00697     for chkId in range(self.bgChan4Mon.count()):
00698       self.bgChan4Mon.find(chkId).setChecked(0)
00699       self.bgChan4Plot.find(chkId).setChecked(0)
00700     for chkId in range(self.bgAcdEnv1Mon.count()):
00701       self.bgAcdEnv1Mon.find(chkId).setChecked(0)
00702       self.bgAcdEnv1Plot.find(chkId).setChecked(0)
00703     for chkId in range(self.bgPDUMon.count()):
00704       self.bgPDUMon.find(chkId).setChecked(0)
00705       self.bgPDUPlot.find(chkId).setChecked(0)
00706     #self.__dictSem.release()
00707 
00708   def initDisplays(self):
00709     #self.scrPlotView.setVScrollBarMode(QScrollView.AlwaysOn)
00710     self.frameOuterPlotsLayout = QGridLayout(self.frameOuterPlots,1,1,11,6,"frameOuterPlotsLayout")
00711     self.frameOuterPlotsLayout.addWidget(self.scrPlotView, 0, 0)
00712 
00713   def changeRate(self, val):
00714     self.__rate = val
00715 
00716   def calcDeadTime(self, regName):
00717     reg = self.__gtic.regs[regName]
00718     regNo = reg.id()
00719     resp = self.__gtic.read(regNo)
00720     status = resp.status()
00721     newVal = resp.value()
00722     newTS = resp.payloads()[1]
00723     if status == 0:
00724       if self.oldVal is None:
00725         self.oldVal = newVal
00726         self.oldTS = newTS
00727         return None
00728       else:
00729         dTime = newVal - self.oldVal
00730         dTS = newTS - self.oldTS
00731         self.oldVal = newVal
00732         self.oldTS = newTS
00733         if dTime < 0:
00734           dTime += (1L << 32)
00735         if dTS < 0:
00736           dTS += (1L << 64)
00737         if dTS != 0:                    # Make sure denominator isn't zero
00738           return (float(dTime)/float(dTS)) * (EnvMonImpl.TIMEBASE_RATE_IN_MHZ / EnvMonImpl.DEADTIME_RATE_IN_MHZ) * 100.0
00739         else:
00740           #print "dTimebase = 0"
00741           return None
00742     else:
00743       #print "Deadtime counter saturated"
00744       self.oldVal = None
00745       self.oldTS = None
00746       return None
00747 
00748   def readEnvValues(self):
00749     def updateGui(regs):
00750       for (tWidget, val) in regs.items():
00751         if self.__threadQuit != 0: break
00752         tWidget.setText(val)
00753     cnt = 0
00754     while(self.__threadQuit == 0):
00755       cnt = cnt + 1
00756       #self.__dictSem.acquire()
00757 
00758       #Make a copy of the list so that we don't have concurrency issues
00759       #with the main thread
00760       regList = copy.copy(self.monitorList)
00761       updateGuiRegs = {}
00762       #self.__dictSem.release()
00763       for regName in regList:
00764         if self.__threadQuit != 0:
00765           break
00766         if regName == "event_size" and self.DBN != {}:
00767           val = self.DBN['_event_size']
00768           strVal = "%8d" % val
00769           if not self.__bypass:
00770             strVal = strVal + "   "
00771         elif regName == "sat_deadtime_lrs_ctr":
00772           val = self.calcDeadTime(regName)
00773           if val is not None:
00774             strVal = "%3.2f%%" % val
00775           else:
00776             val    = 0
00777             strVal = "N/A"
00778           if not self.__bypass:
00779             strVal = strVal + "   "
00780         else:
00781           try:
00782             if regName.startswith('env'):
00783               reg = self.__gaeq.regs[regName]
00784               val = reg.get(bypass=self.__bypass, node=self.__gaeq)
00785             elif regName in self.pduRegList:
00786               reg = self.__gtwr.regs[regName]
00787               reg.set(0, self.__gtwr)
00788               val = reg.get(bypass=1, node=self.__gtwr) & 0xFFFF
00789               if not self.__bypass:
00790                 val = reg.getEGU().egu(val)
00791             else:
00792               reg = self.__gtic.regs[regName]
00793               val = reg.get(bypass=self.__bypass, node=self.__gtic)
00794             if not self.__bypass:
00795               if regName in self.DataTakingRegList:
00796                 strVal = "%8d" % val
00797               else:
00798                 strVal = "%8.4f" % val
00799               strVal = strVal + " %2s" % reg.getEGU().units()
00800             else:
00801               strVal = "%8d" % val
00802           except:
00803             val    = 0
00804             strVal = "N/A"
00805         if not regName.startswith('env') or regName.startswith('env_dac'):
00806           #regList[regName].setText(strVal)
00807           #self.execGUImethodNR(regList[regName].setText, strVal)
00808           updateGuiRegs[regList[regName]] = strVal
00809         elif regName[-3:] == self.__freeBoard:
00810           #regList[regName].setText(strVal)
00811           #self.execGUImethodNR(regList[regName].setText, strVal)
00812           updateGuiRegs[regList[regName]] = strVal
00813         if regName in self.scrPlotView.getPlotList():
00814           plot = self.scrPlotView.getPlot(regName)
00815           if regName == "event_size" and self.DBN != {}:
00816             self.DBN['_EventSizeNTuple'].setIntervalEnabled(0)
00817             #plot.update()
00818             self.DBN['_EventSizeNTuple'].setIntervalEnabled(1)
00819           else:
00820             nt = plot.getNTuple()
00821             nt.addRow([cnt, val])
00822       #self.__dictSem.release()
00823       if updateGuiRegs != {}:
00824          self.execGUImethodNR(updateGui, updateGuiRegs)
00825 
00826       t0 = time.time()
00827       while (time.time() - t0 < 2.1 - self.__rate*0.02):
00828         time.sleep(.1)
00829         if self.__threadQuit != 0:
00830           break
00831     # Make sure all the previous calls to GUI bridge
00832     # get processed before shutdown
00833     if self.__threadQuit == 1:
00834       self.execGUImethodNR(self.shutdown)
00835 
00836   def shutdown(self):
00837     self.__threadQuit = 1
00838     self.threadReadEnv.shutdown()
00839     self.inShutdown = True
00840     self.__guiBridge.shutdown()
00841     time.sleep(.1)
00842     self.unregisterExitHandler()
00843     self.close()
00844     #self.deleteLater()
00845 
00846   def quitApp(self):
00847     self.__threadQuit = 2
00848     self.inShutdown = True
00849     self.threadReadEnv.shutdown()
00850     self.__guiBridge.shutdown()
00851     time.sleep(.1)
00852     self.unregisterExitHandler()
00853 
00854   def unregisterExitHandler(self):
00855     for i in range(len(atexit._exithandlers)):
00856       if atexit._exithandlers[i][0] == self.quitApp:
00857         del atexit._exithandlers[i]
00858         break
00859 
00860   def closeEvent(self, e):
00861     if self.__threadQuit == 0:
00862       # Before the user closes the app we want to
00863       # shutdown, so ignore the close request and
00864       # let the thread finish to its completion
00865       # which will call shutdown where the actual
00866       # close happens.
00867       self.__threadQuit = 1
00868       #self.shutdown()
00869       #e.accept()
00870       e.ignore()
00871     else:
00872       e.accept()
00873 
00874   def customEvent(self, e):
00875     """This method overrides the QObject base class's.  There is generally
00876     no reason to call this method directly.  It is called by the Qt
00877     infrastructure whenever the custom event is posted, e.g. by the following
00878     three methods of this class: createGUI, execGUImethodNR and execGUImethod.
00879     """
00880     self.__guiBridge.handleCustomEvent(e)
00881 
00882   def execGUImethodNR(self, func, *args, **kwargs):
00883     """Method used for executing a GUI function from a non-GUI thread.
00884     Use this method when no (useful) response is expected or
00885     when waiting for one could cause a deadlock.  Any response from the
00886     function is lost."""
00887     if self.inShutdown:  return # Don't try to update the GUI during shutdown
00888 
00889     return self.__guiBridge.execGUImethodNR(self, func, *args, **kwargs)
00890 
00891   def execGUImethod(self, func, *args, **kwargs):
00892     """Method used for executing a GUI function from a non-GUI thread.
00893     Use this method when a response is expected from the function and
00894     when it is appropriate to wait for it (no deadlock arises)"""
00895     if self.inShutdown:  return # Don't try to update the GUI during shutdown
00896 
00897     return self.__guiBridge.execGUImethod(self, func, *args, **kwargs)
00898 
00899 
00900 
00901 class PlotWidget(QtViewWidget):
00902 
00903   class EnvMonSetRangeImpl(EnvMonSetRange):
00904     def __init__(self, parent = None,name = None,fl = 1):
00905       EnvMonSetRange.__init__(self,parent,name,fl)
00906       QObject.connect(self.btnOK,     SIGNAL("clicked()"), self.OKButtonClicked)
00907       QObject.connect(self.btnCancel, SIGNAL("clicked()"), self.CancelButtonClicked)
00908       self.__cancel = 1
00909 
00910     def OKButtonClicked(self):
00911       self.__cancel = 0
00912       self.close()
00913 
00914     def CancelButtonClicked(self):
00915       self.close()
00916 
00917     def getMinMax(self):
00918       rect = self.parentWidget().geometry()
00919       self.move (rect.center().x() - self.rect().center().x(),
00920                  rect.center().y() - self.rect().center().y())
00921       self.txtMinVal.setFocus()
00922       self.show()
00923       self.exec_loop()
00924       if self.__cancel:
00925         return None
00926       else:
00927         return (str(self.txtMinVal.text()), str(self.txtMaxVal.text()))
00928 
00929   def __init__(self, envMonDlg, parent, title, sizeX, sizeY, labels):
00930     QtViewWidget.__init__(self, parent, "", Qt.WStaticContents | Qt.WRepaintNoErase)
00931     #QtViewWidget.__init__(self, parent, "")
00932     self.printer=QPrinter()
00933     self.__setRangeDlg = self.EnvMonSetRangeImpl(envMonDlg)
00934     ntc = NTupleController.instance()
00935     self.__nt = ntc.createCircularBuffer(2)
00936     self.__nt.setLabels(labels)
00937     self.__nt.setTitle(title)
00938     self.__nt.reserve(100)
00939     dc = DisplayController.instance()
00940     self.__plot = dc.createDisplay('Strip Chart', self.__nt, labels)
00941     self.setPlotter (self.__plot)
00942     self.setDoubleBuffering(1)
00943     self.resize(sizeX, sizeY)
00944     self.show()
00945 
00946   def getNTuple(self):
00947     return self.__nt
00948 
00949   def contextMenuEvent(self, cmev):
00950     contextMenu = QPopupMenu( self )
00951     caption = QLabel( self )
00952     caption.setAlignment( Qt.AlignCenter )
00953     caption.setText("<font color=darkblue><u><b>Context Menu</b></u></font>")
00954     contextMenu.insertItem(caption)
00955     contextMenu.insertItem( "&Print to printer", self.printPlot, Qt.CTRL+Qt.Key_P)
00956     contextMenu.insertItem( "&Save to &file", self.saveToFile, Qt.CTRL+Qt.Key_S)
00957     contextMenu.insertSeparator()
00958     contextMenu.insertItem( "&Set Range", self.setRange, Qt.CTRL+Qt.Key_R)
00959     contextMenu.exec_loop(QCursor.pos())
00960 
00961   def printPlot(self):
00962     if not self.printer:
00963       self.printer = QPrinter()
00964     if self.printer.setup(self):
00965       pp=QPainter(self.printer)
00966       self.draw(pp)
00967 
00968   def saveToFile(self):
00969     imgFormatList = []
00970     ifQList = QImage.outputFormatList()
00971     fileSpec = "Images ("
00972     for imgFormat in ifQList:
00973       imgFormat = str(imgFormat)
00974       if imgFormat == 'JPEG': imgFormat = 'JPG'
00975       imgFormatList = imgFormatList + [imgFormat]
00976       fileSpec = fileSpec + " *." + imgFormat.lower()
00977     fileSpec = fileSpec + " )"
00978     fileName = QFileDialog.getSaveFileName(QString.null, fileSpec,
00979                          self, "file save as bitmap",
00980                          "Plot -- File Save As Bitmap")
00981     fileName = str(fileName)
00982     if fileName != '':
00983       sep = fileName.rfind('.')
00984       if not sep:
00985         QMessageBox.critical(self, "Environmental Quantity Monitor",
00986                               "Can not determine the output image format without an extension")
00987       else:
00988         imgFormat = fileName[sep+1:].upper()
00989         if imgFormat not in imgFormatList:
00990           QMessageBox.critical(self, "Environmental Quantity Monitor",
00991                               "Unsupported image format:%s" % fileName[fileName.rfind('.')+1:].upper())
00992         else:
00993           if imgFormat == 'JPG': imgFormat = 'JPEG'
00994           plotPixmap = QPixmap.grabWidget(self)
00995           plotPixmap.save(fileName, imgFormat)
00996 
00997 
00998   def setRange(self):
00999     minMax = self.__setRangeDlg.getMinMax()
01000     if minMax is not None:
01001       self.__plot.setRange('y', float(minMax[0]), float(minMax[1]))
01002 
01003 class ScrollablePlotView(QScrollView):
01004   def __init__(self, dbn, parent = None,name = None,fl = 0):
01005     QScrollView.__init__(self, parent, name, fl)
01006     self.__parent = parent
01007     self.__dbn = dbn
01008     self._plots = []
01009     self.setVScrollBarMode(QScrollView.AlwaysOn)
01010     self.box = QVBox(self.viewport())
01011     self.addChild(self.box)
01012     self.__nTupleList = {}
01013     self.__plotList = {}
01014     self.viewport().setFocusProxy( self );
01015     self.viewport().setFocusPolicy( QWidget.WheelFocus );
01016 
01017   def addPlot(self, name, title, sizeX, sizeY, labels):
01018     plot = PlotWidget(self.__parent, self.box, title, sizeX, sizeY, labels)
01019     self.__nTupleList[name] = plot.getNTuple()
01020     self.__plotList[name] = plot
01021     return plot
01022 
01023   def initEventPlot(self): # revisit
01024     dc = DisplayController.instance()
01025     self.eventPlotter = dc.createDisplay('Histogram', self.__dbn['_EventSizeNTuple'], ['Event Size'])
01026     self.eventWidget = QtViewWidget(self.box, '', Qt.WStaticContents | Qt.WRepaintNoErase)
01027     self.eventWidget.setDoubleBuffering(1)
01028     self.eventWidget.setPlotter (self.eventPlotter)
01029     self.eventWidget.resize(250, 300)
01030     self.eventWidget.hide()
01031 
01032   def addEventPlot(self, name):
01033     self.__plotList[name] = self.eventWidget
01034     self.eventWidget.show()
01035     return self.eventWidget
01036 
01037 
01038   def removePlot(self, name):
01039     if name == "event_size":
01040       self.eventWidget.hide()
01041       self.__plotList.__delitem__(name)
01042     else:
01043       self.box.removeChild(self.getPlot(name))
01044       self.__nTupleList.__delitem__(name)
01045       self.__plotList.__delitem__(name)
01046 
01047   def getPlot(self, name):
01048     return self.__plotList[name]
01049 
01050   def getNTupleList(self):
01051     return self.__nTupleList
01052 
01053   def getPlotList(self):
01054     return self.__plotList
01055 
01056 
01057 
01058 if __name__ == "__main__":
01059   from LATTE.runcontrol.RunControlCommon import RunControlCommon
01060 
01061   rcCommon = RunControlCommon()
01062   rcCommon.initialize()
01063   rcCommon.setLoggingLevel("INFO")
01064   rcCommon.connect()
01065 
01066   a = QApplication(sys.argv)
01067   em = EnvMonImpl(rcCommon)
01068   QObject.connect(a,SIGNAL("lastWindowClosed()"), a, SLOT("quit()"))
01069   a.setMainWidget(em)
01070   em.show()
01071   a.exec_loop()
01072 

Generated on Fri Jul 21 13:26:27 2006 for LATTE R04-12-00 by doxygen 1.4.3