ATLAS Offline Software
Recovery.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
3 import json
4 
5 # Reading from the generated file in MakeReferenceFile
6 # It converts the DB payload into a python dictionary using json
7 def ReadDbFile(name):
8  mydict = dict()
9  iov = "non"
10  with open(name) as fp:
11  lines = fp.readlines()
12  for line in lines:
13  if(line.startswith('[\'')):
14  # Removes ending
15  line = line.rstrip(']\n')
16  # Split to get just the dictionary in the second position
17  arrayline = line.split(' : ')
18  mydict = json.loads(arrayline[1])
19  else:
20  iov = line[:line.find(" - ")]
21  print("Data base IOV: %s" % line)
22 
23  return mydict, iov
24 
25 
26 def ReadNewCalib(name):
27  mydict = dict()
28  report_dict = { "Blayer":0 , "L1":0 , "L2":0 , "Disk":0, "unexp.":0}
29  with open(name) as fp:
30  lines = fp.readlines()
31  mod = ""
32  for line in lines:
33  if line.startswith("L") or line.startswith("D"):
34 
35  if line.startswith("L0"): report_dict["Blayer"] += 1
36  elif line.startswith("L1"): report_dict["L1"] += 1
37  elif line.startswith("L2"): report_dict["L2"] += 1
38  elif line.startswith("D"): report_dict["Disk"] += 1
39  else:
40  print(line)
41  report_dict["unexp."] += 1
42 
43  splitline = line.rstrip("\n").split(" ")
44  if len(splitline) == 2:
45  mydict[splitline[1]] = []
46  mod = splitline[1]
47  else:
48  print("ReadNewCalib - ERROR Length of the module is not the correct one. Expected ['module_name', 'hash_ID']. Value:", splitline)
49  elif line.startswith("I"):
50  splitline = line.rstrip("\n").split(" ")
51  splitline.pop(0)
52  float_splitline = [float(string) for string in splitline]
53  mydict[mod].append(float_splitline)
54 
55  return mydict, report_dict
56 
57 def ReadOldCalib(name):
58  mydict = dict()
59  with open(name) as fp:
60  lines = fp.readlines()
61  mod = ""
62  for line in lines:
63  if line.startswith("L") or line.startswith("D"):
64 
65  splitline = line.rstrip("\n").split(" : ")
66  splitline = list(filter(None,splitline[1].split(" ")))
67  if len(splitline) == 2:
68  mydict[splitline[0]] = []
69  mod = splitline[0]
70  else:
71  print("ReadNewCalib - ERROR Length of the module is not the correct one. Expected ['module_name', 'hash_ID']. Value:", splitline)
72  elif line.startswith("I"):
73  splitline = line.rstrip("\n").split(" ")
74  splitline.pop(0)
75  float_splitline = [float(string) for string in splitline]
76  mydict[mod].append(float_splitline)
77  return mydict
78 
79 def avg(a, b):
80  return 1/2*(a + b)
81 
82 
83 # This function recovers the thresholds for the normal, long and ganged pixels
84 def recover_thr(thr1, thr2, listarray, ref_val):
85  recovered_value = avg(thr1, thr2)
86 
87  if recovered_value == 0:
88  if not listarray:
89  recovered_value = ref_val
90  else:
91  recovered_value = sum(listarray)/len(listarray)
92  return recovered_value
93 
94 # This function recovers other than the thresholds
95 def recover(listarray, ref_val):
96 
97  if ref_val == 0:
98  if not listarray:
99  return ref_val
100  else:
101  return sum(listarray)/len(listarray)
102 
103  return ref_val
104 
105 def recover_empties(new_calib, ref_calib):
106 
107  report_dict = dict()
108  report_counter_dict = {"empty" : 0 , "all_zeros":0}
109 
110  for module, frontEnds in new_calib.items():
111 
112  nFE = len(frontEnds)
113  # Checking FE with data loss - All empty
114  for itr_fe in range(nFE):
115 
116  failures = frontEnds[itr_fe].count(0) + frontEnds[itr_fe].count(-28284.3)
117 
118  if failures != 0 :
119  if module not in report_dict:
120  report_dict[module] = []
121 
122  # Recovering O but not empty FE
123  if failures != len(frontEnds[itr_fe]):
124  report_counter_dict["empty"] += 1
125  report_dict[module].append(" FE%02d with %i zeros. Positions:" % (itr_fe,failures))
126 
127  # Running over values and replace them with the previous calibration
128  for itr_par in range(len(frontEnds[itr_fe])):
129  if( frontEnds[itr_fe][itr_par] == 0 or frontEnds[itr_fe][itr_par] == -28284.3):
130 
131  report_dict[module][-1] = report_dict[module][-1] + (" %s,"%(str(itr_par)))
132 
133  # List of the same parameter from the other FE of the same module, it will be used in order to get the average of the module frontEnds
134  val_list = [new_calib[module][i][itr_par] for i in range(nFE) if new_calib[module][i][itr_par] != 0 ]
135  val_list_fit = [new_calib[module][i][itr_par] for i in range(nFE) if new_calib[module][i][itr_par] != 0 and new_calib[module][i][itr_par] != -28284.3 ]
136 
137  # Threshold for normal pixels
138  if itr_par == 0:
139  new_calib[module][itr_fe][itr_par] = recover_thr(frontEnds[itr_fe][4], frontEnds[itr_fe][8], val_list, ref_calib[module][itr_fe][itr_par] )
140 
141  # Threshold for long pixels
142  elif itr_par == 4:
143  new_calib[module][itr_fe][itr_par] = recover_thr(frontEnds[itr_fe][0], frontEnds[itr_fe][8], val_list, ref_calib[module][itr_fe][itr_par])
144 
145  # Threshold for ganged pixels
146  elif itr_par == 8:
147  new_calib[module][itr_fe][itr_par] = recover_thr(frontEnds[itr_fe][0], frontEnds[itr_fe][4], val_list, ref_calib[module][itr_fe][itr_par])
148 
149  # rest of parameters
150  else:
151  # itr_par 13 or 16 are the fit parameters for the denominator. Bad values are 0 or -28284.3 so we need to exclude them from the list
152  if itr_par == 13 or itr_par == 16:
153  new_calib[module][itr_fe][itr_par] = recover(val_list_fit, ref_calib[module][itr_fe][itr_par])
154  else:
155  new_calib[module][itr_fe][itr_par] = recover(val_list, ref_calib[module][itr_fe][itr_par])
156 
157  # Recovering empty FE
158  else :
159  report_counter_dict["all_zeros"] += 1
160  report_dict[module].append(" FE%02d full copy" % itr_fe)
161  new_calib[module][itr_fe] = ref_calib[module][itr_fe]
162 
163  return report_dict, report_counter_dict
164 
165 def UpdateAndSave(new_calib, ref_calib):
166 
167  # Validation for the new calibration (checks the threshold, RMS, Noise and Intime thresholds)
168  from PixelCalibAlgs.CheckValues import CheckThresholds
169  CheckThresholds(new_calib)
170 
171  # Making a copy of the reference calibration
172  updated_calib = ref_calib.copy()
173 
174  # Updating the value with the new calibration
175  updated_calib.update(new_calib)
176 
177  total_fe = 0
178  for key, values in updated_calib.items():
179  total_fe += len(values)
180 
181 
182  print("%-45s: %6i" % ("Total modules in the calibration candidate",len(updated_calib)))
183  print("%-45s: %6i\n" % ("Total FE in the calibration candidate",total_fe))
184 
185 
186 
187  # Commented out since it could be used for comparison - Experts only
188  # Fprint(new_calib , "final_new_calib.txt")
189  # Fprint(ref_calib , "final_ref_calib.txt")
190  Fprint(updated_calib, "FINAL_calibration_candidate.txt")
191 
192  return updated_calib
193 
194 def Fprint(dict, name):
195  f = open(name, "w")
196  for key, values in dict.items():
197 
198  for value in values:
199  f.write("%s %i %i %i %i %i %i %i %i %i %i %i %i %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g\n" % (
200  key,
201  value[ 0], value[ 1], value[ 2], value[ 3],
202  value[ 4], value[ 5], value[ 6], value[ 7],
203  value[ 8], value[ 9], value[10], value[11],
204  value[12], value[13], value[14],
205  value[15], value[16], value[17],
206  value[18], value[19]
207  ))
208 
209 def UpdateCalib(tag):
210  ref_calib, iov = ReadDbFile(tag+".log")
211  new_calib, read_report = ReadNewCalib("calibration_merged.txt")
212 
213  # modifying the new_calib dictionary in order to recover the empty FE
214  print("Recovering missing information..")
215  report, counter_report = recover_empties(new_calib,ref_calib)
216 
217  print("Validating and updating reference calibration.. ")
218  UpdateAndSave(new_calib,ref_calib)
219 
220  f = open("log_recovery.txt", "w")
221  str = "-------- SUMMARY OF PIXEL CALIB RECOVERY --------\n"
222  str += "Modules Calibrated:\n"
223 
224  for key,value in read_report.items():
225  str += "%10s read: %4i\n" % (key, value)
226  str += "\n"
227 
228  str += "Error counters:\n"
229  str += " %15s: %5i\n" % ("Empty values", counter_report["empty"])
230  str += " %15s: %5i\n" % ("Full FE copied", counter_report["all_zeros"])
231 
232  print(str)
233  print("More information in: log_recovery.txt")
234  print("NEW CALIBRATION file to update the DB: FINAL_calibration_candidate.txt")
235 
236  str += """Positions of single 0's:
237  0: normal_threshold, 1: normal_RMS, 2: normal_noise, 3: normal_intime
238  4: long_threshold , 5: long_RMS , 6: long_noise , 7: long_intime
239  8: ganged_threshold, 9: ganged_RMS, 10: ganged_noise, 11: ganged_intime
240  12: 13: 14: Fitting for normal pixels
241  15: 16: 17: Fitting for long and ganged pixels
242  18: 19: quality and smearing (used for MC)\n\n"""
243 
244  str += "Modules with empties:\n"
245  for key,values in report.items():
246  str += "HashID: %4s\n" % (key)
247  for value in values:
248  str += value + "\n"
249  f.write(str)
250 
251 
252 
253 
254 # Just used for testing - Experts only
255 if __name__ == "__main__":
256 
257  UpdateCalib("PixelChargeCalibration-DATA-RUN2-UPD4-26")
258  exit(0)
259 
260 
Recovery.ReadOldCalib
def ReadOldCalib(name)
Definition: Recovery.py:57
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
covarianceTool.filter
filter
Definition: covarianceTool.py:514
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
Recovery.ReadNewCalib
def ReadNewCalib(name)
Definition: Recovery.py:26
Recovery.avg
def avg(a, b)
Definition: Recovery.py:79
Recovery.recover_thr
def recover_thr(thr1, thr2, listarray, ref_val)
Definition: Recovery.py:84
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
Recovery.ReadDbFile
def ReadDbFile(name)
Definition: Recovery.py:7
Recovery.recover_empties
def recover_empties(new_calib, ref_calib)
Definition: Recovery.py:105
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
Recovery.UpdateAndSave
def UpdateAndSave(new_calib, ref_calib)
Definition: Recovery.py:165
calibdata.exit
exit
Definition: calibdata.py:236
Recovery.Fprint
def Fprint(dict, name)
Definition: Recovery.py:194
Trk::open
@ open
Definition: BinningType.h:40
CheckValues.CheckThresholds
def CheckThresholds(calib)
Definition: CheckValues.py:16
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:569
str
Definition: BTagTrackIpAccessor.cxx:11
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
Recovery.recover
def recover(listarray, ref_val)
Definition: Recovery.py:95
Recovery.UpdateCalib
def UpdateCalib(tag)
Definition: Recovery.py:209