00001 00002 #!/usr/local/bin/python 00003 # 00004 # Copyright 2003 00005 # by 00006 # The Board of Trustees of the 00007 # Leland Stanford Junior University. 00008 # All rights reserved. 00009 # 00010 00011 00012 __facility__ = "Online" 00013 __abstract__ = "GLAST Online Single Event Display - EBF Interface" 00014 __author__ = "A. Kavelaars <aliciak@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00015 __date__ = "11/18/2003" 00016 __version__ = "$Revision: 1.45 $" 00017 __credits__ = "SLAC" 00018 00019 import LATTE.copyright_SLAC 00020 from qt import * 00021 import os, sys, string 00022 import LDF 00023 import Numeric 00024 import time 00025 import logging as myLog 00026 # Important Constants 00027 00028 NUM_XY_TKR = 24 00029 NUM_Z_TKR = 36 00030 NUM_Z_CAL = 8 00031 NUM_XY_CAL = 12 00032 00033 LOG_RANGE = 12 00034 NUMBER_STRIPS = 1536 00035 STRIP_RANGE = 36 00036 00037 LAYER = ['Y0','X0','X1','Y1','Y2','X2','X3','Y3','Y4','X4','X5','Y5','Y6', 00038 'X6','X7','Y7','Y8','X8','X9','Y9','Y10','X10','X11','Y11','Y12', 00039 'X12','X13','Y13','Y14','X14','X15','Y15','Y16','X16','X17','Y17'] 00040 00041 #~ TCC = ['0,1','2,3','4,5'] 00042 00043 RANGE_TKR_X = [1,2,5,6,9,10,13,14,17,18,21,22,25,26,29,30,33,34] 00044 RANGE1_TKR_X = [1, 5, 9, 13, 17, 21, 25, 29, 33] 00045 RANGE2_TKR_X = [2, 6, 10, 14, 18, 22, 26, 30, 34] 00046 00047 RANGE_TKR_Y = [0,3,4,7,8,11,12,15,16,19,20,23,24,27,28,31,32,35] 00048 00049 RANGE1_TKR_Y = [4, 8, 12, 16, 20, 24, 28, 32, 35] 00050 RANGE2_TKR_Y = [0, 3, 7, 11, 15, 19, 23, 27, 31] 00051 RANGE_CAL_X = [0,2,4,6] 00052 RANGE_CAL_Y = [1,3,5,7] 00053 # TEM cc geometry (real) 00054 #~ OFFSET = [0, 0, 1, 1, 3, 3, 2, 2] 00055 #~ Minitower cc geometry (inverted) 00056 #~ OFFSET = [1, 1, 0, 0, 2, 2, 3, 3] 00057 00058 00059 ACD_SIDE0 = 0 00060 ACD_SIDE1 = 1 00061 ACD_SIDE2 = 2 00062 ACD_SIDE3 = 3 00063 ACD_SIDE4 = 4 00064 ACD_SIDE5 = 5 # ??? 00065 ACD_SIDE6 = 6 # ??? 00066 ACD_NA = 7 # ??? 00067 LOOKUP_ACD_TILE = {"120" : (ACD_SIDE1, 4, 2), "NA4" : (ACD_NA, 0, 0), 00068 "502" : (ACD_SIDE5, 0, 0), "NA5" : (ACD_NA, 0, 0), 00069 "121" : (ACD_SIDE1, 3, 2), "111" : (ACD_SIDE1, 3, 1), 00070 "101" : (ACD_SIDE1, 3, 0), "122" : (ACD_SIDE1, 2, 2), 00071 "112" : (ACD_SIDE1, 2, 1), "102" : (ACD_SIDE1, 2, 0), 00072 "103" : (ACD_SIDE1, 1, 0), "113" : (ACD_SIDE1, 1, 1), 00073 "123" : (ACD_SIDE1, 1, 2), "503" : (ACD_SIDE5, 0, 0), 00074 "104" : (ACD_SIDE1, 0, 0), "114" : (ACD_SIDE1, 0, 1), 00075 "124" : (ACD_SIDE1, 0, 2), "130" : (ACD_SIDE1, 0, 3), 00076 "110" : (ACD_SIDE1, 4, 1), "100" : (ACD_SIDE1, 4, 0), 00077 "220" : (ACD_SIDE2, 2, 4), "210" : (ACD_SIDE2, 1, 4), 00078 "600" : (ACD_SIDE6, 0, 0), "200" : (ACD_SIDE2, 0, 4), 00079 "000" : (ACD_SIDE0, 4, 4), "010" : (ACD_SIDE0, 3, 4), 00080 "020" : (ACD_SIDE0, 2, 4), "221" : (ACD_SIDE2, 2, 3), 00081 "211" : (ACD_SIDE2, 1, 3), "201" : (ACD_SIDE2, 0, 3), 00082 "001" : (ACD_SIDE0, 4, 3), "011" : (ACD_SIDE0, 3, 3), 00083 "021" : (ACD_SIDE0, 2, 3), "022" : (ACD_SIDE0, 2, 2), 00084 "NA6" : (ACD_NA, 0, 0), "002" : (ACD_SIDE0, 4, 2), 00085 "222" : (ACD_SIDE2, 2, 2), "602" : (ACD_SIDE6, 0, 0), 00086 "212" : (ACD_SIDE2, 1, 2), "202" : (ACD_SIDE2, 0, 2), 00087 "012" : (ACD_SIDE0, 3, 2), "013" : (ACD_SIDE0, 3, 1), 00088 "003" : (ACD_SIDE0, 4, 1), "203" : (ACD_SIDE2, 0, 1), 00089 "213" : (ACD_SIDE2, 1, 1), "223" : (ACD_SIDE2, 2, 1), 00090 "014" : (ACD_SIDE0, 3, 0), "004" : (ACD_SIDE0, 4, 0), 00091 "204" : (ACD_SIDE2, 0, 0), "NA7" : (ACD_NA, 0, 0), 00092 "214" : (ACD_SIDE2, 1, 0), "224" : (ACD_SIDE2, 2, 0), 00093 "NA10" : (ACD_NA, 0, 0), "230" : (ACD_SIDE2, 3, 0), 00094 "324" : (ACD_SIDE3, 0, 1), "NA9" : (ACD_NA, 0, 0), 00095 "501" : (ACD_SIDE5, 0, 0), "NA8" : (ACD_NA, 0, 0), 00096 "323" : (ACD_SIDE3, 1, 1), "313" : (ACD_SIDE3, 1, 2), 00097 "303" : (ACD_SIDE3, 1, 3), "322" : (ACD_SIDE3, 2, 1), 00098 "312" : (ACD_SIDE3, 2, 2), "302" : (ACD_SIDE3, 2, 3), 00099 "301" : (ACD_SIDE3, 3, 3), "311" : (ACD_SIDE3, 3, 2), 00100 "321" : (ACD_SIDE3, 3, 1), "500" : (ACD_SIDE5, 0, 0), 00101 "300" : (ACD_SIDE3, 4, 3), "310" : (ACD_SIDE3, 4, 2), 00102 "320" : (ACD_SIDE3, 4, 1), "330" : (ACD_SIDE3, 0, 0), 00103 "314" : (ACD_SIDE3, 0, 2), "304" : (ACD_SIDE3, 0, 3), 00104 "NA0" : (ACD_NA, 0, 0), "424" : (ACD_SIDE4, 1, 0), 00105 "603" : (ACD_SIDE6, 0, 0), "414" : (ACD_SIDE4, 2, 0), 00106 "404" : (ACD_SIDE4, 3, 0), "044" : (ACD_SIDE0, 0, 0), 00107 "034" : (ACD_SIDE0, 1, 0), "024" : (ACD_SIDE0, 2, 0), 00108 "423" : (ACD_SIDE4, 1, 1), "413" : (ACD_SIDE4, 2, 1), 00109 "403" : (ACD_SIDE4, 3, 1), "043" : (ACD_SIDE0, 0, 1), 00110 "033" : (ACD_SIDE0, 1, 1), "023" : (ACD_SIDE0, 2, 1), 00111 "NA1" : (ACD_NA, 0, 0), "042" : (ACD_SIDE0, 0, 2), 00112 "422" : (ACD_SIDE4, 1, 2), "601" : (ACD_SIDE6, 0, 0), 00113 "412" : (ACD_SIDE4, 2, 2), "402" : (ACD_SIDE4, 3, 2), 00114 "032" : (ACD_SIDE0, 1, 2), "031" : (ACD_SIDE0, 1, 3), 00115 "041" : (ACD_SIDE0, 0, 3), "401" : (ACD_SIDE4, 3, 3), 00116 "411" : (ACD_SIDE4, 2, 3), "421" : (ACD_SIDE4, 1, 3), 00117 "030" : (ACD_SIDE0, 1, 4), "040" : (ACD_SIDE0, 0, 4), 00118 "400" : (ACD_SIDE4, 3, 4), "NA2" : (ACD_NA, 0, 0), 00119 "410" : (ACD_SIDE4, 2, 4), "420" : (ACD_SIDE4, 1, 4), 00120 "NA3" : (ACD_NA, 0, 0), "430" : (ACD_SIDE4, 0, 0), 00121 } 00122 LOOKUP_ACD_XZM = ["200", "201", "202", "203", "204", 00123 "210", "211", "212", "213", "214", 00124 "220", "221", "222", "223", "224", 00125 "230"] 00126 LOOKUP_ACD_XZP = ["400", "401", "402", "403", "404", 00127 "410", "411", "412", "413", "414", 00128 "420", "421", "422", "423", "424", 00129 "430"] 00130 LOOKUP_ACD_YZM = ["100", "101", "102", "103", "104", 00131 "110", "111", "112", "113", "114", 00132 "120", "121", "122", "123", "124", 00133 "130"] 00134 LOOKUP_ACD_YZP = ["300", "301", "302", "303", "304", 00135 "310", "311", "312", "313", "314", 00136 "320", "321", "322", "323", "324", 00137 "330"] 00138 LOOKUP_ACD_XY = ["000", "001", "002", "003", "004", 00139 "010", "011", "012", "013", "014", 00140 "020", "021", "022", "023", "024", 00141 "030", "031", "032", "033", "034", 00142 "040", "041", "042", "043", "044"] 00143 LOOKUP_ACD_RBN = ["500", "501", "502", "503", 00144 "600", "601", "602", "603"] 00145 LOOKUP_ACD_NA = ["NA0", "NA1", "NA2", "NA3", "NA4", 00146 "NA5", "NA6", "NA7", "NA8", "NA9", 00147 "NA10"] 00148 00149 00150 class GEMcontribution_(object): 00151 __condSumName = ["ROI", "TKR", "CAL_LE", "CAL_HE", "CNO", "Periodic", "Solicited", "External"] 00152 def __init__(self, event, contribution, gui): 00153 self.__event = event 00154 self.__contribution = contribution 00155 self.__gui = gui 00156 00157 def __getattr__(self, attr): 00158 """This method fakes up inheritance from an LDF.GEMcontribution. 00159 When a called method can not be found to belong to this class, this 00160 method is called. We use it to redirect the call to the 'base' class. 00161 """ 00162 return getattr(self.__contribution, attr) 00163 00164 def __drawRing(self, drawACDside, nX, nY, i, j, extraWPix, extraHPix): 00165 color = QColor("magenta") 00166 00167 tileWidth = drawACDside.width()/nX 00168 tileHeight = drawACDside.height()/nY 00169 00170 pACD = QPainter(drawACDside.final) 00171 pACD.setPen(color) 00172 pACD.drawRect(tileWidth * i, tileHeight * j, tileWidth + extraWPix, tileHeight + extraHPix) 00173 pACD.end() 00174 00175 def __drawTile(self, drawACDside, nX, nY, mask, lookup): 00176 i = 0 00177 while (mask): 00178 if mask & 1: 00179 tile = lookup[i] 00180 tileIJ = LOOKUP_ACD_TILE[tile] 00181 if tile == "130" or tile == "330": 00182 nX = 1 00183 extraWPix = 0 00184 else: 00185 extraWPix = 1 00186 if tile == "230" or tile == "430": 00187 nY = 1 00188 extraHPix = 0 00189 else: 00190 extraHPix = 1 00191 self.__drawRing(drawACDside, nX, nY, tileIJ[1], tileIJ[2], extraWPix, extraHPix) 00192 mask >>= 1 00193 i += 1 00194 00195 def plot(self): 00196 gui = self.__gui 00197 tl = self.tileList() 00198 00199 drawHatACD = gui.drawHatACD 00200 drawSide1ACD = gui.drawSide1ACD 00201 drawSide2ACD = gui.drawSide2ACD 00202 drawSide3ACD = gui.drawSide3ACD 00203 drawSide4ACD = gui.drawSide4ACD 00204 00205 self.__drawTile(drawSide4ACD, 4, 5, tl.XZP(), LOOKUP_ACD_XZP) 00206 self.__drawTile(drawSide2ACD, 4, 5, tl.XZM(), LOOKUP_ACD_XZM) 00207 self.__drawTile(drawSide3ACD, 5, 4, tl.YZP(), LOOKUP_ACD_YZP) 00208 self.__drawTile(drawSide1ACD, 5, 4, tl.YZM(), LOOKUP_ACD_YZM) 00209 self.__drawTile(drawHatACD, 5, 5, tl.XY(), LOOKUP_ACD_XY) 00210 #self.__drawTile(gui.drawNAACD, tl.NA(), LOOKUP_ACD_NA) 00211 #self.__drawTile(gui.drawRBNACD, tl.RBN(), LOOKUP_ACD_RBN) 00212 00213 # Request that the screen is updated, for those Widgets that need it 00214 if drawHatACD.isVisible(): 00215 drawHatACD.update() 00216 drawSide1ACD.update() 00217 drawSide2ACD.update() 00218 drawSide3ACD.update() 00219 drawSide4ACD.update() 00220 00221 if gui.drawGOSEDData.isVisible(): 00222 opt = self.onePPStime() 00223 00224 out = [] 00225 00226 out.append(["ROI vector", "0x%04x" % (self.roiVector())]) 00227 out.append(["TKR vector", "0x%04x" % (self.tkrVector())]) 00228 out.append(["CAL HE vector", "0x%04x" % (self.calHEvector())]) 00229 out.append(["CAL LE vector", "0x%04x" % (self.calLEvector())]) 00230 00231 cs = self.conditionSummary() 00232 csVal = cs 00233 csStr = "" 00234 csIdx = 0 00235 while csVal: 00236 if csVal & 0x1: csStr = self.__condSumName[csIdx] + " " + csStr 00237 csIdx += 1 00238 csVal >>= 1 00239 00240 out.append(["Condition summary", "0x%02x = %s" % (cs, csStr)]) 00241 out.append(["Missed", "0x%02x" % (self.missed())]) 00242 out.append(["CNO vector", "0x%04x" % (self.cnoVector())]) 00243 out.append(["Veto list:", ""]) 00244 out.append([" XZP, XZM", "0x%04x, 0x%04x" % (tl.XZP(), tl.XZM())]) 00245 out.append([" YZP, YZM", "0x%04x, 0x%04x" % (tl.YZP(), tl.YZM())]) 00246 out.append([" XY", "0x%08x" % (tl.XY())]) 00247 out.append([" NA, RBN", "0x%04x, 0x%04x" % (tl.NA(), tl.RBN())]) 00248 out.append(["Live time", "0x%08x = %d" % (self.liveTime(), self.liveTime())]) 00249 out.append(["Prescaled", "0x%08x = %d" % (self.prescaled(), self.prescaled())]) 00250 out.append(["Discarded", "0x%08x = %d" % (self.discarded(), self.discarded())]) 00251 #out.append(["Sent = 0x%08x = %d" % (self.sent(), self.sent())) 00252 out.append(["Condition arrival:", ""]) 00253 out.append([" Raw", "0x%08x " % (self.condArrTime().datum())]) 00254 out.append([" External", "0x%02x = %d" % (self.condArrTime().external(), self.condArrTime().external() )]) 00255 out.append([" CNO", "0x%02x = %d" % (self.condArrTime().cno() , self.condArrTime().cno() )]) 00256 out.append([" CAL HE", "0x%02x = %d" % (self.condArrTime().calHE() , self.condArrTime().calHE() )]) 00257 out.append([" CAL LE", "0x%02x = %d" % (self.condArrTime().calLE() , self.condArrTime().calLE() )]) 00258 out.append([" TKR", "0x%02x = %d" % (self.condArrTime().tkr() , self.condArrTime().tkr() )]) 00259 out.append([" ROI", "0x%02x = %d" % (self.condArrTime().roi() , self.condArrTime().roi() )]) 00260 out.append(["Trigger time", "0x%08x = %d" % (self.triggerTime(), self.triggerTime())]) 00261 out.append(["One PPS time:", ""]) 00262 out.append([" seconds, timebase", "0x%02x, 0x%07x = %d, %d" % \ 00263 (opt.seconds(), opt.timebase(), opt.seconds(), opt.timebase())]) 00264 out.append(["Delta window open time", "0x%04x = %d" % (self.deltaWindowOpenTime(), self.deltaWindowOpenTime())]) 00265 out.append(["Delta event time", "0x%08x = %d" % (self.deltaEventTime(), self.deltaEventTime())]) 00266 00267 view = gui.drawGOSEDData.trigger 00268 #~ view2 = gui.drawGOSEDData.trigger2 00269 #~ text = "" 00270 #~ for item in out: 00271 #~ text += item[0] + " " + item[1] + "\n" 00272 #~ view2.setText(text) 00273 # Next 4 lines are a trick to freeze sorting 00274 view.setSorting(-1) 00275 firstParameter = out[0] 00276 oldItem = QListViewItem(view, firstParameter[0] + " ", firstParameter[1]) 00277 out = out[1:] 00278 for parameter in out: 00279 item = QListViewItem(view, oldItem, parameter[0] + " ", parameter[1]) 00280 oldItem = item 00281 00282 class AEMcontributionIterator_(LDF.AEMcontributionIterator): 00283 __drawSide = [] 00284 def __init__(self,event,contribution, gui, lci): 00285 LDF.AEMcontributionIterator.__init__(self,event,contribution) 00286 self.__gui = gui 00287 self.__acdPeds = gui.GOSEDPreferencesGUI.getAcdPeds() 00288 self.__minValue = gui.GOSEDPreferencesGUI.minACD() 00289 self.__maxValue = gui.GOSEDPreferencesGUI.maxACD() 00290 00291 self.__drawSide.append(self.__drawHatTile) 00292 self.__drawSide.append(self.__drawSide1Tile) 00293 self.__drawSide.append(self.__drawSide2Tile) 00294 self.__drawSide.append(self.__drawSide3Tile) 00295 self.__drawSide.append(self.__drawSide4Tile) 00296 self.__drawSide.append(self.__drawSide5Tile) 00297 self.__drawSide.append(self.__drawSide6Tile) 00298 self.__drawSide.append(self.__drawNATile) 00299 00300 def __drawTile(self, drawACDside, nX, nY, i, j, ab, color): 00301 tileWidth = drawACDside.width()/nX 00302 tileHeight = drawACDside.height()/nY 00303 00304 # To embed triangles in tiles: 00305 # For every i, add 1 00306 # For every i+1, substract 1 00307 arr = QPointArray() 00308 if ab: 00309 arr.setPoints([tileWidth*i + 1, tileHeight*j + 1, 00310 tileWidth*(i+1) - 1, tileHeight*j + 1, 00311 tileWidth*i + 1, tileHeight*(j+1) - 1]) 00312 else: 00313 arr.setPoints([tileWidth*(i+1) - 1, tileHeight*(j+1) - 1, 00314 tileWidth*(i+1) - 1, tileHeight*j + 1, 00315 tileWidth*i + 1, tileHeight*(j+1) - 1]) 00316 00317 pACD = QPainter(drawACDside.final) 00318 #pACD.setRasterOp(Qt.AndROP) 00319 pACD.setBrush(color) 00320 pACD.setPen(color) 00321 pACD.drawPolygon(arr) 00322 pACD.end() 00323 00324 def __drawHatTile(self, i, j, ab, color): 00325 drawHatACD = self.__gui.drawHatACD 00326 self.__drawTile(drawHatACD, 5, 5, i, j, ab, color) 00327 # ATK-051110: Must be painted here to avoid that 00328 # the display flickers on update. 00329 drawHatACD.drawNames(drawHatACD.final) 00330 00331 def __drawSide1Tile(self, i, j, ab, color): 00332 drawSide1ACD = self.__gui.drawSide1ACD 00333 if j < 3: 00334 self.__drawTile(drawSide1ACD, 5, 4, i, j, ab, color) 00335 else: 00336 self.__drawTile(drawSide1ACD, 1, 4, i, j, ab, color) 00337 # ATK-051110: Must be painted here to avoid that 00338 # the display flickers on update. 00339 drawSide1ACD.drawNames(drawSide1ACD.final) 00340 00341 def __drawSide2Tile(self, i, j, ab, color): 00342 drawSide2ACD = self.__gui.drawSide2ACD 00343 if i < 3: 00344 self.__drawTile(drawSide2ACD, 4, 5, i, j, ab, color) 00345 else: 00346 self.__drawTile(drawSide2ACD, 4, 1, i, j, ab, color) 00347 # ATK-051110: Must be painted here to avoid that 00348 # the display flickers on update. 00349 drawSide2ACD.drawNames(drawSide2ACD.final) 00350 00351 def __drawSide3Tile(self, i, j, ab, color): 00352 drawSide3ACD = self.__gui.drawSide3ACD 00353 if j > 0: 00354 self.__drawTile(drawSide3ACD, 5, 4, i, j, ab, color) 00355 else: 00356 self.__drawTile(drawSide3ACD, 1, 4, i, j, ab, color) 00357 # ATK-051110: Must be painted here to avoid that 00358 # the display flickers on update. 00359 drawSide3ACD.drawNames(drawSide3ACD.final) 00360 00361 def __drawSide4Tile(self, i, j, ab, color): 00362 drawSide4ACD = self.__gui.drawSide4ACD 00363 if i > 0: 00364 self.__drawTile(drawSide4ACD, 4, 5, i, j, ab, color) 00365 else: 00366 self.__drawTile(drawSide4ACD, 4, 1, i, j, ab, color) 00367 # ATK-051110: Must be painted here to avoid that 00368 # the display flickers on update. 00369 drawSide4ACD.drawNames(drawSide4ACD.final) 00370 00371 def __drawSide5Tile(self, i, j, ab, color): 00372 pass 00373 00374 def __drawSide6Tile(self, i, j, ab, color): 00375 pass 00376 00377 def __drawNATile(self, i, j, ab, color): 00378 pass 00379 00380 def plot(self, prefix = ""): 00381 gui = self.__gui 00382 00383 drawHatACD = gui.drawHatACD 00384 drawSide1ACD = gui.drawSide1ACD 00385 drawSide2ACD = gui.drawSide2ACD 00386 drawSide3ACD = gui.drawSide3ACD 00387 drawSide4ACD = gui.drawSide4ACD 00388 00389 self.iterate() 00390 00391 # Request that the screen is updated, for those Widgets that need it 00392 if drawHatACD.isVisible(): 00393 drawHatACD.update() 00394 drawSide1ACD.update() 00395 drawSide2ACD.update() 00396 drawSide3ACD.update() 00397 drawSide4ACD.update() 00398 00399 def header(self, cable, hdr): 00400 # RiC 9/8/05 - Refrain from printing out "Cable has no data" cases 00401 if self.__gui.drawGOSEDData.isVisible() and hdr.phaVector(): 00402 out = self.__gui.drawGOSEDData.acd 00403 00404 out.append( "Cable %d = FREE board '%s' header:" % \ 00405 (cable, self.map().freeName(self.event().identity(), cable))) 00406 out.append( " start-bit = %01x" % (hdr.startBit())) 00407 out.append( " hit-map = 0x%05x" % (hdr.hitMap())) 00408 out.append( " accept-map = 0x%05x" % (hdr.acceptMap())) 00409 out.append( " PHA vector = %01x" % (hdr.phaVector())) 00410 out.append( " header parity error = %01x" % (hdr.parityError())) 00411 00412 # RiC 9/8/05 - Changed to refrain from printing out "Cable has no data" 00413 #if ( hdr.phaVector() ): 00414 out.append( " Value parity") 00415 out.append( " Channel Tile Side Range (hex) (dec) error More") 00416 #else: 00417 # out.append( "Cable %d has no data" % (cable)) 00418 00419 def pha(self, cable, channel, p): 00420 id = self.event().identity() 00421 tbl = self.map().lookup(id, cable, channel) 00422 tile = tbl.name() 00423 pha = p.ADCvalue() 00424 if self.__acdPeds is not None: # subtract pedestals if available 00425 pha -= self.__acdPeds[cable,channel,p.ADCrange(),0] 00426 00427 if self.__gui.drawGOSEDData.isVisible(): 00428 out = self.__gui.drawGOSEDData.acd 00429 if tbl.a(): side = 'A' 00430 else: side = 'B' 00431 out.append(" %2d %4s %s %d 0x%03x = %4d %d %d" % \ 00432 (channel, tbl.name(), side, p.ADCrange(), p.ADCvalue(), 00433 p.ADCvalue(), p.parityError(), p.more())) 00434 00435 # Map range 0 to lower half scale, range 1 to upper half scale 00436 import colorScale 00437 dv = float(self.__maxValue - self.__minValue) 00438 if dv == 0.0: dv = 1.0e-308 00439 v = 0.5 * (p.ADCrange() + (float(pha) - float(self.__minValue)) / dv) 00440 r, g, b = colorScale.colorScale(v) 00441 00442 color = QColor(r, g, b) 00443 00444 tileSide = LOOKUP_ACD_TILE[tile] 00445 self.__drawSide[tileSide[0]](tileSide[1], tileSide[2], tbl.a(), color) 00446 00447 # class CALcontributionIterator1(LDF.CALcontributionIterator): 00448 # """ \brief CAL contribution Filter 00449 00450 # This class obtains the information of CAL from EBF to setup the min and max 00451 # engery of the event. To do so it filters by event, twr, and range. Using the 00452 # GOSED Preferences menu (from the Tools tab on the menu bar), if the scale is 00453 # selected as ACD Calibration, the min and max values will be determined for 00454 # every event as the min and max value of ACD counts that that event has. 00455 # If Default is selected, min and max will be 0 and 1000 ACD counts, 00456 # respectively. If Custom is selected, the user will select its own min and 00457 # max values of interest from the GOSED Preferences menu """ 00458 00459 # def __init__(self, event, contribution, gui, lci): 00460 # """ CALcontributionIterator1 contructor 00461 00462 # \param event Event 00463 # \param contribution Contribution 00464 # \param gui GOSED 00465 # """ 00466 00467 # LDF.CALcontributionIterator.__init__(self, event, contribution) 00468 # self.__gui = gui 00469 00470 # # Determine which tower and range are currently selected 00471 # self.__selectedTower = \ 00472 # self.__gui.drawGOSEDTWR.selectTWR.id(self.__gui.drawGOSEDTWR.selectTWR.selected()) 00473 # self.__selectedRange = \ 00474 # self.__gui.drawGOSEDCALTKR.selectRNG.id(self.__gui.drawGOSEDCALTKR.selectRNG.selected()) 00475 00476 # # Initialize variables 00477 # self.__maxValue = 0 00478 # self.__minValue = 1000000 00479 00480 # self.__logCount = 0 00481 # self.__energyCount = 0 00482 00483 # self.__maxValue2 = 0 00484 # self.__minValue2 = 1000000 00485 00486 # self.__logCount2 = 0 00487 # self.__energyCount2 = 0 00488 00489 # self.__calPeds = gui.GOSEDPreferencesGUI.getCalPeds() 00490 00491 # def plot(self): 00492 # """ This def will call the iterate() function to return the min and max 00493 # value within the scale format selected by the user (Event, Custom or 00494 # Default) 00495 00496 # \return Values filtered in the iteration: minValue, maxValue, logCount, 00497 # energyCount 00498 # """ 00499 # # Determine the length of the event CAL data and return if it is 0 00500 # length = self.contribution().numLogAccepts() 00501 # if length == 0: 00502 # return 00503 00504 # # Obtain tower number from LDF. This tower will have CAL data since 00505 # # it passed the filter above 00506 # towerSource = LDF.LATPcellHeader.source(self.contribution().header()) 00507 00508 # # Enables TWRs with CAL data 00509 # twrButton = self.__gui.drawGOSEDTWR.selectTWR.find(towerSource) 00510 # twrButton.setEnabled(1) 00511 00512 00513 # # If the file was just opened select the first twr entry in the event to 00514 # # filter by it. 00515 # if self.__selectedTower == -1: 00516 # self.__selectedTower = towerSource 00517 # twrButton.setChecked(1) 00518 00519 # # Filter by twr ATK 12/05/03 We need to calculate limits for all the TWrs 00520 # # to plot values in GOTED 00521 # #~ if towerSource != self.__selectedTower: 00522 # #~ return 00523 00524 # # Iterate calls the log function for every event entry 00525 # self.iterate() 00526 00527 # # If no twr was selected, we set limits as Default (see if this is obsolete 00528 # # since now we always select the first twr when opening the file) 00529 # if self.__minValue == 1000000: 00530 # self.__minValue = 0 00531 00532 # if self.__maxValue == 0: 00533 # self.__maxValue = 1000 00534 00535 # # Change limits if user has changed scale format 00536 # if self.__gui.preferredLimits == "Default": 00537 # self.__minValue = 0 00538 # self.__maxValue = 1000 00539 00540 # elif self.__gui.preferredLimits == "Custom": 00541 # self.__minValue = self.__gui.GOSEDPreferencesGUI.minCAL() 00542 # self.__maxValue = self.__gui.GOSEDPreferencesGUI.maxCAL() 00543 00544 # # And for the CAL & TKR Window: 00545 # if self.__minValue2 == 1000000: 00546 # self.__minValue2 = 0 00547 00548 # if self.__maxValue2 == 0: 00549 # self.__maxValue2 = 1000 00550 00551 # # Change limits if user has changed scale format 00552 # if self.__gui.preferredLimits == "Default": 00553 # self.__minValue2 = 0 00554 # self.__maxValue2 = 1000 00555 00556 # elif self.__gui.preferredLimits == "Custom": 00557 # self.__minValue2 = self.__gui.GOSEDPreferencesGUI.minCAL() 00558 # self.__maxValue2 = self.__gui.GOSEDPreferencesGUI.maxCAL() 00559 00560 # # Return calculated values in the iteration 00561 # return {"minValue": self.__minValue, "maxValue": self.__maxValue, 00562 # "logCount": self.__logCount, "energyCount": self.__energyCount, 00563 # "minValue2": self.__minValue2, "maxValue2": self.__maxValue2, 00564 # "logCount2": self.__logCount2, "energyCount2": self.__energyCount2} 00565 00566 # def log(self, tower, layer, theLog): 00567 # """ This function enables the TWR and RNG display buttons for which there 00568 # is CAL data in the event. It also checks the TWR and RNG display button for 00569 # the first entry in the event data. Log returns if the value of the TWR or 00570 # RNG is not the same as the one selected (the first time it returns for all 00571 # entries that have twr and rng values other than the the first tower and 00572 # range entry in the event). If the entry passes the filter it obtains its 00573 # energy value (in ACD counts) and range,and contrasts them with the actual 00574 # min and max values to update them if necesary. 00575 00576 # \return tower, layer, theLog 00577 # """ 00578 # # Get range values, we are gonna make sure that posValue and negValue are 00579 # # the same for each entry 00580 # posValue = theLog.positive().value() 00581 # negValue = theLog.negative().value() 00582 00583 # posRange = theLog.positive().range() 00584 # negRange = theLog.negative().range() 00585 00586 # # Subtract pedestals if available 00587 # if self.__calPeds is not None: 00588 # posValue -= self.__calPeds[tower,layer,theLog.column(),0,posRange,0] 00589 # negValue -= self.__calPeds[tower,layer,theLog.column(),1,negRange,0] 00590 00591 # #Assuming positive and negative range are the same for an event log entry 00592 # RNGButton = self.__gui.drawGOSEDCAL.selectRNG.find(posRange) 00593 # RNGButton.setEnabled(1) 00594 00595 # RNGButton2 = self.__gui.drawGOSEDCALTKR.selectRNG.find(posRange) 00596 # RNGButton2.setEnabled(1) 00597 00598 # #~ print "Exists data in CAL 1 iterator log function before filters" 00599 00600 # # If the file was just opened select the first rng entry in the event to 00601 # # filter by it. 00602 # if self.__selectedRange == -1: 00603 # self.__selectedRange = posRange 00604 # RNGButton.setChecked(1) 00605 00606 # #~ if self.__selectedRange2 == -1: 00607 # #~ self.__selectedRange2 = posRange 00608 # #~ RNGButton2.setChecked(1) 00609 00610 # # Return if the entry does not have the selected rng value. 00611 # # If negRange is not the same as posRange the entry is discarded (check if 00612 # # this is a good idea) 00613 # if self.__selectedRange != -1 and self.__selectedRange != 4: 00614 # if posRange != self.__selectedRange or negRange != self.__selectedRange: 00615 # pass 00616 00617 # else: 00618 # # Once we have filtered to obtain the desired entries calculate the average 00619 # # energy in ACD counts and contrast it with the present min and max values. 00620 # averageEnergy = (posValue + negValue)/2 00621 00622 # # Update counts of log and energy entries 00623 # self.__logCount += 1 00624 # self.__energyCount += averageEnergy 00625 00626 # # Update min and max values for the filtered event with the new value 00627 # # if necessary. 00628 # if averageEnergy > self.__maxValue: 00629 # self.__maxValue = averageEnergy 00630 00631 # if averageEnergy < self.__minValue: 00632 # self.__minValue = averageEnergy 00633 00634 # # Return if the entry does not have the selected rng value. 00635 # # If negRange is not the same as posRange the entry is discarded (check if 00636 # # this is a good idea) 00637 # #~ if self.__selectedRange2 != -1 and self.__selectedRange2 != 4: 00638 # #~ if posRange != self.__selectedRange2 or negRange != self.__selectedRange2: 00639 # #~ return 00640 00641 # # Once we have filtered to obtain the desired entries calculate the average 00642 # # energy in ACD counts and contrast it with the present min and max values. 00643 # #~ averageEnergy2 = (posValue + negValue)/2 00644 00645 # #~ # Update counts of log and energy entries 00646 # #~ self.__logCount2 += 1 00647 # #~ self.__energyCount2 += averageEnergy2 00648 00649 # #~ # Update min and max values for the filtered event with the new value 00650 # #~ # if necessary. 00651 # #~ if averageEnergy2 > self.__maxValue2: 00652 # #~ self.__maxValue2 = averageEnergy2 00653 00654 # #~ if averageEnergy2 < self.__minValue2: 00655 # #~ self.__minValue2 = averageEnergy2 00656 # #~ print "Exists data in CAL 1 iterator log function after filters" 00657 00658 00659 class CALcontributionIterator2(LDF.CALcontributionIterator): 00660 """ \brief CAL contribution Displayer 00661 00662 This class obtains the filtered entries from CALcontributorIterator1 and 00663 converts them to the appropriate format to display them 00664 """ 00665 00666 def __init__(self, event, contribution, gui, limits, lci): 00667 """ CALcontributionIterator2 contructor 00668 00669 \param event Event 00670 \param contribution Contribution 00671 \param gui GOSED 00672 \param limits Tuple with filtered values (min value, max value, 00673 log count and energy count) obtained from 00674 CALcontributionIterator1 00675 """ 00676 00677 LDF.CALcontributionIterator.__init__(self, event, contribution) 00678 self.__event = event 00679 self.__contribution = contribution 00680 self.__gui = gui 00681 self.__limits = limits 00682 self.__tower = None 00683 self.__calPeds = gui.GOSEDPreferencesGUI.getCalPeds() 00684 00685 # Create a dictionary of colors for range readout 00686 self.__rangeColorMap = { 0 : QColor(255,0,0), 00687 1 : QColor(255,255,0), 00688 2 : QColor(0,170,0), 00689 3 : QColor(0,0,255) 00690 } 00691 00692 # Determine which tower and range are currently selected 00693 self.__scale = gui.drawGOSEDCAL.scaleSelection.currentItem() 00694 self.__scale2 = gui.drawGOSEDCALTKR.scaleSelection.currentItem() 00695 00696 self.__selectedTower = \ 00697 gui.drawGOSEDTWR.selectTWR.id(gui.drawGOSEDTWR.selectTWR.selected()) 00698 self.__selectedRange = [] 00699 self.__selectedRange2 = [] 00700 for i in range(0, 5): 00701 button = gui.drawGOSEDCAL.selectRNG.find(i) 00702 if button.isChecked(): 00703 self.__selectedRange.append(i) 00704 button2 = gui.drawGOSEDCALTKR.selectRNG.find(i) 00705 if button2.isChecked(): 00706 self.__selectedRange2.append(i) 00707 00708 if self.__selectedRange == []: 00709 checkAll = False 00710 for i in range(0, 4): 00711 button = gui.drawGOSEDCAL.selectRNG.find(i) 00712 if button.isEnabled(): 00713 checkAll = False 00714 if checkAll: 00715 self.__selectedRange.append(4) 00716 gui.drawGOSEDCAL.RNGAll.setChecked(1) 00717 gui.drawGOSEDCAL.RNGAll.setEnabled(1) 00718 if self.__selectedRange2 == []: 00719 checkAll = False 00720 for i in range(0, 4): 00721 button = gui.drawGOSEDCAL.selectRNG.find(i) 00722 if button.isEnabled(): 00723 checkAll = False 00724 if checkAll: 00725 self.__selectedRange2.append(4) 00726 gui.drawGOSEDCALTKR.RNGAll.setEnabled(1) 00727 gui.drawGOSEDCALTKR.RNGAll.setChecked(1) 00728 00729 00730 #~ print "ranges: ", self.__selectedRange, self.__selectedRange2 00731 #~ self.__selectedRange = \ 00732 #~ gui.drawGOSEDCAL.selectRNG.id(gui.drawGOSEDCALTKR.selectRNG.selected()) 00733 #~ self.__selectedRange2 = \ 00734 #~ gui.drawGOSEDCALTKR.selectRNG.id(gui.drawGOSEDCALTKR.selectRNG.selected()) 00735 00736 # Initialize GOTED TKR temporary Pixmaps 00737 self.__ebfZ_CAL = {} 00738 00739 # Initialize limits 00740 if limits is None: 00741 self.__minValue = 0 00742 self.__maxValue = 1000 00743 00744 self.__minValue2 = 0 00745 self.__maxValue2 = 1000 00746 00747 self.__logCount = 0 00748 self.__energyCount = 0 00749 00750 #~ self.__minValue2 = 0 00751 #~ self.__maxValue2 = 1000 00752 00753 #~ self.__logCount2 = 0 00754 #~ self.__energyCount2 = 0 00755 00756 # Change limits if user has changed scale format 00757 if gui.preferredLimits == "Custom": 00758 self.__minValue = gui.GOSEDPreferencesGUI.minCAL() 00759 self.__maxValue = gui.GOSEDPreferencesGUI.maxCAL() 00760 00761 if gui.preferredLimits2 == "Custom": 00762 self.__minValue2 = gui.GOSEDPreferencesGUI.minCAL2() 00763 self.__maxValue2 = gui.GOSEDPreferencesGUI.maxCAL2() 00764 00765 #~ self.__minValue2 = gui.GOSEDPreferencesGUI.minCAL() 00766 #~ self.__maxValue2 = gui.GOSEDPreferencesGUI.maxCAL() 00767 # return 00768 00769 else: 00770 # Do we ever get in here? -ATK 040705 00771 self.__minValue = limits["minValue"] 00772 self.__maxValue = limits["maxValue"] 00773 00774 self.__minValue2 = limits["minValue"] 00775 self.__maxValue2 = limits["maxValue"] 00776 00777 #~ self.__minValue2 = limits["minValue2"] 00778 #~ self.__maxValue2 = limits["maxValue2"] 00779 00780 # Create CAL color spectrum dividing the min to max interval in 6. 00781 # If Energy Scale has been selected as Default or Custom the corresponding 00782 # values will the input min and max values here. 00783 # interval = (self.__maxValue - self.__minValue)/6 00784 # self.__interval = interval 00785 00786 #~ for view in (gui.drawGOSEDCAL, gui.drawGOSEDCALTKR): 00787 # gui.drawGOSEDCALTKR.redLbl.setText(str(self.__minValue) + " - " + 00788 # str(self.__minValue + 1*interval)) 00789 # gui.drawGOSEDCALTKR.orangeLbl.setText(str(self.__minValue + 1*interval) + 00790 # " - " + 00791 # str(self.__minValue + 2*interval)) 00792 # gui.drawGOSEDCALTKR.yellowLbl.setText(str(self.__minValue + 2*interval) + 00793 # " - " + 00794 # str(self.__minValue + 3*interval)) 00795 # gui.drawGOSEDCALTKR.greenLbl.setText(str(self.__minValue + 3*interval) + 00796 # " - " + 00797 # str(self.__minValue + 4*interval)) 00798 # gui.drawGOSEDCALTKR.blueLbl.setText(str(self.__minValue + 4*interval) + 00799 # " - " + 00800 # str(self.__minValue + 5*interval)) 00801 # gui.drawGOSEDCALTKR.violetLbl.setText(str(self.__minValue + 5*interval) + 00802 # " - " + str(self.__maxValue)) 00803 00804 #~ self.__interval2 = (self.__maxValue2 - self.__minValue2)/6 00805 #~ gui.drawGOSEDCALTKR.redLbl.setText(str(self.__minValue2) + " - " + 00806 #~ str(self.__minValue2 + 1*self.__interval2)) 00807 #~ gui.drawGOSEDCALTKR.orangeLbl.setText(str(self.__minValue2 + 1*self.__interval2) + 00808 #~ " - " + 00809 #~ str(self.__minValue2 + 2*self.__interval2)) 00810 #~ gui.drawGOSEDCALTKR.yellowLbl.setText(str(self.__minValue2 + 2*self.__interval2) + 00811 #~ " - " + 00812 #~ str(self.__minValue2 + 3*self.__interval2)) 00813 #~ gui.drawGOSEDCALTKR.greenLbl.setText(str(self.__minValue2 + 3*self.__interval2) + 00814 #~ " - " + 00815 #~ str(self.__minValue2 + 4*self.__interval2)) 00816 #~ gui.drawGOSEDCALTKR.blueLbl.setText(str(self.__minValue2 + 4*self.__interval2) + 00817 #~ " - " + 00818 #~ str(self.__minValue2 + 5*self.__interval2)) 00819 #~ gui.drawGOSEDCALTKR.violetLbl.setText(str(self.__minValue2 + 5*self.__interval2) + 00820 #~ " - " + str(self.__maxValue2)) 00821 00822 00823 00824 def plot(self): 00825 """ Plot here will call the iterate() function to display the filtered 00826 event within the scale format selected by the user (Event, Custom or 00827 Default) 00828 00829 There are three sorts of pixmaps (and the 3 equivalent for the YZ projection): 00830 background = Background Pixmap with the skeleton of the CAL 00831 final = Final pixmap that is going to be loaded to the display. If no 00832 data passed the filter, the custom widget drawXZ_CAL will 00833 automatically load background to final for display 00834 ebfXZ_CAL = Temporary Pixmap that, if there is data that passed the filter 00835 for the current event, it gets painted with it over background. 00836 If so it is then passed to final (once the iteration is over). 00837 """ 00838 gui = self.__gui 00839 # Return if there is no CAL data in the event. 00840 length = self.__contribution.numLogAccepts() 00841 if length != 0: 00842 #~ return 00843 00844 # Obtain tower number from LDF. This tower will have CAL data since 00845 # it passed the filter above 00846 towerSource = LDF.LATPcellHeader.source(self.contribution().header()) 00847 00848 # Enables TWRs with CAL data - ATK-040705 00849 twrButton = self.__gui.drawGOSEDTWR.selectTWR.find(towerSource) 00850 twrButton.setEnabled(1) 00851 00852 # If the file was just opened select the first twr entry in the event to 00853 # filter by it. - ATK-040705 00854 if self.__selectedTower == -1: 00855 if gui.firstTower == None: 00856 gui.firstTower = towerSource 00857 self.__selectedTower = towerSource 00858 twrButton.setChecked(1) 00859 #~ gui.drawGOSEDCAL.RNGAll.setChecked(1) 00860 #~ gui.drawGOSEDCALTKR.RNGAll.setChecked(1) 00861 00862 # Initialize GOTED Frames, for all TWRs with CAL data 00863 #~ gui.drawGOTED.towerList[towerSource].setEnabled(1) 00864 00865 # Initialize GOTED CAL Pixmaps, for all TWRs with CAL data 00866 self.__ebfZ_CAL[towerSource] = QPixmap(gui.drawGOTED.TWR0.width(), 00867 gui.drawGOTED.TWR0.height()) 00868 00869 # If there is already a pixmap loaded from TKR, build from it 00870 if gui.drawGOTED.final[towerSource].isNull(): 00871 copyBlt(self.__ebfZ_CAL[towerSource], 0, 0, gui.drawGOTED.background) 00872 else: 00873 copyBlt(self.__ebfZ_CAL[towerSource], 0, 0, 00874 gui.drawGOTED.final[towerSource]) 00875 00876 # Iterate over event entries to paint filtered entries onto temporary pixmap 00877 self.iterate() 00878 00879 if length != 0: 00880 # ATK - 09 Jan 04: Implementation on hold, needs to consider 00881 # pairing of layers in trays to create proper top projection of the tower: 00882 # Here we presently just pass back white background pixmap instead of top 00883 # projection 00884 # 00885 # Pass GOTED Pixmaps 00886 bitBlt(gui.drawGOTED.towerList[towerSource], 0, 0, 00887 self.__ebfZ_CAL[towerSource], 0, 0) 00888 bitBlt(gui.drawGOTED.final[towerSource], 0, 0, 00889 self.__ebfZ_CAL[towerSource], 0, 0) 00890 #~ bitBlt(gui.towerList[towerSource], 0, 0, 00891 #~ self.__ebfZ_CAL[towerSource], 0, 0) 00892 00893 # Filter by selected tower: 00894 if towerSource != self.__selectedTower: 00895 return 00896 00897 # Frame in red the selected TWR 00898 Zpm = gui.clickTWR(self.__selectedTower) 00899 #~ if Zpm is not None: 00900 bitBlt(gui.drawGOTED.towerList[towerSource], 0, 0, Zpm , 0, 0) 00901 bitBlt(gui.drawGOTED.final[towerSource], 0, 0, Zpm , 0, 0) 00902 00903 # Request that the screen is updated, for those Widgets that need it 00904 if gui.drawXZ_CAL.isVisible(): 00905 gui.drawYZ_CAL.update() 00906 gui.drawXZ_CAL.update() 00907 if gui.drawXZ_CAL2.isVisible(): 00908 gui.drawYZ_CAL2.update() 00909 gui.drawXZ_CAL2.update() 00910 if gui.drawGOSEDData.isVisible(): 00911 gui.drawGOSEDData.update() 00912 00913 # Fill in total count of Log hits and total average Energy 00914 gui.drawGOSEDData.totLogHits.setText(str(self.__logCount)) 00915 gui.drawGOSEDData.totEnergy.setText(str(self.__energyCount)) 00916 00917 00918 def __drawLog(self, final, posArr, posColor, negArr, negColor): 00919 # If the scale is range readout and the range is different than the selected ranges 00920 # paint a black rim - ATK 040706 00921 pCAL = QPainter(final) 00922 00923 # Positive Range 00924 pCAL.setBrush(posColor) 00925 pCAL.setPen(posColor) 00926 if posColor == QColor("black"): 00927 pCAL.setBrush(Qt.NoBrush) 00928 pCAL.drawPolygon(posArr) 00929 00930 # Negative Range 00931 pCAL.setBrush(negColor) 00932 pCAL.setPen(negColor) 00933 if negColor == QColor("black"): 00934 pCAL.setBrush(Qt.NoBrush) 00935 pCAL.drawPolygon(negArr) 00936 00937 pCAL.end() 00938 00939 def log(self, tower, layer, theLog): 00940 """ This function iterates over all current event entries and displays 00941 all those entries that passed the filter of for CAL in 00942 CALContributorIterator1. 00943 00944 \return tower, layer, theLog 00945 """ 00946 # Initialize variables 00947 layerTag = ["X0", "Y0", "X1", "Y1", "X2", "Y2", "X3", "Y3"] 00948 gccc = [ 0, 3, 0, 3, 2, 1, 2, 1] 00949 gcrc = [ 0, 0, 1, 1, 2, 2, 3, 3] 00950 00951 # Initialize variables for the filtered entry 00952 gui = self.__gui 00953 scale = self.__scale 00954 scale2 = self.__scale2 00955 00956 # Initialize GOTED Pixmaps for TWRs with CAL data 00957 if gui.drawGOTED.final[tower].isNull(): 00958 gui.drawGOTED.final[tower] = QPixmap(gui.drawGOTED.TWR0.width(), 00959 gui.drawGOTED.TWR0.height()) 00960 00961 # ATK - 09 Jan 04: Implementation on hold, needs to consider 00962 # pairing of layers in trays to create proper top projection of the tower: 00963 # 00964 #~ # Paint XY GOTED projection for every tower with data 00965 #~ pCAL = QPainter(self.__ebfZ_CAL[tower]) 00966 #~ pCAL.setBrush(color) 00967 #~ pCAL.setPen(color) 00968 #print gui.TWR0.geometry().width(), gui.TWR0.height() 00969 #~ pCAL.drawRect(column*gui.drawGOTED.TWR0.width()/12, 00970 #~ column*gui.drawGOTED.TWR0.height()/12, 00971 #~ gui.drawGOTED.TWR0.width()/12, 00972 #~ gui.drawGOTED.TWR0.height()/12 00973 #~ ) 00974 00975 #~ pCAL.end() 00976 00977 # Filter by selected tower: 00978 if tower != self.__selectedTower: 00979 return 00980 00981 column = theLog.column() 00982 00983 positive = theLog.positive() 00984 negative = theLog.negative() 00985 00986 posRange = positive.range() 00987 posValue = positive.value() 00988 negRange = negative.range() 00989 negValue = negative.value() 00990 00991 # Subtract pedestals if available 00992 calPeds = self.__calPeds 00993 if calPeds is not None: 00994 posValue -= calPeds[tower,layer,theLog.column(),0,posRange,0] 00995 negValue -= calPeds[tower,layer,theLog.column(),1,negRange,0] 00996 00997 # Enable All Ranges Button 00998 rangeAll = gui.drawGOSEDCAL.RNGAll 00999 rangeAll.setEnabled(1) 01000 rangeAll2 = gui.drawGOSEDCALTKR.RNGAll 01001 rangeAll2.setEnabled(1) 01002 01003 #Assuming positive and negative range are the same for an event log entry 01004 RNGButton = gui.drawGOSEDCAL.selectRNG.find(posRange) 01005 RNGButton.setEnabled(1) 01006 if rangeAll.isChecked(): 01007 RNGButton.setChecked(1) 01008 self.__selectedRange.append(posRange) 01009 01010 RNGButton2 = gui.drawGOSEDCALTKR.selectRNG.find(posRange) 01011 RNGButton2.setEnabled(1) 01012 if rangeAll2.isChecked(): 01013 RNGButton2.setChecked(1) 01014 self.__selectedRange2.append(posRange) 01015 01016 # Update counts of log and energy entries 01017 value = (posValue + negValue)/2 01018 self.__logCount += 1 01019 self.__energyCount += value 01020 01021 # Ric is overriding the color here: 01022 import colorScale 01023 # Paint only selected range 01024 if posRange not in self.__selectedRange: 01025 scale = 1 01026 if negRange not in self.__selectedRange: 01027 scale = 1 01028 dv = float(self.__maxValue) - float(self.__minValue) 01029 if dv == 0.0: dv = 1.0e-308 01030 v = (float(posValue) - float(self.__minValue)) / dv 01031 r, g, b = colorScale.colorScale(v) 01032 posColor = QColor(r, g, b) 01033 v = (float(negValue) - float(self.__minValue)) / dv 01034 r, g, b = colorScale.colorScale(v) 01035 negColor = QColor(r, g, b) 01036 01037 if posRange not in self.__selectedRange2: 01038 scale2 = 1 01039 if negRange not in self.__selectedRange2: 01040 scale2 = 1 01041 # Added new color for CAL/TKR window independent of CAL window 01042 dv = float(self.__maxValue2) - float(self.__minValue2) 01043 if dv == 0.0: dv = 1.0e-308 01044 v = (float(posValue) - float(self.__minValue2)) / dv 01045 r, g, b = colorScale.colorScale(v) 01046 posColor2 = QColor(r, g, b) 01047 v = (float(negValue) - float(self.__minValue2)) / dv 01048 r, g, b = colorScale.colorScale(v) 01049 negColor2 = QColor(r, g, b) 01050 01051 # If we are scaling by range from 0 to 3, determine energy color for the 01052 # entry value within the range spectrum: 01053 if scale == 1: 01054 # Use correct colors for pos and neg range - ATK 040705 01055 posColor = self.__rangeColorMap[posRange] 01056 negColor = self.__rangeColorMap[negRange] 01057 # Paint a black rim if range not in selected set of ranges 01058 if posRange not in self.__selectedRange: 01059 posColor = QColor("black") 01060 if negRange not in self.__selectedRange: 01061 negColor = QColor("black") 01062 #~ if posRange == 0: 01063 #~ posColor = QColor(255,0,0) 01064 #~ elif posRange == 1: 01065 #~ posColor = QColor(255,255,0) 01066 #~ elif posRange == 2: 01067 #~ posColor = QColor(0,170,0) 01068 #~ elif posRange == 3: 01069 #~ posColor = QColor(0,0,255) 01070 01071 # negColor = color - ATK 040705 01072 # posColor = color - ATK 040705 01073 01074 # If we are scaling by range from 0 to 3, determine energy color for the 01075 # entry value within the range spectrum: 01076 if scale2 == 1: 01077 # Use correct colors for pos and neg range - ATK 040705 01078 posColor2 = self.__rangeColorMap[posRange] 01079 negColor2 = self.__rangeColorMap[negRange] 01080 # Paint a black rim if range not in selected set of ranges 01081 if posRange not in self.__selectedRange2: 01082 posColor2 = QColor("black") 01083 if negRange not in self.__selectedRange2: 01084 negColor2 = QColor("black") 01085 01086 # If there is data in the selected tower intialize final pixmaps in the draw class. 01087 logWidth = gui.drawXZ_CAL.final.width() / 12 01088 logHeight = gui.drawXZ_CAL.final.height() / 8 01089 01090 arrA = QPointArray() 01091 # Points: Make them one pixel less in height, on bottom 01092 arrA.setPoints([logWidth*column + 1, logHeight*layer + 1, # Top Left 01093 logWidth*(column+1) - 1, logHeight*layer + 1, # Top Right 01094 logWidth*column + 1, logHeight*(layer+1) - 2]) # Bottom Left 01095 arrB = QPointArray() 01096 arrB.setPoints([logWidth*(column+1) - 1, logHeight*(layer+1) - 2, # Bottom Right 01097 logWidth*(column+1) - 1, logHeight*layer + 1, # Top Right 01098 logWidth*column + 1, logHeight*(layer+1) - 2]) # Bottom Left 01099 01100 # Once the color has been determined, paint log with it 01101 # in the correct projection. 01102 if gui.drawXZ_CAL.isVisible(): 01103 if layer in range(1, 9, 2): 01104 self.__drawLog(gui.drawXZ_CAL.final, arrA, posColor, arrB, negColor) 01105 elif layer in range(0, 8, 2): 01106 self.__drawLog(gui.drawYZ_CAL.final, arrA, posColor, arrB, negColor) 01107 01108 if gui.drawXZ_CAL2.isVisible(): 01109 if layer in range(1, 9, 2): 01110 self.__drawLog(gui.drawXZ_CAL2.final, arrA, posColor2, arrB, negColor2) 01111 elif layer in range(0, 8, 2): 01112 self.__drawLog(gui.drawYZ_CAL2.final, arrA, posColor2, arrB, negColor2) 01113 01114 if 3 in self.__selectedRange and 4 not in self.__selectedRange: 01115 if gui.drawXZ_CAL.isVisible(): 01116 if layer in range(1, 9, 2): 01117 self.__drawLog(gui.drawXZ_CAL.final, arrA, QColor("black"), arrB, QColor("black")) 01118 elif layer in range(0, 8, 2): 01119 self.__drawLog(gui.drawYZ_CAL.final, arrA, QColor("black"), arrB, QColor("black")) 01120 01121 if 3 in self.__selectedRange2 and 4 not in self.__selectedRange2: 01122 if gui.drawXZ_CAL2.isVisible(): 01123 if layer in range(1, 9, 2): 01124 self.__drawLog(gui.drawXZ_CAL2.final, arrA, QColor("black"), arrB, QColor("black")) 01125 elif layer in range(0, 8, 2): 01126 self.__drawLog(gui.drawYZ_CAL2.final, arrA, QColor("black"), arrB, QColor("black")) 01127 01128 # Fill in CAL listview window with the entry data: 01129 if gui.drawGOSEDData.isVisible(): 01130 messageItem = QListViewItem( gui.drawGOSEDData.CALview ) 01131 #~ gui.drawGOSEDData.CALview.lastItem()) # ATK: This caused the slowdown 01132 messageItem.setText( 0, str(tower)) 01133 messageItem.setText( 1, str(layerTag[layer])) # RiC: Should be col 2 01134 messageItem.setText( 3, str(gccc[layer])) # RiC: Should be col 1 01135 messageItem.setText( 2, str(column)) 01136 if self.__calPeds is not None: 01137 messageItem.setText( 4, "%d" % posValue) 01138 messageItem.setText( 5, str(posRange)) 01139 messageItem.setText( 6, "%d" % negValue) 01140 messageItem.setText( 7, str(negRange)) 01141 else: 01142 messageItem.setText( 4, "0x%03x" % posValue) 01143 messageItem.setText( 5, str(posRange)) 01144 messageItem.setText( 6, "0x%03x" % negValue) 01145 messageItem.setText( 7, str(negRange)) 01146 messageItem.setText( 8, str(gcrc[layer])) 01147 messageItem.setText( 9, str(column)) 01148 01149 class TKRcontributionIterator_(LDF.TKRcontributionIterator): 01150 """ \brief TKR contribution Displayer 01151 01152 This class obtains the information of TKR from EBF to setup the tkr data in 01153 GOSED. To do so it filters by event and twr, iterating over all the entries 01154 in the event. 01155 """ 01156 01157 def __init__(self, event, contribution, gui): 01158 """ TKRcontributionIterator contructor 01159 01160 \param event Event 01161 \param contribution Contribution 01162 \param gui GOSED 01163 """ 01164 01165 # Initialize variables 01166 LDF.TKRcontributionIterator.__init__(self, event, contribution) 01167 self.__xy = ['Y', 'X', 'X', 'Y'] 01168 self.__gui = gui 01169 self.__gtcc = [6, 3, 7, 2, 5, 0, 4, 1] 01170 self.__event = event 01171 self.__tower = None 01172 01173 self.hitCount = 0 01174 self.layerCount = 0 01175 01176 # Retreive current selected tower: 01177 self.__selectedTower = gui.drawGOSEDTWR.selectTWR.id(gui.drawGOSEDTWR.selectTWR.selected()) 01178 01179 # Initialize GOTED TKR temporary Pixmaps 01180 self.__ebfZ_TKR = {} 01181 01182 01183 def plot(self): 01184 """ Plot here will call the iterateStrips() function to display the filtered 01185 event. 01186 01187 There are three sorts of pixmaps (and the 3 equivalent for the YZ projection): 01188 background = Background Pixmap with the skeleton of the TKR 01189 final = Final pixmap that is going to be loaded to the display. If no 01190 data passed the filter, the custom widget drawXZ_CAL will 01191 automatically load background to final for display 01192 """ 01193 01194 gui = self.__gui 01195 01196 # Return if there is no TKR data in the event. 01197 tkrContribution = self.contribution() 01198 length = tkrContribution.numAccepts(self.__event) 01199 if length != 0: 01200 # Obtain tower number from EBF 01201 towerSource = LDF.LATPcellHeader.source(self.contribution().header()) 01202 01203 # Initialize GOTED Frames, for all TWRs with TKR data 01204 #~ gui.drawGOTED.towerList[towerSource].setEnabled(1) 01205 01206 #~ print "tower Header", towerHeader 01207 01208 # Enable all towers that have data for the event 01209 twrButton = gui.drawGOSEDTWR.selectTWR.find(towerSource) 01210 twrButton.setEnabled(1) 01211 01212 # If we fix that tower can be passed directly to plot(), we can save having to 01213 # enter iteratestrips by adding the next 7 lines for all the towers that are not 01214 # the selected one. With the above line this is fixed. ATK 11/21/03 01215 if self.__selectedTower == -1: 01216 if gui.firstTower == None: 01217 gui.firstTower = towerSource 01218 self.__selectedTower = towerSource 01219 twrButton.setChecked(1) 01220 01221 # Initialize GOTED temporary pixmap, for all Towers with data. 01222 self.__ebfZ_TKR[towerSource] = QPixmap(gui.drawGOTED.towerList[towerSource].width(), 01223 gui.drawGOTED.towerList[towerSource].height()) 01224 01225 if gui.drawGOTED.final[towerSource].isNull(): 01226 copyBlt(self.__ebfZ_TKR[towerSource], 0, 0, gui.drawGOTED.background) 01227 else: 01228 copyBlt(self.__ebfZ_TKR[towerSource], 0, 0, gui.drawGOTED.final[towerSource]) 01229 01230 #~ # Pass GOTED Pixmaps 01231 #~ bitBlt(gui.drawGOTED.towerList[towerSource], 0, 0, self.__ebfZ_TKR[towerSource], 0, 0) 01232 #~ bitBlt(gui.drawGOTED.final[towerSource], 0, 0, self.__ebfZ_TKR[towerSource], 0, 0) 01233 01234 # Iterate over strip data. 01235 self.iterateStrips() 01236 01237 if length != 0: 01238 # ATK - 09 Jan 04: Implementation on hold, needs to consider 01239 # pairing of layers in trays to create proper top projection of the tower: 01240 # Here we presently just pass back white background pixmap instead of top 01241 # projection 01242 # 01243 # Pass GOTED Pixmaps 01244 bitBlt(gui.drawGOTED.towerList[towerSource], 0, 0, 01245 self.__ebfZ_TKR[towerSource], 0, 0) 01246 bitBlt(gui.drawGOTED.final[towerSource], 0, 0, 01247 self.__ebfZ_TKR[towerSource], 0, 0) 01248 #~ bitBlt(gui.towerList[towerSource], 0, 0, 01249 #~ self.__ebfZ_TKR[towerSource], 0, 0) 01250 01251 # Iterate over TOT data 01252 self.iterateTOTs() 01253 01254 if length != 0: 01255 # Filter by selected tower: 01256 if towerSource != self.__selectedTower: 01257 return 01258 01259 # Frame in red the selected TWR 01260 Zpm = gui.clickTWR(self.__selectedTower) 01261 #~ if Zpm is not None: 01262 bitBlt(gui.drawGOTED.towerList[towerSource], 0, 0, Zpm , 0, 0) 01263 bitBlt(gui.drawGOTED.final[towerSource], 0, 0, Zpm , 0, 0) 01264 01265 # Request that the screen is updated, for those Widgets that need it 01266 if gui.drawYZ_TKR.isVisible(): 01267 gui.drawYZ_TKR.update() 01268 gui.drawXZ_TKR.update() 01269 if gui.drawYZ_TKR2.isVisible(): 01270 gui.drawYZ_TKR2.update() 01271 gui.drawXZ_TKR2.update() 01272 01273 def strip(self, tower, layerEnd, hit): 01274 """ This function iterates over all current event entries and displays 01275 all those entries that passed the filter of for TWR. 01276 01277 \return tower, layerEnd, hit 01278 """ 01279 # Initialize variables 01280 gui = self.__gui 01281 layer = layerEnd >> 1 01282 rc = layer / 4 01283 cc = self.__gtcc[layer % 4] 01284 01285 (xTKR, yTKR, zTKR, stripNum) = (LDF.TKRstrip.gtfe(hit), 01286 LDF.TKRstrip.gtfe(hit), layer, hit) 01287 01288 # Initialize GOTED Pixmaps for TWRs with TKR data 01289 if gui.drawGOTED.final[tower].isNull(): 01290 gui.drawGOTED.final[tower] = QPixmap(gui.drawGOTED.TWR0.width(), 01291 gui.drawGOTED.TWR0.height()) 01292 01293 # We only have the mageneta color for TKR 01294 color = QColor("magenta") 01295 01296 # ATK - 09 Jan 04: Implementation on hold, needs to consider 01297 # pairing of layers in trays to create proper top projection of the tower: 01298 # 01299 # Paint XY GOTED projection for every tower with data 01300 #~ self.pTKR = QPainter(self.__ebfZ_TKR[tower]) 01301 #~ self.pTKR.setBrush(color) 01302 #~ self.pTKR.setPen(color) 01303 #~ self.pTKR.drawLine(stripNum*gui.drawGOTED.TWR0.width()/1536, 01304 #~ stripNum*gui.drawGOTED.TWR0.height()/1536 - 2, 01305 #~ stripNum*gui.drawGOTED.TWR0.width()/1536, 01306 #~ stripNum*gui.drawGOTED.TWR0.height()/1536 + 2 01307 #~ ) 01308 #~ self.pTKR.drawLine(stripNum*gui.drawGOTED.TWR0.width()/1536 - 2, 01309 #~ stripNum*gui.drawGOTED.TWR0.height()/1536 + 1, 01310 #~ stripNum*gui.drawGOTED.TWR0.width()/1536 + 2, 01311 #~ stripNum*gui.drawGOTED.TWR0.height()/1536 + 1 01312 #~ ) 01313 #~ self.pTKR.end() 01314 01315 # Filter by selected tower: 01316 if tower != self.__selectedTower: 01317 return 01318 01319 x = stripNum*gui.drawXZ_TKR.final.width()/NUMBER_STRIPS 01320 y = (35-zTKR)*7 01321 01322 # Paint ebf pixmap with filtered data of the current event 01323 if self.__xy[layer & 0x3] == "X": 01324 pTKR = QPainter(gui.drawXZ_TKR.final) 01325 pTKR.setBrush(color) 01326 pTKR.setPen(color) 01327 if y in RANGE1_TKR_X: 01328 pTKR.drawLine(x, y + 1, x, y + 1 + 6) 01329 pTKR.drawLine(x - 2, y + 4, x + 2, y + 4) 01330 #pTKR.drawRect(stripNum*STRIP_RANGE*4/NUMBER_STRIPS + 1, 01331 # y + 1, 4 , 6) 01332 else: 01333 pTKR.drawLine(x, y, x, y + 6 + 1) 01334 pTKR.drawLine(x - 2, y + 4, x + 2, y + 4) 01335 #pTKR.drawRect(x, y + 2, 1 , 6) 01336 #pTKR.drawRect(stripNum*STRIP_RANGE*4/NUMBER_STRIPS + 1, 01337 # y + 2, 4 , 6) 01338 bitBlt(gui.drawXZ_TKR2.final, 0, 0, gui.drawXZ_TKR.final, 0, 0) 01339 01340 elif self.__xy[layer & 0x3] == "Y": 01341 pTKR = QPainter(gui.drawYZ_TKR.final) 01342 pTKR.setBrush(color) 01343 pTKR.setPen(color) 01344 if y in RANGE1_TKR_Y: 01345 pTKR.drawLine(x, y + 2, x, y + 2 + 6) 01346 pTKR.drawLine(x - 2, y + 4, x + 2, y + 4) 01347 #pTKR.drawRect(x, y + 2, 1, 6) 01348 #pTKR.drawRect(stripNum*STRIP_RANGE*4/NUMBER_STRIPS + 1, 01349 # y + 1, 4 , 6) 01350 01351 else: 01352 pTKR.drawLine(x, y + 1, x, y + 1 + 6) 01353 pTKR.drawLine(x - 2, y + 4, x + 2, y + 4) 01354 #pTKR.drawRect(x, y + 1, 1 , 6) 01355 #pTKR.drawRect(stripNum*STRIP_RANGE*4/NUMBER_STRIPS + 1, 01356 # y + 2, 4 , 6) 01357 01358 bitBlt(gui.drawYZ_TKR2.final, 0, 0, gui.drawYZ_TKR.final, 0, 0) 01359 01360 pTKR.end() 01361 01362 # Add one to the number of hits count 01363 self.hitCount += 1 01364 01365 # Load entry in the TKR list view 01366 if gui.drawGOSEDData.isVisible(): 01367 towerValue = str(tower) 01368 xyValue = str(LAYER[layer]) 01369 layerValue = str(layer) 01370 tccValue = str(cc) + ',' + str(cc + 1) 01371 trcValue = str(rc) 01372 tfeValue = str(LDF.TKRstrip.gtfe(hit)) 01373 chanValue = str(hit) 01374 hitValue = "0x%04x" % hit 01375 01376 messageItem = QListViewItem( gui.drawGOSEDData.TKRview ) 01377 #, gui.drawGOSEDData.TKRview.lastItem()) # ATK: This caused the slowdown 01378 # If we wanted a check list here is how to do it: 01379 #messageItem = QCheckListItem( gui.drawGOSEDData.TKRview,"", QCheckListItem.CheckBox) 01380 01381 messageItem.setText( 0, towerValue) 01382 messageItem.setText( 1, xyValue) 01383 messageItem.setText( 2, layerValue) 01384 messageItem.setText( 3, tccValue ) 01385 messageItem.setText( 4, trcValue) 01386 messageItem.setText( 5, tfeValue) 01387 messageItem.setText( 6, chanValue) 01388 messageItem.setText( 7, hitValue) 01389 01390 gui.drawGOSEDData.totHits.setText(str(self.hitCount)) 01391 01392 # Not implemented 01393 def TOT(self, tower, layerEnd, tot): 01394 pass 01395 01396 class OSWcontributionIterator_(LDF.OSWcontributionIterator): 01397 def __init__(self, event, contribution): 01398 LDF.OSWcontributionIterator.__init__(self, event, contribution) 01399 self.__timestamp = None 01400 self.__timebase = None 01401 self.__evtSequence = None 01402 01403 def timestamp(self): 01404 return self.__timestamp 01405 01406 def evtSequence(self): 01407 return self.__evtSequence 01408 01409 def OSW_time(self, event, contribution): 01410 # Note that the next line COPIES the contribution in order to cast (YUCK)! 01411 tc = LDF.OSWtimeContribution(contribution) 01412 01413 eventNumber = LDF.EventSummary.eventNumber(contribution.summary()) 01414 eventTag = LDF.EventSummary.tag(contribution.summary()) 01415 01416 ts = LDF.OSWtimeSpec(tc.timeStamp()) 01417 01418 self.__timestamp = (ts.sec(), ts.nsec()) 01419 self.__evtSequence = tc.evtSequence() 01420 01421 return 0 01422 01423 01424 class DIAGcontributionIterator_(LDF.DIAGcontributionIterator): 01425 __CALlayerLabel = ["x0", "x1", "x2", "x3", "y0", "y1", "y2", "y3"] 01426 __gccc = [0, 2, 3, 1] 01427 01428 def __init__(self,event,contribution,dataStart, gui): 01429 LDF.DIAGcontributionIterator.__init__(self,event,contribution) 01430 self.offset(dataStart) # Set the start of the diagnostic data 01431 self.__gui = gui 01432 self.__diagCALView = self.__gui.drawGOSEDData.diagCAL 01433 self.__diagTKRView = self.__gui.drawGOSEDData.diagTKR 01434 01435 def CALdiag(self, tower, layer, diag): 01436 gccc = self.__gccc[layer>>1] 01437 layer = self.__CALlayerLabel[layer] 01438 negLogAccepts = diag.logAccepts (1) # negative 01439 negHigh = diag.high (1) # negative 01440 negLow = diag.low (1) # negative 01441 posLogAccepts = diag.logAccepts (0) # positive 01442 posHigh = diag.high (0) # positive 01443 posLow = diag.low (0) # positive 01444 01445 if self.__gui.drawGOSEDData.isVisible(): 01446 item = QListViewItem(self.__diagCALView) 01447 item.setText(0, str(gccc)) 01448 item.setText(1, str(layer)) 01449 item.setText(2, "0x%03x" % negLogAccepts) 01450 item.setText(3, str(negHigh)) 01451 item.setText(4, str(negLow)) 01452 item.setText(5, "0x%03x" % posLogAccepts) 01453 item.setText(6, str(posHigh)) 01454 item.setText(7, str(posLow)) 01455 01456 #~ diagCALView.insertItem(item) 01457 return 0 01458 01459 def TKRdiag(self, tower, gtcc, diag): 01460 gtrc = (diag.datum() & 0xffff) 01461 01462 if self.__gui.drawGOSEDData.isVisible(): 01463 item = QListViewItem(self.__diagTKRView) 01464 item.setText(0, str(gtcc)) 01465 item.setText(1, "0x%03x" % gtrc) 01466 01467 #print " %1d 0x%03x" % (gtcc, (diag.datum() & 0xffff)) 01468 return 0 01469 01470 01471 class ERRcontributionIterator_(LDF.ERRcontributionIterator): 01472 __gccc = [0, 2, 3, 1] 01473 __gtcc = [3, 6, 2, 7, 0, 5, 1, 4] 01474 __pn = ["+", "-"] 01475 __xy = ["X", "Y"] 01476 __layer = [0, 2, 2, 0] 01477 01478 def __init__(self,event,contribution,dataStart, gui): 01479 LDF.ERRcontributionIterator.__init__(self,event,contribution) 01480 self.offset(dataStart) # Set the start of the error data 01481 self.__gui = gui 01482 01483 self.__errorWindow = self.__gui.drawGOSEDData.error 01484 01485 def gcccError(self, tower, gccc, err): 01486 #if not self.__errorWindow.isVisible(): return 0 01487 if err.type() == 0: 01488 01489 self.__errorWindow.append(" GCCC %d had missing start bit(s) on sweep %d (raw: 0x%04x):" % \ 01490 (gccc, err.sweep(), err.raw())) 01491 else: 01492 self.__errorWindow.append(" GCCC %d had parity error(s) on sweep %d (raw: 0x%04x):" % \ 01493 (gccc, err.sweep(), err.raw())) 01494 for i in range(8): 01495 if err.param() & (1 << i): 01496 self.__errorWindow.append(" %s%s%d, wire %d" % \ 01497 (self.__pn[i > 3], 01498 self.__xy[gccc & 1], 01499 self.__layer[gccc] + ((i >> 1) & 1), 01500 i & 1)) 01501 self.__errorWindow.append(" ") 01502 return 0 01503 01504 def gtccError(self, tower, gtcc, err): 01505 #if not self.__errorWindow.isVisible(): return 0 01506 self.__errorWindow.append("GTCC %d, GTRC %d (msg: 0x%04x):" % \ 01507 (gtcc, err.GTRC(), err.raw())) 01508 return 0 01509 01510 def phaseError(self, tower, err): 01511 #if not self.__errorWindow.isVisible(): return 0 01512 self.__errorWindow.append(" ") 01513 self.__errorWindow.append("Cable Controller phasing error tags (raw: 0x%04x):" % \ 01514 (err)) 01515 01516 tag = [0, 0, 0, 0, 0, 0, 0, 0] 01517 msg = "" 01518 for c in range(8): tag[self.__gtcc[c]] = (err >> (c << 1)) & 0x0003 01519 self.__errorWindow.append(" GTCC: 0 1 2 3 4 5 6 7") 01520 for c in range(8): msg += " %d" % (tag[c]) 01521 self.__errorWindow.append(" tag:%s" % (msg)) 01522 self.__errorWindow.append(" ") 01523 return 0 01524 01525 def timeoutError(self, tower, err): 01526 #if not self.__errorWindow.isVisible(): return 0 01527 self.__errorWindow.append(" ") 01528 self.__errorWindow.append("Cable Controller timeouts (raw: 0x%03x):" % (err)) 01529 cTmos = err & 0x000f 01530 msg = " GCCC:" 01531 for i in range(4): 01532 if cTmos & (1 << i): msg += " %d" % (self.__gccc[i]) 01533 tTmos = (err >> 4) & 0x00ff 01534 msg += ", GTCC:" 01535 for i in range(8): 01536 if tTmos & (1 << i): msg += " %d" % (self.__gtcc[i]) 01537 self.__errorWindow.append(" %s" % (msg)) 01538 self.__errorWindow.append(" ") 01539 return 0 01540 01541 def gtrcPhaseError(self, tower, gtcc, gtrc, err): 01542 #if not self.__errorWindow.isVisible(): return 0 01543 self.__errorWindow.append(" GTRC phasing error (raw: 0x%04x)" % \ 01544 (err.raw())) 01545 self.__errorWindow.append(" Current tag number: %d" % \ 01546 (err.currentTag())) 01547 self.__errorWindow.append(" Layer 0 tag number: %d" % \ 01548 (err.layer0Tag())) 01549 self.__errorWindow.append(" Expected layer number: %d" % \ 01550 (err.expectedLayer())) 01551 self.__errorWindow.append(" Layer number received by TEM: %d" % \ 01552 (err.receivedLayer())) 01553 self.__errorWindow.append(" ") 01554 return 0 01555 01556 def __tag(self, tag, err): 01557 for i in range(5): 01558 tag.append(err & 0x3) 01559 err >>= 2 01560 01561 return tag 01562 01563 def gtfePhaseError(self, tower, gtcc, gtrc, err1, err2, err3, err4, err5): 01564 #if not self.__errorWindow.isVisible(): return 0 01565 tags = " 0x%03x 0x%03x 0x%03x 0x%03x 0x%03x" % (err1, err2, err3, err4, err5) 01566 self.__errorWindow.append(" GTFE phasing error tags (raw: %s)" % (tags)) 01567 tag = [] 01568 self.__tag(tag, err1) 01569 self.__tag(tag, err2) 01570 self.__tag(tag, err3) 01571 self.__tag(tag, err4) 01572 self.__tag(tag, err5 >> 2) 01573 self.__errorWindow.append(" GTFE 0 1 2 3 4 5 6 7 8 9 10 11") 01574 str = " 0-11 " 01575 for i in range(12): 01576 str += "%2d " % tag[i] 01577 self.__errorWindow.append( str ) 01578 str = " 12-23 " 01579 for i in range(12, 24): 01580 str += "%2d " % tag[i] 01581 self.__errorWindow.append( str ) 01582 self.__errorWindow.append(" ") 01583 return 0 01584 01585 def gtccFIFOerror(self, tower, gtcc, err): 01586 #if not self.__errorWindow.isVisible(): return 0 01587 self.__errorWindow.append(" FIFO full error, projected word count = 0x%04x" % \ 01588 (err)) 01589 return 0 01590 01591 def gtccTMOerror(self, tower, gtcc): 01592 #if not self.__errorWindow.isVisible(): return 0 01593 self.__errorWindow.append(" Cable timeout error") 01594 return 0 01595 01596 def gtccHDRParityError(self, tower, gtcc): 01597 #if not self.__errorWindow.isVisible(): return 0 01598 self.__errorWindow.append(" Header parity error") 01599 return 0 01600 01601 def gtccWCParityError(self, tower, gtcc): 01602 #if not self.__errorWindow.isVisible(): return 0 01603 self.__errorWindow.append(" Word count parity error") 01604 return 0 01605 01606 def gtrcSummaryError(self, tower, gtcc): 01607 #if not self.__errorWindow.isVisible(): return 0 01608 self.__errorWindow.append(" GTRC summary error") 01609 return 0 01610 01611 def gtccDataParityError(self, tower, gtcc): 01612 #if not self.__errorWindow.isVisible(): return 0 01613 self.__errorWindow.append(" Data parity error") 01614 return 0 01615 01616 class myLATcomponentIterator(LDF.LATcomponentIterator): 01617 """ \brief LAT component Displayer 01618 01619 This class obtains the information of all the LAT components from EBF and 01620 passes it to the corresponding component iterators, to be displayed in GOSED. 01621 """ 01622 def __init__(self, gui): 01623 """ myLATcomponentIterator contructor 01624 01625 \param gui GOSED 01626 """ 01627 01628 # Initialize variables 01629 LDF.LATcomponentIterator.__init__(self) 01630 self.__calSrc = None 01631 self.__tkrContribution = None 01632 self.__gui = gui 01633 self.__diagnosticData = 0 01634 01635 def UDFcomponent(self, event, ebfContribution): 01636 return 0 01637 01638 def __displayEvtStats(self, eventSequence, eventTag, trgParityErr, timestamp): 01639 draw = self.__gui.drawGOSEDData 01640 draw.eventNumber.setText(str(eventSequence)) 01641 draw.eventTag.setText(str(eventTag)) 01642 evtTime = time.ctime(timestamp[0]) 01643 draw.timeStamp.setText("%s + %09d nS" % (evtTime, timestamp[1])) 01644 if trgParityErr: 01645 draw.flagLine.setPaletteForegroundColor( QColor("red")) 01646 draw.flagLine.setText("Event has TrgParityErr") 01647 01648 def GLTcomponent(self, event, contribution): 01649 """ Obtain the "fingerprints" of the event 01650 """ 01651 buffer = Numeric.fromstring(contribution.data(), 'i') 01652 eventNumber = LDF.EventSummary.eventNumber(contribution.summary()) 01653 eventTag = LDF.EventSummary.tag(contribution.summary()) 01654 eventSequence = (eventNumber << 2) | eventTag 01655 trgParityErr = LDF.EventSummary.trgParityError(contribution.summary()) 01656 01657 #timestamp = time.asctime(time.gmtime(buffer[0])) #+ str(buffer[1]) + " mS" 01658 01659 self.__displayEvtStats(eventSequence, eventTag, trgParityErr, buffer) 01660 return 0 01661 01662 def OSWcomponent(self, event, contribution): 01663 """ Obtain the 'fingerprints' of the event 01664 """ 01665 oswContribIter = OSWcontributionIterator_(event, contribution) 01666 oswContribIter.iterate() 01667 01668 # RiC - Kludge this for now by printing instead of displaying in the GUI 01669 #eventNumber = LDF.EventSummary.eventNumber(contribution.summary()) 01670 eventTag = LDF.EventSummary.tag(contribution.summary()) 01671 eventSequence = oswContribIter.evtSequence() 01672 trgParityErr = LDF.EventSummary.trgParityError(contribution.summary()) 01673 if trgParityErr: 01674 print "Event %d = %08x has a Trigger Parity Error" % (eventSequence, 01675 eventSequence) 01676 01677 self.__displayEvtStats(eventSequence, eventTag, trgParityErr, 01678 oswContribIter.timestamp()) 01679 return 0 01680 01681 def GEMcomponent(self, event, gemContribution): 01682 """ Obtain the ACD information of the event 01683 """ 01684 # RiC - Kludge this for now by printing instead of displaying in the GUI 01685 if LDF.EventSummary.trgParityError(gemContribution.summary()): 01686 print "GEM contribution has a Trigger Parity Error" 01687 01688 gemContrib = GEMcontribution_(event, gemContribution, self.__gui) 01689 gemContrib.plot() 01690 return 0 01691 01692 def ACDcomponent(self, event, aemContribution): 01693 """ Obtain the ACD information of the event 01694 """ 01695 # RiC - Kludge this for now by printing instead of displaying in the GUI 01696 if LDF.EventSummary.trgParityError(aemContribution.summary()): 01697 print "ACD contribution has a Trigger Parity Error" 01698 01699 acdContrib = AEMcontributionIterator_(event, aemContribution, self.__gui, self) 01700 acdContrib.plot() 01701 return 0 01702 01703 def TKRcomponent(self, event, tkrContribution): 01704 """ Obtain the TKR information of the event to be processed by 01705 TKRcontributionIterator. 01706 """ 01707 # RiC - Kludge this for now by printing instead of displaying in the GUI 01708 source = LDF.LATPcellHeader.source(tkrContribution.header()) 01709 if LDF.EventSummary.trgParityError(tkrContribution.summary()): 01710 print "TEM %d contribution (TKR) has a Trigger Parity Error" % (source) 01711 01712 tkrIterator = TKRcontributionIterator_(event, tkrContribution, self.__gui) 01713 tkrIterator.plot() 01714 01715 if tkrIterator.diagnostic() is not None: 01716 self.TKRend(tkrIterator.diagnostic()) 01717 01718 return 0 01719 01720 01721 def CALcomponent(self, event, calContribution): 01722 """ Obtain the CAL information of the event to be processed by 01723 CALcontributionIterator1 and CALcontributionIterator2. 01724 """ 01725 # RiC - Kludge this for now by printing instead of displaying in the GUI 01726 source = LDF.LATPcellHeader.source(calContribution.header()) 01727 if LDF.EventSummary.trgParityError(calContribution.summary()): 01728 print "TEM %d contribution (CAL) has a Trigger Parity Error" % (source) 01729 01730 # calContrib1 = CALcontributionIterator1(event, calContribution, self.__gui, self) 01731 01732 # limits = calContrib1.plot() 01733 #~ if limits is None: 01734 #~ return 01735 01736 limits = None 01737 calContrib2 = CALcontributionIterator2(event, calContribution, self.__gui, limits, self) 01738 calContrib2.plot() 01739 01740 self.CALend(calContrib2.CALend()) 01741 01742 return 0 01743 01744 01745 def diagnostic(self, event, contribution): 01746 """ Obtain the diagnostic information of the event. 01747 """ 01748 # Print the right message in the edit box for error and diagnostic 01749 self.__gui.drawGOSEDData.flagLine.setPaletteForegroundColor( QColor("black")) 01750 self.__gui.drawGOSEDData.flagLine.setText("Event has diagnostic data") 01751 01752 iter = DIAGcontributionIterator_(event,contribution,self.TKRend(),self.__gui) 01753 01754 #~ self.__gui.drawGOSEDData.diagCAL.setText(CALdata) 01755 iter.iterateCAL() 01756 iter.iterateTKR() 01757 01758 #12 longwords in diagnostic 01759 self.diagnosticEnd(self.TKRend() + iter.size()) 01760 return 0 01761 01762 01763 def error(self, event, contribution): 01764 """ Obtain the error information of the event. 01765 """ 01766 gui = self.__gui 01767 01768 # Instead print the right message in the edit box for error and diagnostic 01769 gui.drawGOSEDData.flagLine.setPaletteForegroundColor( QColor("red")) 01770 if LDF.EventSummary.diagnostic(contribution.summary()): 01771 gui.drawGOSEDData.flagLine.setText("Event has diagnostic and error data") 01772 else: 01773 gui.drawGOSEDData.flagLine.setText("Event has error data") 01774 errorWindow = gui.drawGOSEDData.error 01775 01776 # Dump error information for both CAL and TKR 01777 if not LDF.EventSummary.error(contribution.summary()): 01778 return 01779 01780 if self.diagnosticEnd() != 0: 01781 offset=self.diagnosticEnd() 01782 else: 01783 offset=self.TKRend() 01784 iter = ERRcontributionIterator_(event, contribution, offset, gui) 01785 theError = iter.theError() 01786 01787 #if errorWindow.isVisible(): 01788 source = LDF.LATPcellHeader.source(contribution.header()) 01789 errorWindow.append("Tower %d:" % source) 01790 errorWindow.append(" Cable Cable ") 01791 errorWindow.append("timeout phasing TKR CAL") 01792 errorWindow.append(" %1d %1d 0x%02x 0x%01x" % \ 01793 (theError.tmo(), 01794 theError.phs(), 01795 theError.tkr(), 01796 theError.cal())) 01797 errorWindow.append(" ") 01798 01799 iter.iterate() 01800 01801 errorWindow.append(" ") 01802 01803 self.errorEnd(offset + iter.size()) 01804 return 0 01805 01806 #~ def cleanup(self, event, contribution): 01807 #~ prefix = " " 01808 #~ src = LATPcellHeader.source(contribution.header()) 01809 #~ len = (self.errorEnd() + 15) & 0xfffffff0L # Integer # of LATp cells 01810 01811 #~ # Check for extra data after the last LATp cell we expected 01812 #~ if (contribution.length() - len > 0): 01813 #~ print "%sFound %d bytes after end of TEM %d contribution" % \ 01814 #~ (prefix, contribution.length() - len, src) 01815 01816 #~ # Check for non-zero data indicating we got lost during parsing 01817 #~ # LATp cell padding is expected to always be zeros 01818 #~ buffer = Numeric.fromstring(contribution.payload(), 'u') 01819 01820 #~ mbz = buffer[(self.errorEnd())/4-2:] 01821 01822 #~ for word in mbz: 01823 #~ if word != 0: 01824 #~ print "%sNon-zero bytes beyond end of TEM %d contribution: 0x%08x" % \ 01825 #~ (prefix, src, word) 01826 #~ return 0