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