Coverage for src/km3dq_common/config_library.py: 0%

179 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-25 11:58 +0000

1#! /usr/bin/env python 

2############################################################################### 

3# Definition of QAQC variable, defects, data-quality tags... 

4# 

5# Developer: Benjamin Trocme (benjamin.trocme at apc.in2p3.fr) - 2023 

6 

7import tomli 

8import sys 

9 

10from km3dq_common import config_path 

11 

12##################################### 

13# Definition of the current detectors 

14WEEKLY_DETECTORS = {"ORCA": "D0ORCA023", 

15 "ARCA": "D0ARCA028"} 

16WEEKLY_TAGS = ["default", 

17 "calibration"] 

18 

19 

20############################################################################### 

21def get_detx_caract(det): 

22 """ Return the number of DOMs (incl base module so far) and PMts """ 

23 

24 all_caract = {} 

25 all_caract['D0ARCA028'] = {"doms": 504, 

26 "pmts": 14341} 

27 all_caract['D0ARCA021'] = {"doms": 378, 

28 "pmts": 11718} 

29 all_caract['D0ARCA020'] = {"doms": 342, 

30 "pmts": 10602} 

31 all_caract['D0ARCA009'] = {"doms": 162, 

32 "pmts": 5022} 

33 

34 all_caract['D0ORCA023'] = {"doms": 414, 

35 "pmts": 11698} 

36 all_caract['D1ORCA019'] = {"doms": 342, 

37 "pmts": 9643} 

38 all_caract['D0ORCA018'] = {"doms": 324, 

39 "pmts": 10044} 

40 all_caract['D1ORCA015'] = {"doms": 270, 

41 "pmts": 8370} 

42 all_caract['D0ORCA015'] = {"doms": 270, 

43 "pmts": 8370} 

44 all_caract['D1ORCA011'] = {"doms": 198, 

45 "pmts": 6138} 

46 all_caract['D0ORCA011'] = {"doms": 198, 

47 "pmts": 6138} 

48 all_caract['D1ORCA013'] = {"doms": 234, 

49 "pmts": 7254} 

50 all_caract['D0ORCA007'] = {"doms": 126, 

51 "pmts": 3906} 

52 all_caract['D0ORCA010'] = {"doms": 180, 

53 "pmts": 5580} 

54 all_caract['D_ORCA006'] = {"doms": 108, 

55 "pmts": 3348} 

56 

57 return all_caract[det] 

58 

59 

60############################################################################### 

61def configure_var_name(v_prop): 

62 """ Description of JQAQC variables """ 

63 

64 # QAQC variables 

65 v_prop['description'] = {"run": "Run", 

66 "livetime": "Livetime (s)", 

67 "nb_of_meta": "Nb of metadata", 

68 "timestampdiff": "Missing time-slices", 

69 "timestampdiff_r": ("Missing time-slices" 

70 "/Run duration"), 

71 "triggerrate": "Trigger rate(Hz)", 

72 "hrv": "High rate veto bit", 

73 "daq": "UDP packet-loss (DAQ)", 

74 "whiterabbitstatus": "White rabbit status", 

75 "fifo": "FIFO almost full", 

76 "pmts": "Number of PMTs", 

77 "pmts_norm": "Normalized number of PMTs", 

78 "meanrate": "Mean rate (Hz)", 

79 "rmsrate": "RMS rate (Hz)", 

80 "hrv_fifo_failures": "Number of hrv/fifo failures", 

81 "duplic_timeslices": "Number of duplicated timeslices", 

82 "oos": "Out-of-sync", 

83 "out_usync": "Micro out-of-sync", 

84 "JDAQJTProc": "Triggered != Retriggered", 

85 "acoustics": "Acoustic rate", 

86 "ahrs_per_mn": ("Number of AHRS event per minute " 

87 "in > 80% of DOMs"), 

88 "jdaqevent": "Total", 

89 "jtrigger3dshower": "3D shower trigger", 

90 "jtriggermxshower": "MX shower trigger", 

91 "jtrigger3dmuon": "3D Muon trigger "} 

92 

93 

94############################################################################### 

95def configure_dataquality_tag(tag): 

96 """ 

97 TOMl configuration of the data quality tags 

98 === Arguments === 

99 - tag : tag name - [string] - Ex: "default", "neutrino2024"... 

100 === Output === 

101 - Dictionnary with all tag characteristics for all detectors 

102 """ 

103 #################################################### 

104 def all_dets_process(tag, toml_input, det_list): 

105 # det_list: dictionnary with keys ARCA, ORCA 

106 output = {} 

107 

