ATLAS Offline Software
Loading...
Searching...
No Matches
PixelPostProcessing.py
Go to the documentation of this file.
2# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3#
4
5import ROOT
6import math
7import importlib.resources
8from PixelMonitoring.PixelAthMonitoringBase import LabelX, LabelY, baselayers, xbinsl
9
10
13
14# Final output histogram (LB vs estimated b-tag degradation)
15LB_deg = ROOT.TH1F('TotalDegradationPerLumiAA', 'b-tag degradation;LB;total b-tag degradation', 3000, -0.5, 2999.5)
16
17# Degradation factors
18# [IBL+BL+L1+L2, IBL+BL+L1, IBL+BL+L2, IBL+L1+L2, BL+L1+L2, IBL+BL, IBL+L1, IBL+L2, BL+L1, BL+L2, L1+L2, IBL-only, BL-only, L1-only, L2-only]
19# FIXME: New factors based on GN2 study
20#degFactor70 = [0.0032, 0.0078, 0.011, 0.020, 0.023, 0.018, 0.098, 0.10, 0.26, 0.36, 0.33, 0.17, 0.65, 0.79, 0.81]
21degFactor70 = [0.0007, 0.003, 0.005, 0.011, 0.0114, 0.012, 0.0695, 0.084, 0.165, 0.225, 0.236, 0.179, 0.590, 0.744, 0.755]
22degfactor_IBL = [1, 1, 1, 1, 0.99937, 0.99931, 0.99924, 0.99915, 0.99797, 0.99768, 0.99728, 0.99675, 0.99422, 0.99253, 0.99140, 0.99895, 0.99895, 0.99140, 0.99253, 0.99422, 0.99675, 0.99728, 0.99768, 0.99797, 0.99915, 0.99924, 0.99931, 0.99937, 1, 1, 1, 1]
23
25 layer = inputs[0][0]['sec']
26 nEventLB = inputs[0][1][1]
27 nAllEvents = nEventLB.Integral(1, nEventLB.GetNbinsX()+1)
28
29 histoName = inputs[0][1][0].GetName()
30 histo = inputs[0][1][0].Clone()
31 errorName = histoName.split('_')[0]
32 histo.SetName(errorName + '_Norm_' + layer)
33 histoTitle = histo.GetTitle().split(",")[0]
34 if nAllEvents != 0:
35 histo.Scale(1.0/nAllEvents)
36 histo.SetTitle(histoTitle + " per event, " + layer)
37 return [histo]
38
39#FIXME: Update this function
41 Th = 0.5 # Threshold of the FE status for "bad" FE. Do not change.
42 LB = inputs[0][0]['LB']
43 rv = [] # Vector of histograms showing bad FEs in eta-phi for all layer
44 rv1 = [] # Vector of histograms showing bad FEs in eta-phi for all mask pattern
45 rv_IBL = ROOT.TH2F()
46 rv_BLayer = ROOT.TH2F()
47 rv_Layer1 = ROOT.TH2F()
48 rv_Layer2 = ROOT.TH2F()
49 totalDeg = 0.0
50 degfactor_IBLtotal=0
51 for i in range(len(inputs[0][1])): # inputs[0][1] is treated as a vector here, but in fact the size is 1.
52 plots = [_[1][i] for _ in inputs] # all plots passed as first element of list
53 for m, plot in enumerate(plots): # m: LB number, plot: FE status map for each layer
54
55 # Vector showing the eta and phi range of all FEs in this layer
56 etaMin = []
57 etaMax = []
58 phiMin = []
59 phiMax = []
60 sec = inputs[m][0]['sec'] # layer name
61 # rv.append(ROOT.TH2F('defectPlot', 'badFERegion', 500, -3.0, 3.0, 500, -math.pi, math.pi))
62 # modified for -2.5 < eta < 2.5
63 rv.append(ROOT.TH2F('defectPlot', 'badFERegion', 500, -2.5, 2.5, 500, -math.pi, math.pi))
64 rv[m].SetTitle('badFE_EtaPhi_' + sec)
65 rv[m].GetXaxis().SetTitle('#eta')
66 rv[m].GetYaxis().SetTitle('#phi')
67
68
71 with importlib.resources.open_text('PixelMonitoring', 'FE_EtaEdge_' + sec + '.txt') as etaInfo:
72 for line in etaInfo.readlines():
73 toks = line.split()
74 etaMin.append(float(toks[3]))
75 etaMax.append(float(toks[4]))
76 with importlib.resources.open_text('PixelMonitoring', 'FE_PhiEdge_' + sec + '.txt') as phiInfo:
77 for line in phiInfo.readlines():
78 toks = line.split()
79 if float(toks[3]) < -math.pi:
80 phiMin.append(float(toks[3]) + 2*math.pi)
81 else:
82 phiMin.append(float(toks[3]))
83 if float(toks[4]) > math.pi:
84 phiMax.append(float(toks[4]) - 2*math.pi)
85 else:
86 phiMax.append(float(toks[4]))
87
88
92 for xbin in range(plot.GetNbinsX()):
93 for ybin in range(plot.GetNbinsY()):
94 if(plot.GetBinContent(xbin+1, ybin+1) < Th): # This FE status is "good"! Skip.
95 continue
96 if sec=='IBL':
97 degfactor_IBLtotal=degfactor_IBLtotal+(1-degfactor_IBL[xbin])
98 # Find eta and phi range of this bad FE
99 # etaMin_bin = rv[m].GetXaxis().FindBin(etaMin[xbin] + 3.0/500)
100 # etaMax_bin = rv[m].GetXaxis().FindBin(etaMax[xbin] + 3.0/500)
101 # modified for -2.5 < eta < 2.5
102 etaMin_bin = rv[m].GetXaxis().FindBin(etaMin[xbin] + 2.5/500)
103 etaMax_bin = rv[m].GetXaxis().FindBin(etaMax[xbin] + 2.5/500)
104 phiMin_bin = rv[m].GetYaxis().FindBin(phiMin[ybin] + math.pi/500)
105 phiMax_bin = rv[m].GetYaxis().FindBin(phiMax[ybin] + math.pi/500)
106
107 # Fill the histogram showging bad eta-phi region
108 for eta_bin in range(etaMin_bin, etaMax_bin):
109 eta = rv[m].GetXaxis().GetBinCenter(eta_bin)
110 for phi_bin in range(phiMin_bin, phiMax_bin):
111 phi = rv[m].GetYaxis().GetBinCenter(phi_bin)
112 rv[m].Fill(eta, phi)
113 if phiMin[ybin] > phiMax[ybin]:
114 for phi_bin in range(1, phiMax_bin):
115 phi = rv[m].GetYaxis().GetBinCenter(phi_bin)
116 rv[m].Fill(eta, phi)
117 for phi_bin in range(phiMin_bin, rv[m].GetNbinsY()+1):
118 phi = rv[m].GetYaxis().GetBinCenter(phi_bin)
119 rv[m].Fill(eta, phi)
120
121 # Rename histograms' title
122 if sec == 'IBL':
123 rv_IBL = rv[m].Clone()
124 rv_IBL.SetName('badFE_EtaPhi_IBL_new')
125 elif sec == 'BLayer':
126 rv_BLayer = rv[m].Clone()
127 rv_BLayer.SetName('badFE_EtaPhi_BLayer_new')
128 elif sec == 'Layer1':
129 rv_Layer1 = rv[m].Clone()
130 rv_Layer1.SetName('badFE_EtaPhi_Layer1_new')
131 elif sec == 'Layer2':
132 rv_Layer2 = rv[m].Clone()
133 rv_Layer2.SetName('badFE_EtaPhi_Layer2_new')
134
135
138
139 # Define the histograms of bad region in eta-phi for all mask patterns
140 for m in range(0, 15): # (0, 15): All mask patterns
141 # rv1.append(ROOT.TH2F('defectPlot', 'badFEOverlaps', 500, -3.0, 3.0, 500, -math.pi, math.pi))
142 # modified for -2.5 < eta < 2.5
143 rv1.append(ROOT.TH2F('defectPlot', 'badFEOverlaps', 500, -2.5, 2.5, 500, -math.pi, math.pi))
144 rv1[m].GetXaxis().SetTitle('#eta')
145 rv1[m].GetYaxis().SetTitle('#phi')
146
147 # Scan the eta-phi maps showing bad FE region for all layers
148 for xbin in range(rv[0].GetNbinsX()):
149 eta = rv[0].GetXaxis().GetBinCenter(xbin+1)
150 for ybin in range(rv[0].GetNbinsY()):
151 phi = rv[0].GetYaxis().GetBinCenter(ybin+1)
152 entIBL = rv_IBL.GetBinContent(xbin+1, ybin+1)
153 entBLayer = rv_BLayer.GetBinContent(xbin+1, ybin+1)
154 entLayer1 = rv_Layer1.GetBinContent(xbin+1, ybin+1)
155 entLayer2 = rv_Layer2.GetBinContent(xbin+1, ybin+1)
156
157 # Find regions where bad FEs overlap across multiple layers
158 if entIBL >= 1 and entBLayer >= 1 and entLayer1 >= 1 and entLayer2 >= 1: # IBL & B-Layer & Layer1 & Layer2
159 rv1[0].SetTitle('badFE_EtaPhi_IBL_BLayer_Layer1_Layer2')
160 rv1[0].Fill(eta, phi)
161 elif entIBL >= 1 and entBLayer >= 1 and entLayer1 >= 1: # IBL & B-Layer & Layer1
162 rv1[1].SetTitle('badFE_EtaPhi_IBL_BLayer_Layer1')
163 rv1[1].Fill(eta, phi)
164 elif entIBL >= 1 and entBLayer >= 1 and entLayer2 >= 1: # IBL & B-Layer & Layer2
165 rv1[2].SetTitle('badFE_EtaPhi_IBL_BLayer_Layer2')
166 rv1[2].Fill(eta, phi)
167 elif entIBL >= 1 and entLayer1 >= 1 and entLayer2 >= 1: # IBL & Layer2 & Layer2
168 rv1[3].SetTitle('badFE_EtaPhi_IBL_Layer1_Layer2')
169 rv1[3].Fill(eta, phi)
170 elif entBLayer >= 1 and entLayer1 >= 1 and entLayer2 >= 1: # B-Layer & Layer2 & Layer2
171 rv1[4].SetTitle('badFE_EtaPhi_BLayer_Layer1_Layer2')
172 rv1[4].Fill(eta, phi)
173 elif entIBL >= 1 and entBLayer >= 1: # IBL & B-Layer
174 rv1[5].SetTitle('badFE_EtaPhi_IBL_BLayer')
175 rv1[5].Fill(eta, phi)
176 elif entIBL >= 1 and entLayer1 >= 1: # IBL & Layer1
177 rv1[6].SetTitle('badFE_EtaPhi_IBL_Layer1')
178 rv1[6].Fill(eta, phi)
179 elif entIBL >= 1 and entLayer2 >= 1: # IBL & Layer2
180 rv1[7].SetTitle('badFE_EtaPhi_IBL_Layer2')
181 rv1[7].Fill(eta, phi)
182 elif entBLayer >= 1 and entLayer1 >= 1: # B-Layer & Layer1
183 rv1[8].SetTitle('badFE_EtaPhi_BLayer_Layer1')
184 rv1[8].Fill(eta, phi)
185 elif entBLayer >= 1 and entLayer2 >= 1: # B-Layer & Layer2
186 rv1[9].SetTitle('badFE_EtaPhi_BLayer_Layer2')
187 rv1[9].Fill(eta, phi)
188 elif entLayer1 >= 1 and entLayer2 >= 1: # Layer1 & Layer2
189 rv1[10].SetTitle('badFE_EtaPhi_Layer1_Layer2')
190 rv1[10].Fill(eta, phi)
191 elif entIBL >= 1: # IBL only
192 rv1[11].SetTitle('badFE_EtaPhi_onlyIBL')
193 rv1[11].Fill(eta, phi)
194 elif entBLayer >= 1: # B-Layer only
195 rv1[12].SetTitle('badFE_EtaPhi_onlyBLayer')
196 rv1[12].Fill(eta, phi)
197 elif entLayer1 >= 1: # Layer1 only
198 rv1[13].SetTitle('badFE_EtaPhi_onlyLayer1')
199 rv1[13].Fill(eta, phi)
200 elif entLayer2 >= 1: # Layer2 only
201 rv1[14].SetTitle('badFE_EtaPhi_onlyLayer2')
202 rv1[14].Fill(eta, phi)
203
204 # Calculate total degradation,
205 # FIXME: IBL-only case should be calculated by a different method using degradation factor map
206 for m in range(0, 15): # (0, 15): All mask pattern
207 if m==11:
208 deg = degfactor_IBLtotal
209 else:
210 nBadRegion = rv1[m].Integral()
211 badFrac = nBadRegion/(500*500)
212 deg = (1.0-degFactor70[m])*badFrac
213 totalDeg = totalDeg + deg
214
215 a = LB.split('_')
216 LB_deg.Fill(int(a[1]), totalDeg) # Fill the estimated degradation of this LB
217 binNum = LB_deg.FindBin(int(a[1]))
218 LB_deg.SetBinError(binNum, 0)
219
220 return [rv_IBL, rv_BLayer, rv_Layer1, rv_Layer2, rv1[0], rv1[1], rv1[2], rv1[3], rv1[4], rv1[5], rv1[6], rv1[7], rv1[8], rv1[9], rv1[10], rv1[11], rv1[12], rv1[13], rv1[14], LB_deg]
221
222
223
224def evaluateModuleHistograms(inputs, minBinStat=5, mvaThr=0.5, excludeOutOfAcc=True, historyDepth=10):
225 layer = inputs[0][0]['layer']
226 ohisto = inputs[0][1][1].Clone()
227 ohisto.Reset()
228 i_layer = baselayers.index(layer)
229
230 # from this histo get current LB
231 lbhisto = inputs[0][1][2]
232 lbn = lbhisto.FindLastBinAbove(0)
233 currentLB = lbn + 1
234 if currentLB<historyDepth: # do nothing, return empty histogram
235 return [ohisto]
236
237 histos = [_[1][0] for _ in inputs]
238 for ih, histo in enumerate(histos):
239 #
240 # collect info from module's past behaviour
241 #
242 stat = 0
243 cont = 0
244 for inputbin in range(currentLB-historyDepth, currentLB):
245 stat += histo.GetBinEntries(inputbin)
246 cont += histo.GetBinContent(inputbin)*histo.GetBinEntries(inputbin)
247 #
248 # from module name get binx, biny of output histo
249 #
250 splits = histo.GetName().split('_')
251 if (layer in ['BLayer','Layer1','Layer2']):
252 x = splits[3]
253 y = splits[1] + '_' + splits[2]
254 elif layer=='IBL':
255 #S0_M1A -> A1_0
256 x = splits[3][2] + splits[3][1] + '_' + splits[2][1]
257 #B14 -> #S14
258 y = 'S'+splits[1][1:]
259 else:
260 # D1 -> Disk 1
261 x = 'Disk ' + splits[0][1]
262 # remove 'A' or 'C'
263 y = splits[1] + '_' + splits[2] + '_' + splits[3][:-1]
264 i_x = LabelX[i_layer].index(x)+1
265 i_y = LabelY[i_layer].index(y)+1
266 i_bin = i_y*(xbinsl[i_layer]+2) + i_x
267
268 # assessment
269 if (i_x<5 or i_x>ohisto.GetNbinsX()-4) and layer=='IBL' and excludeOutOfAcc :
270 ohisto.SetBinContent(i_x,i_y,0)
271 ohisto.SetBinEntries(i_bin,1) #OK (out of acceptance)
272 elif (i_x==1 or i_x==ohisto.GetNbinsX()) and layer=='BLayer' and excludeOutOfAcc :
273 ohisto.SetBinContent(i_x,i_y,0)
274 ohisto.SetBinEntries(i_bin,1) #OK (out of acceptance)
275 else:
276 if stat>=minBinStat:
277 if cont/stat>mvaThr: #not OK
278 ohisto.SetBinContent(i_x,i_y,1.0)
279 ohisto.SetBinEntries(i_bin,1)
280 else: #OK
281 ohisto.SetBinContent(i_x,i_y,0)
282 ohisto.SetBinEntries(i_bin,1)
283 else: #not enough info - empty
284 ohisto.SetBinContent(i_x,i_y,0)
285 ohisto.SetBinEntries(i_bin,0)
286
287
288 if layer=='IBL':
289 ohisto.SetBinContent(11,13,0) # FE S13-C3-M0 - OK
290 ohisto.SetBinEntries(ohisto.GetBin(11,13),1)
291
292 ohisto.SetName('FixMe_'+str(layer))
293 if 'IBL' in layer:
294 ohisto.SetTitle('Front-Ends to fix, '+str(layer))
295 else:
296 ohisto.SetTitle('Modules to fix, '+str(layer))
297 ohisto.SetOption("colztext")
298 return [ohisto]
299
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
evaluateModuleHistograms(inputs, minBinStat=5, mvaThr=0.5, excludeOutOfAcc=True, historyDepth=10)
Definition index.py:1