108 for i_site in ["ARCA", "ORCA"]: 

109 for i_det in det_list[i_site].split(" "): 

110 if tag in toml_input.keys(): 

111 if i_det in toml_input[tag]: # Detector explicitly defined 

112 output[i_det] = toml_input[tag][i_det] 

113 else: # Use the site definition 

114 output[i_det] = toml_input[tag][i_site] 

115 else: 

116 output[i_det] = "N/A" 

117 

118 return output 

119 

120 try: 

121 with open(config_path("dataquality_tag"), mode="rb") as fconfig: 

122 toml = tomli.load(fconfig) 

123 

124 dq_t = {} 

125 

126 # The path directory is the name of the data-quality tag 

127 dq_t['dir_path'] = tag 

128 

129 # Retrieve the general descriptions 

130 dq_t['name'] = toml['short_descr'][tag] 

131 dq_t['descr'] = toml['descr'][tag] 

132 dq_t['status'] = toml['status'][tag] 

133 

134 # Retrieve the dataset from the dataset.toml file 

135 dq_t['dataset'] = toml['dataset'][tag] 

136 

137 except: 

138 print("Problem in dataquality_tag.toml file") 

139 sys.exit() 

140 

141 try: 

142 with open(config_path("dataset"), mode="rb") as fconfig_ds: 

143 toml_ds = tomli.load(fconfig_ds) 

144 dq_t['dataset_descr'] = toml_ds['descr'][dq_t['dataset']] 

145 

146 # QAQC version - Detector dependant -> specific processing 

147 dq_t['qaqc_vers'] = all_dets_process(dq_t['dataset'], 

148 toml_ds['qaqc_vers'], 

149 toml_ds['site_all_dets'][dq_t['dataset']]) 

150 # Extract the list of available detectors based on the 

151 # definition of the QAQC-file versions and the site_all_dets variable 

152 dq_t['det'] = {"ORCA": [], 

153 "ARCA": []} 

154 for i_det in dq_t['qaqc_vers'].keys(): 

155 if "ORCA" in i_det and i_det in toml_ds['site_all_dets'][dq_t['dataset']]['ORCA']: 

156 dq_t['det']['ORCA'].append(i_det) 

157 elif "ARCA" in i_det and i_det in toml_ds['site_all_dets'][dq_t['dataset']]['ARCA']: 

158 dq_t['det']['ARCA'].append(i_det) 

159 

160 # Retrieve the defect tag 

161 dq_t['def_tag'] = toml['def_tag'][tag] 

162 except: 

163 print("Problem in dataset configuration") 

164 sys.exit() 

165 

166 # Retrieve the processing type/versions from the processing.toml file 

167 # Detector dependant -> specific processing 

168 try: 

169 dq_t['proc'] = toml_ds['proc'][dq_t['dataset']] 

170 with open(config_path("processing"), mode="rb") as fconfig_proc: 

171 toml_proc = tomli.load(fconfig_proc) 

172 dq_t['proc_descr'] = toml_proc['descr'][dq_t['proc']] 

173 dq_t['proc_type'] = all_dets_process(dq_t['proc'], 

174 toml_proc['proc_type'], 

175 toml_ds['site_all_dets'][dq_t['dataset']]) 

176 dq_t['proc_version'] = all_dets_process(dq_t['proc'], 

177 toml_proc['proc_version'], 

178 toml_ds['site_all_dets'][dq_t['dataset']]) 

179 except: 

180 print("Problem in processing configuration") 

181 sys.exit() 

182 

183 # Retrieve the good run list definition 

184 try: 

185 dq_t['grl'] = toml['grl'][tag] 

186 # Open the grl.toml file to retrieve the grl description 

187 with open(config_path("grl"), mode="rb") as fconfig_grl: 

188 toml_grl = tomli.load(fconfig_grl) 

189 dq_t['grl_descr'] = toml_grl['descr'][dq_t['grl']] 

190 # GRL names - If not defined, use the quasi_online one. 

191 if dq_t['grl'] in toml_grl['grl_name'].keys(): 

192 dq_t['grl_name'] = toml_grl['grl_name'][dq_t['grl']] 

193 else: 

194 dq_t['grl_name'] = toml_grl['grl_name']['quasi_online'] 

195 except: 

196 print("Problem in grl configuration") 

197 sys.exit() 

198 

199 return dq_t 

200 

201 

202############################################################################### 

203def configure_defect(): 

204 """ 

205 TOMl configuration of the defects 

206 """ 

207 with open(config_path("defect"), mode="rb") as fconfig: 

208 toml = tomli.load(fconfig) 

209 

210 defect_0 = {} 

211 

212 defect_0['descr'] = toml['descr'] 

213 defect_0['type'] = list(defect_0['descr'].keys()) 

214 defect_0['bit'] = toml['bit'] 

215 

216 return defect_0 

217 

218 

219############################################################################### 

220def configure_def_var_name(v_prop): 

221 """ Description of defect variables """ 

222 

223 # QAQC variables 

224 v_prop['description']["def_daq"] = "DAQ defects" 

225 v_prop['description']["def_operation"] = "Operation defects" 

226 # v_prop['description']["def_oos"] = "Out-of-sync defects" 

227 v_prop['description']["def_data_corruption"] = "Data corruption defects" 

228 v_prop['description']["def_calibration"] = "Calibration defects" 

229 v_prop['description']["def_data_processing"] = "Data processing defects" 

230 v_prop['description']["def_analysis"] = "Analysis defects" 

231 v_prop['description']["def_high_level_analysis"] = "Neutrino analysis defects" 

232 v_prop['description']["def_signoff"] = "Missing signoff" 

233 

234 

235############################################################################### 

236def configure_fact(): 

237 """ 

238 TOMl configuration of the facts 

239 """ 

240 with open(config_path("fact"), mode="rb") as fconfig: 

241 toml = tomli.load(fconfig) 

242 

243 fact_0 = {} 

244 

245 fact_0['type'] = toml['type'] 

246 

247 return fact_0 

248 

249 

250############################################################################### 

251def configure_det_fact(): 

252 """ 

253 TOMl configuration of the detector facts 

254 """ 

255 with open(config_path("det_fact"), mode="rb") as fconfig: 

256 toml = tomli.load(fconfig) 

257 

258 det_fact_0 = {} 

259 

260 det_fact_0['type'] = toml['type'] 

261 det_fact_0['status'] = toml['status'] 

262 

263 return det_fact_0 

264 

265 

266############################################################################### 

267def configure_var_unit(v_prop): 

268 """ Description of variables """ 

269 v_prop['unit'] = {"livetime": "s", 

270 "timestampdiff": "s", 

271 "triggerrate": "Hz", 

272 "meanrate": "Hz", 

273 "rmsrate": "Hz"} 

274 

275 

276############################################################################### 

277def configure_var_bit(v_prop): 

278 """ 

279 Bit of variables contributing to the veto//Qscore degradation  

280 used to store in the TTree 

281 """ 

282 v_prop['bit'] = {"livetime": 0, 

283 "timestampdiff": 1, 

284 "timestampdiff_r": 2, 

285 "triggerrate": 3, 

286 "hrv": 4, 

287 "daq": 5, 

288 "whiterabbitstatus": 6, 

289 "fifo": 7, 

290 "pmts": 8, 

291 "pmts_norm": 9, 

292 "meanrate": 10, 

293 "rmsrate": 11, 

294 "oos": 12, 

295 "out_usync": 13, 

296 "JDAQJTProc": 14, 

297 "acoustics": 15, 

298 "ahrs_per_mn": 16, 

299 "nb_of_meta": 17, 

300 "hrv_fifo_failures": 18, 

301 "duplic_timeslices": 19, 

302 "def_daq": 22, 

303 "def_operation": 23, 

304 # "def_oos": 24, 

305 "def_data_corruption": 25, 

306 "def_calibration": 26, 

307 "def_data_processing": 27, 

308 "def_analysis": 28, 

309 "def_high_level_analysis": 29, 

310 "def_signoff": 30} 

311 

312 

313############################################################################### 

314def configure_var_thresholds(v_prop, det, dqt): 

315 """ 

316 Configure various variables for the analysis of the TTree derived from 

317 the JQAQC file 

318 TOMl configuration 

319 """ 

320 with open(config_path("grl"), mode="rb") as fconfig: 

321 toml = tomli.load(fconfig) 

322 

323 # First fill the thresholds with the quasi_online ones 

324 # It is mandatory as all thresholds are derived from them 

325 v_prop['veto_thresholds'] = dict(toml['veto_thresholds']['quasi_online']) 

326 v_prop['qsco_thresholds'] = dict(toml['qsco_thresholds']['quasi_online']) 

327 v_prop['good_thresholds'] = dict(toml['good_thresholds']['quasi_online']) 

328 v_prop['poor_thresholds'] = dict(toml['poor_thresholds']['quasi_online']) 

329 v_prop['bad_thresholds'] = dict(toml['bad_thresholds']['quasi_online']) 

330 v_prop['discard_thresholds'] = dict(toml['discard_thresholds']['quasi_online']) 

331 v_prop['y_range_display'] = dict(toml['y_range_display']['quasi_online']) 

332 

333 # If non quasi_online GRL, update the thresholds with the config file 

334 for i_type in ("veto_thresholds", "qsco_thresholds", 

335 "good_thresholds", "poor_thresholds", 

336 "bad_thresholds", "discard_thresholds", 

337 "y_range_display"): 

338 if dqt['grl'] != "quasi_online" and dqt['grl'] in toml[i_type].keys(): 

339 for i_modif in toml[i_type][dqt['grl']]: 

340 # If empty list, remove the thresholds defined in quasi_online dqt['grl'] 

341 if len(toml[i_type][dqt['grl']][i_modif]) == 0: 

342 v_prop[i_type].pop(i_modif) 

343 continue 

344 # Otherwise update them 

345 v_prop[i_type][i_modif] = \ 

346 toml[i_type][dqt['grl']][i_modif] 

347 

348 # DUMMY detector used only by the get_grl_html_descr function 

349 # used by km3dq_perf/generatewww.py - No impact on perf 

350 if det == "DUMMY": 

351 return 

352 

353 # Special cases impossible to handle with TOML 

354 if "v16.0.3" in dqt["qaqc_vers"][det]: 

355 if "out_usync" in v_prop['veto_thresholds']: 

356 v_prop['veto_thresholds'].pop("out_usync") 

357 if "out_usync" in v_prop['qsco_thresholds']: 

358 v_prop['qsco_thresholds'].pop("out_usync") 

359 if any(("v16.0.3" in dqt["qaqc_vers"][det], 

360 "v17.3.2" in dqt["qaqc_vers"][det])): 

361 for i_missing in ["nb_of_meta", "hrv_fifo_failures", "duplic_timeslices"]: 

362 if i_missing in v_prop['veto_thresholds']: 

363 v_prop['veto_thresholds'].pop(i_missing) 

364 if i_missing in v_prop['qsco_thresholds']: 

365 v_prop['qsco_thresholds'].pop(i_missing) 

366 

367 # Display options 

368 v_prop['y_range_display']['pmts'][1] = get_detx_caract(det)['pmts']*1.2 

369 if "ORCA" in det: # Increased range for bioluminescence 

370 v_prop['y_range_display']["hrv"] = [-0.1, 0.8] 

371 

372 

373############################################################################### 

374def get_grl_html_descr(dq_tag_0): 

375 """ 

376 Returns the grl description in an html for the summary webpage 

377 The grl may depend on the detector due to missing variables. This is  

378 by-passed by passing a dummy value to the configure_var_thresholds 

379 function. In this way, no variable is discarded 

380 """ 

381 

382 var_prop = {} 

383 configure_var_thresholds(var_prop, "DUMMY", dq_tag_0) 

384 configure_var_unit(var_prop) 

385 html_descr = {} 

386 for i_key in var_prop.keys(): 

387 # One assumes that the QQC variables arrive before the defects 

388 # in the configuration file 

389 html_descr[i_key] = "<b>QAQC variables</b><br>" 

390 defect_found = False 

391 for i_var in var_prop[i_key].keys(): 

392 # qaqc variable 

393 if any((isinstance(var_prop[i_key][i_var][0], int), 

394 isinstance(var_prop[i_key][i_var][0], float))): 

395 if var_prop[i_key][i_var][0] == var_prop[i_key][i_var][1]: 

396 thresh = f"{var_prop[i_key][i_var][0]}" 

397 if i_var == "veto": 

398 thresh = f"{var_prop[i_key][i_var][0] == 1}" 

399 else: 

400 thresh = (f"{var_prop[i_key][i_var][0]} &#8212 " 

401 f"{var_prop[i_key][i_var][1]}") 

402 if i_var in var_prop['unit'].keys(): 

403 thresh += f" {var_prop['unit'][i_var]}" 

404 

405 html_descr[i_key] += (f"{i_var}: {thresh}") 

406 # defect 

407 elif isinstance(var_prop[i_key][i_var][0], str): 

408 if defect_found is False: 

409 html_descr[i_key] += "<hr><b>Defects</b><br>" 

410 defect_found = True 

411 html_descr[i_key] += (f"{i_var.replace('def_', '')}: " 

412 f"{var_prop[i_key][i_var][0]}") 

413 for j in range(1, len(var_prop[i_key][i_var])): 

414 html_descr[i_key] += (f", {var_prop[i_key][i_var][j]}") 

415 

416 html_descr[i_key] += ("<br>") 

417 

418 return html_descr