ATLAS Offline Software
Loading...
Searching...
No Matches
JsonFileWriterL1.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
4
8
9#include <iomanip>
10#include <fstream>
11#include <algorithm>
12#include <sstream>
13
14#include <nlohmann/json.hpp>
15using json = nlohmann::json;
16
17using namespace std;
18
22
23
24bool
25TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const L1Menu & l1menu) const
26{
27
28 json items = json::object_t{};
29 for( auto & item : l1menu ) {
30 json jItem({});
31 jItem["name"] = item.name();
32 jItem["ctpid"] = item.ctpId();
33 jItem["definition"] = item.definition();
34 jItem["monitor"] = item.monitor();
35 jItem["partition"] = item.partition();
36 jItem["triggerType"] = item.triggerType();
37 jItem["bunchgroups"] = json(item.bunchgroups());
38 if(auto legacy = item.legacy() )
39 jItem["legacy"] = *legacy;
40 items[item.name()] = jItem;
41 };
42
43 json thresholds = json::object_t{};
44 for(const std::string & thrType : l1menu.thresholdTypes()) {
45 json jThresholsByType({});
46 // first the thresholds of this type
47 for(auto & thr : l1menu.thresholds(thrType)) {
48 json jThr({});
49 jThr["mapping"] = thr->mapping();
50
51 if(thr->hasChild("sectors")) { // for MBTS_A and MBTS_C
52 std::vector<std::string> sectors;
53 for(auto & s : thr->getList("sectors")) {
54 sectors.push_back(s.getValue());
55 }
56 jThr["sectors"] = sectors;
57 }
58 if(thr->hasAttribute("voltage")) { // for MBTSII
59 jThr["voltage"] = thr->getAttribute<float>("voltage");
60 }
61
62 // value
63 try {
64 if(thr->hasAttribute("value")) {
65 auto & caloThr = dynamic_cast<const TrigConf::L1Threshold_Calo &>(*thr); // for MBTSII
66 jThr["value"] = int(caloThr.thrValue());
67 }
68 } catch(std::bad_cast&) {};
69
70 // MU
71 try {
72 const auto & muThr = dynamic_cast<const TrigConf::L1Threshold_MU &>(*thr);
73 jThr["baThr"] = muThr.ptBarrel();
74 jThr["ecThr"] = muThr.ptEndcap();
75 jThr["fwThr"] = muThr.ptForward();
76 jThr["baIdx"] = muThr.idxBarrel();
77 jThr["ecIdx"] = muThr.idxEndcap();
78 jThr["fwIdx"] = muThr.idxForward();
79 jThr["region"] = muThr.region();
80 jThr["tgcFlags"] = muThr.tgcFlags();
81 jThr["rpcFlags"] = muThr.rpcFlags();
82 if(const std::string & roiExcl = muThr.rpcExclROIList(); !roiExcl.empty()) {
83 jThr["rpcExclROIList"] = roiExcl;
84 }
85 } catch(std::bad_cast&) {};
86
87 // TAU
88 try {
89 const auto & tauThr = dynamic_cast<const TrigConf::L1Threshold_TAU &>(*thr);
90 std::string isobits = "00000";
91 auto isomask = tauThr.isolationMask();
92 for(size_t b=0; b<5; ++b) {
93 if(isomask & (1<<b)) { isobits[4-b] = '1'; }
94 }
95 jThr["isobits"] = isobits;
96 jThr["thrValues"] = json::array_t({});
97 for(auto & rv : tauThr.thrValues()) {
98 json jRV({});
99 jRV["value"] = static_cast<unsigned int>(rv.value());
100 jRV["etamin"] = rv.etaMin();
101 jRV["etamax"] = rv.etaMax();
102 jRV["phimin"] = 0; // never used, so not read
103 jRV["phimax"] = 64; // never used, so not read
104 jRV["priority"] = rv.priority();
105 jThr["thrValues"] += jRV;
106 }
107 } catch(std::bad_cast&) {};
108
109 // EM
110 try {
111 const auto & EMThr = dynamic_cast<const TrigConf::L1Threshold_EM &>(*thr);
112 jThr["thrValues"] = json::array_t({});
113 for(auto & rv : EMThr.thrValues()) {
114 json jRV({});
115 jRV["value"] = static_cast<unsigned int>(rv.value());
116 jRV["etamin"] = rv.etaMin();
117 jRV["etamax"] = rv.etaMax();
118 jRV["phimin"] = 0; // never used, so not read
119 jRV["phimax"] = 64; // never used, so not read
120 std::string isobits = "00000";
121 auto isomask = EMThr.isolationMask(rv.etaMin());
122 for(size_t b=0; b<5; ++b) {
123 if(isomask & (1<<b)) { isobits[4-b] = '1'; }
124 }
125 jRV["isobits"] = isobits;
126 jRV["priority"] = rv.priority();
127 jThr["thrValues"] += jRV;
128 }
129 } catch(std::bad_cast&) {};
130
131 // JET
132 try {
133 const auto & JThr = dynamic_cast<const TrigConf::L1Threshold_JET &>(*thr);
134 jThr["thrValues"] = json::array_t({});
135 for(auto & rv : JThr.thrValues()) {
136 json jRV({});
137 jRV["value"] = static_cast<unsigned int>(rv.value());
138 jRV["etamin"] = rv.etaMin();
139 jRV["etamax"] = rv.etaMax();
140 jRV["phimin"] = 0; // never used, so not read
141 jRV["phimax"] = 64; // never used, so not read
142 jRV["window"] = JThr.window(0);
143 jRV["priority"] = rv.priority();
144 jThr["thrValues"] += jRV;
145 }
146 } catch(std::bad_cast&) {};
147
148 // TE
149 try {
150 const auto & teThr = dynamic_cast<const TrigConf::L1Threshold_TE &>(*thr);
151 //jThr["thrValues"] = json::array_t({});
152 for(auto & rv : teThr.thrValues()) {
153 json jRV({});
154 jRV["value"] = static_cast<unsigned int>(rv.value());
155 jRV["etamin"] = rv.etaMin();
156 jRV["etamax"] = rv.etaMax();
157 jRV["priority"] = rv.priority();
158 jThr["thrValues"] += jRV;
159 }
160 } catch(std::bad_cast&) {};
161
162 // ZB
163 try {
164 const auto & zbThr = dynamic_cast<const TrigConf::L1Threshold_ZB &>(*thr);
165 jThr["seed"] = zbThr.seed();
166 jThr["seedBcdelay"] = zbThr.seedBcdelay();
167 jThr["seedMultiplicity"] = zbThr.seedMultiplicity();
168 } catch(std::bad_cast&) {};
169
170 // ZBTopo
171 try {
172 const auto & zbTopoThr = dynamic_cast<const TrigConf::L1Threshold_ZBTopo &>(*thr);
173 jThr["mask0"] = zbTopoThr.mask0();
174 jThr["mask0"] = zbTopoThr.mask0();
175 jThr["mask0"] = zbTopoThr.mask0();
176 jThr["mask0"] = zbTopoThr.mask0();
177 jThr["mask0"] = zbTopoThr.mask0();
178 jThr["mask0"] = zbTopoThr.mask0();
179 jThr["seedBcdelay"] = zbTopoThr.seedBcdelay();
180
181 } catch(std::bad_cast&) {};
182
183 // eEM
184 try {
185 const auto & eEMThr = dynamic_cast<const TrigConf::L1Threshold_eEM &>(*thr);
186 jThr["reta"] = TrigConf::Selection::wpToString(eEMThr.reta());
187 jThr["rhad"] = TrigConf::Selection::wpToString(eEMThr.rhad());
188 jThr["wstot"] = TrigConf::Selection::wpToString(eEMThr.wstot());
189 jThr["thrValues"] = json::value_t::array;
190 for(auto & rv : eEMThr.thrValues()) {
191 json jRV({});
192 jRV["value"] = static_cast<unsigned int>(rv.value());
193 jRV["etamin"] = rv.etaMin();
194 jRV["etamax"] = rv.etaMax();
195 jRV["priority"] = rv.priority();
196 jThr["thrValues"] += jRV;
197 }
198 } catch(std::bad_cast&) {};
199
200 // jEM
201 try {
202 const auto & jEMThr = dynamic_cast<const TrigConf::L1Threshold_jEM &>(*thr);
203 jThr["iso"] = TrigConf::Selection::wpToString(jEMThr.iso());
204 jThr["frac"] = TrigConf::Selection::wpToString(jEMThr.frac());
205 jThr["frac2"] = TrigConf::Selection::wpToString(jEMThr.frac2());
206 jThr["thrValues"] = json::value_t::array;
207 for(auto & rv : jEMThr.thrValues()) {
208 json jRV({});
209 jRV["value"] = static_cast<unsigned int>(rv.value());
210 jRV["etamin"] = rv.etaMin();
211 jRV["etamax"] = rv.etaMax();
212 jRV["priority"] = rv.priority();
213 jThr["thrValues"] += jRV;
214 }
215 } catch(std::bad_cast&) {};
216
217 // eTAU
218 try {
219 const auto & eTAUThr = dynamic_cast<const TrigConf::L1Threshold_eTAU &>(*thr);
220 jThr["rCore"] = TrigConf::Selection::wpToString(eTAUThr.rCore());
221 jThr["rHad"] = TrigConf::Selection::wpToString(eTAUThr.rHad());
222 jThr["thrValues"] = json::array_t({});
223 for(auto & rv : eTAUThr.thrValues()) {
224 json jRV({});
225 jRV["value"] = static_cast<unsigned int>(rv.value());
226 jRV["etamin"] = rv.etaMin();
227 jRV["etamax"] = rv.etaMax();
228 jRV["phimin"] = 0; // never used, so not read
229 jRV["phimax"] = 64; // never used, so not read
230 jRV["priority"] = rv.priority();
231 jThr["thrValues"] += jRV;
232 }
233 } catch(std::bad_cast&) {};
234
235 // jTAU
236 try {
237 const auto & jTAUThr = dynamic_cast<const TrigConf::L1Threshold_jTAU &>(*thr);
238 jThr["isolation"] = TrigConf::Selection::wpToString(jTAUThr.isolation());
239 jThr["thrValues"] = json::array_t({});
240 for(auto & rv : jTAUThr.thrValues()) {
241 json jRV({});
242 jRV["value"] = static_cast<unsigned int>(rv.value());
243 jRV["etamin"] = rv.etaMin();
244 jRV["etamax"] = rv.etaMax();
245 jRV["phimin"] = 0; // never used, so not read
246 jRV["phimax"] = 64; // never used, so not read
247 jRV["priority"] = rv.priority();
248 jThr["thrValues"] += jRV;
249 }
250 } catch(std::bad_cast&) {};
251
252 // cTAU
253 try {
254 const auto & cTAUThr = dynamic_cast<const TrigConf::L1Threshold_cTAU &>(*thr);
255 jThr["isolation"] = TrigConf::Selection::wpToString(cTAUThr.isolation());
256 jThr["thrValues"] = json::array_t({});
257 for(auto & rv : cTAUThr.thrValues()) {
258 json jRV({});
259 jRV["value"] = static_cast<unsigned int>(rv.value());
260 jRV["etamin"] = rv.etaMin();
261 jRV["etamax"] = rv.etaMax();
262 jRV["phimin"] = 0; // never used, so not read
263 jRV["phimax"] = 64; // never used, so not read
264 jRV["priority"] = rv.priority();
265 jThr["thrValues"] += jRV;
266 }
267 } catch(std::bad_cast&) {};
268
269 // jJ
270 try {
271 const auto & jJThr = dynamic_cast<const TrigConf::L1Threshold_jJ &>(*thr);
272 jThr["thrValues"] = json::array_t({});
273 for(auto & rv : jJThr.thrValues()) {
274 json jRV({});
275 jRV["value"] = static_cast<unsigned int>(rv.value());
276 jRV["etamin"] = rv.etaMin();
277 jRV["etamax"] = rv.etaMax();
278 jRV["priority"] = rv.priority();
279 jThr["thrValues"] += jRV;
280 }
281 } catch(std::bad_cast&) {};
282
283 // jLJ
284 try {
285 const auto & jLJThr = dynamic_cast<const TrigConf::L1Threshold_jLJ &>(*thr);
286 jThr["thrValues"] = json::array_t({});
287 for(auto & rv : jLJThr.thrValues()) {
288 json jRV({});
289 jRV["value"] = static_cast<unsigned int>(rv.value());
290 jRV["etamin"] = rv.etaMin();
291 jRV["etamax"] = rv.etaMax();
292 jRV["priority"] = rv.priority();
293 jThr["thrValues"] += jRV;
294 }
295 } catch(std::bad_cast&) {};
296
297 // gJ
298 try {
299 const auto & gJThr = dynamic_cast<const TrigConf::L1Threshold_gJ &>(*thr);
300 jThr["value"] = int(gJThr.thrValue());
301 } catch(std::bad_cast&) {};
302
303 // gLJ
304 try {
305 const auto & gLJThr = dynamic_cast<const TrigConf::L1Threshold_gLJ &>(*thr);
306 jThr["value"] = int(gLJThr.thrValue());
307 } catch(std::bad_cast&) {};
308
309 // jXE
310 try {
311 const auto & jXEThr = dynamic_cast<const TrigConf::L1Threshold_jXE &>(*thr);
312 jThr["value"] = int(jXEThr.thrValue());
313 } catch(std::bad_cast&) {};
314
315 // jTE
316 try {
317 const auto & jTEThr = dynamic_cast<const TrigConf::L1Threshold_jTE &>(*thr);
318 jThr["value"] = int(jTEThr.thrValue());
319 } catch(std::bad_cast&) {};
320
321 // gXE
322 try {
323 const auto & gXEThr = dynamic_cast<const TrigConf::L1Threshold_gXE &>(*thr);
324 jThr["value"] = int(gXEThr.thrValue());
325 } catch(std::bad_cast&) {};
326
327 // gTE
328 try {
329 const auto & gTEThr = dynamic_cast<const TrigConf::L1Threshold_gTE &>(*thr);
330 jThr["value"] = int(gTEThr.thrValue());
331 } catch(std::bad_cast&) {};
332
333 jThresholsByType[thr->name()] = std::move(jThr);
334 };
335 json jThrType({});
336 if(thrType != "internal") {
337 jThrType["thresholds"] = std::move(jThresholsByType);
338 }
339 jThrType["type"] = thrType;
340
341 // extra info
342 auto & extraInfo = l1menu.thrExtraInfo().thrExtraInfo(thrType);
343 if(extraInfo.hasAttribute("ptMinToTopo")) { // for MBTSII
344 jThrType["ptMinToTopo"] = extraInfo.getAttribute<unsigned int>("ptMinToTopo");
345 }
346 if(extraInfo.hasAttribute("resolutionMeV")) { // for MBTSII
347 jThrType["resolutionMeV"] = extraInfo.getAttribute<unsigned int>("resolutionMeV");
348 }
349
350 // extra info using type specific accessors
351 if(thrType == "internal") {
352 jThrType["names"] = json::array_t({});
353 for(auto & thr : l1menu.thresholds(thrType)) {
354 jThrType["names"] += thr->name();
355 }
356 auto & extInfo = l1menu.thrExtraInfo().thrExtraInfo("internal");
357 if(auto randoms = extInfo.getExtraInfo("randoms")) {
358 for(size_t rc=0; rc<4; ++rc) {
359 jThrType["randoms"]["RNDM" + std::to_string(rc)]["cut"] =
360 randoms->get().getAttribute<unsigned int>("RNDM" + std::to_string(rc)+".cut");
361 }
362 }
363 }
364
365 if(thrType == "MU") {
366 auto & muinfo = l1menu.thrExtraInfo().MU();
367 jThrType["exclusionLists"] = json::value_t::object;
368 for(auto & listName : muinfo.exclusionListNames()) {
369 jThrType["exclusionLists"][listName] = json::array_t({});
370 for(auto & x : muinfo.exclusionList(listName)) {
371 jThrType["exclusionLists"][listName] += json({ {"sectorName", x.first}, {"rois", x.second}});
372 }
373 }
374 for(auto & rpcPt : muinfo.knownRpcPtValues()) {
375 jThrType["roads"]["rpc"][std::to_string(rpcPt)] = muinfo.rpcIdxForPt(rpcPt);
376 }
377 for(auto & tgcPt : muinfo.knownTgcPtValues()) {
378 jThrType["roads"]["tgc"][std::to_string(tgcPt)] = muinfo.tgcIdxForPt(tgcPt);
379 }
380 }
381
382 if(thrType == "EM" && l1menu.run()>1) {
383 auto & eminfo = l1menu.thrExtraInfo().EM();
384 for(const std::string isoSet : { "EMIsoForEMthr", "HAIsoForEMthr" }) {
385 jThrType["isolation"][isoSet]["thrtype"] = isoSet;
386 jThrType["isolation"][isoSet]["Parametrization"] = json::array_t({});
387 for(size_t bit = 1; bit<=5; ++bit) {
388 auto & iso = eminfo.isolation(isoSet,bit);
389 json jIso({});
390 jIso["etamax"] = iso.etamax();
391 jIso["etamin"] = iso.etamin();
392 jIso["isobit"] = iso.isobit();
393 jIso["mincut"] = iso.mincut();
394 jIso["offset"] = iso.offset();
395 jIso["priority"] = iso.priority();
396 jIso["slope"] = iso.slope();
397 jIso["upperlimit"] = iso.upperlimit();
398 jThrType["isolation"][isoSet]["Parametrization"] += jIso;
399 }
400 }
401 }
402
403 if(thrType == "TAU" && l1menu.run()>1) {
404 auto & tauinfo = l1menu.thrExtraInfo().TAU();
405 const std::string isoSet{ "EMIsoForTAUthr" };
406 jThrType["isolation"][isoSet]["thrtype"] = isoSet;
407 jThrType["isolation"][isoSet]["Parametrization"] = json::array_t({});
408 for(size_t bit = 1; bit<=5; ++bit) {
409 auto & iso = tauinfo.isolation(isoSet,bit);
410 json jIso({});
411 jIso["etamax"] = iso.etamax();
412 jIso["etamin"] = iso.etamin();
413 jIso["isobit"] = iso.isobit();
414 jIso["mincut"] = iso.mincut();
415 jIso["offset"] = iso.offset();
416 jIso["priority"] = iso.priority();
417 jIso["slope"] = iso.slope();
418 jIso["upperlimit"] = iso.upperlimit();
419 jThrType["isolation"][isoSet]["Parametrization"] += jIso;
420 }
421 }
422
423 if(thrType == "JET") {
424 auto & jetinfo = l1menu.thrExtraInfo().JET();
425 jThrType["ptMinToTopoSmallWindow"] = (int)jetinfo.ptMinToTopoSmallWindow();
426 jThrType["ptMinToTopoLargeWindow"] = (int)jetinfo.ptMinToTopoLargeWindow();
427 }
428
429 if(thrType == "XS") {
430 auto & xsinfo = l1menu.thrExtraInfo().XS();
431 jThrType["significance"]["xeMin"] = xsinfo.xeMin();
432 jThrType["significance"]["xeMax"] = xsinfo.xeMax();
433 jThrType["significance"]["teSqrtMin"] = xsinfo.teSqrtMin();
434 jThrType["significance"]["teSqrtMax"] = xsinfo.teSqrtMax();
435 jThrType["significance"]["xsSigmaScale"] = xsinfo.xsSigmaScale();
436 jThrType["significance"]["xsSigmaOffset"] = xsinfo.xsSigmaOffset();
437 }
438
439 if(thrType == "eEM") {
440 auto & eeminfo = l1menu.thrExtraInfo().eEM();
441 jThrType["maxEt"] = (int)eeminfo.maxEt();
443 const auto & wpstr = TrigConf::Selection::wpToString(wp);
444 jThrType["workingPoints"][wpstr] = json::array_t({});
445 for(auto & iso : eeminfo.isolation(wp)) {
446 json jWPIso({});
447 std::stringstream stream;
448 stream << std::fixed << std::setprecision(3) << iso.value().reta_d();
449 jWPIso["reta"] = std::stod(stream.str());
450 jWPIso["reta_fw"] = iso.value().reta_fw();
451 stream.str("");
452 stream.clear();
453 stream << std::fixed << std::setprecision(3) << iso.value().rhad_d();
454 jWPIso["rhad"] = std::stod(stream.str());
455 jWPIso["rhad_fw"] = iso.value().rhad_fw();
456 stream.str("");
457 stream.clear();
458 stream << std::fixed << std::setprecision(3) << iso.value().wstot_d();
459 jWPIso["wstot"] = std::stod(stream.str());
460 jWPIso["wstot_fw"] = iso.value().wstot_fw();
461 jWPIso["etamin"] = iso.etaMin();
462 jWPIso["etamax"] = iso.etaMax();
463 jWPIso["priority"] = iso.priority();
464 jThrType["workingPoints"][wpstr] += jWPIso;
465 }
466 }
467 }
468
469 if(thrType == "jEM") {
470 auto & jeminfo = l1menu.thrExtraInfo().jEM();
471 jThrType["maxEt"] = (int)jeminfo.maxEt();
472 jThrType["ptMinToTopo1"] = (int)jeminfo.ptMinToTopo("1A");
473 jThrType["ptMinToTopo2"] = (int)jeminfo.ptMinToTopo("2A");
474 jThrType["ptMinToTopo3"] = (int)jeminfo.ptMinToTopo("3A");
475 jThrType["ptMinxTOB1"] = (int)jeminfo.ptMinxTOB("1A");
476 jThrType["ptMinxTOB2"] = (int)jeminfo.ptMinxTOB("2A");
477 jThrType["ptMinxTOB3"] = (int)jeminfo.ptMinxTOB("3A");
479 const auto & wpstr = TrigConf::Selection::wpToString(wp);
480 jThrType["workingPoints"][wpstr] = json::array_t({});
481 for(auto & iso : jeminfo.isolation(wp)) {
482 json jWPIso({});
483 std::stringstream stream;
484 stream << std::fixed << std::setprecision(3) << iso.value().iso_d();
485 jWPIso["iso"] = std::stod(stream.str());
486 jWPIso["iso_fw"] = iso.value().iso_fw();
487 stream.str("");
488 stream.clear();
489 stream << std::fixed << std::setprecision(3) << iso.value().frac_d();
490 jWPIso["frac"] = std::stod(stream.str());
491 jWPIso["frac_fw"] = iso.value().frac_fw();
492 stream.str("");
493 stream.clear();
494 stream << std::fixed << std::setprecision(3) << iso.value().frac2_d();
495 jWPIso["frac2"] = std::stod(stream.str());
496 jWPIso["frac2_fw"] = iso.value().frac2_fw();
497 jWPIso["etamin"] = iso.etaMin();
498 jWPIso["etamax"] = iso.etaMax();
499 jWPIso["priority"] = iso.priority();
500 jThrType["workingPoints"][wpstr] += jWPIso;
501 }
502 }
503 }
504
505 if(thrType == "eTAU") {
506 auto & eeminfo = l1menu.thrExtraInfo().eTAU();
507 jThrType["minIsoEt"] = (int)eeminfo.minIsoEt();
508 jThrType["maxEt"] = (int)eeminfo.maxEt();
509 jThrType["algoVersion"] = (int)eeminfo.algoVersion();
512 const auto & wpstr = TrigConf::Selection::wpToString(wp);
513 jThrType["workingPoints"][wpstr] = json::array_t({});
514 for(auto & iso : eeminfo.isolation(wp)) {
515 json jWPIso({});
516 std::stringstream stream;
517 stream << std::fixed << std::setprecision(3) << iso.value().rCore_d();
518 jWPIso["rCore"] = std::stod(stream.str());
519 jWPIso["rCore_fw"] = iso.value().rCore_fw();
520 stream.str("");
521 stream.clear();
522 stream << std::fixed << std::setprecision(3) << iso.value().rHad_d();
523 jWPIso["rHad"] = std::stod(stream.str());
524 jWPIso["rHad_fw"] = iso.value().rHad_fw();
525 jThrType["workingPoints"][wpstr] += jWPIso;
526 }
527 }
528 }
529
530 if(thrType == "jTAU") {
531 auto & jtauinfo = l1menu.thrExtraInfo().jTAU();
532 jThrType["maxEt"] = (int)jtauinfo.maxEt();
533 jThrType["ptMinToTopo1"] = (int)jtauinfo.ptMinToTopo("1A");
534 jThrType["ptMinToTopo2"] = (int)jtauinfo.ptMinToTopo("2A");
535 jThrType["ptMinToTopo3"] = (int)jtauinfo.ptMinToTopo("3A");
536 jThrType["ptMinxTOB1"] = (int)jtauinfo.ptMinxTOB("1A");
537 jThrType["ptMinxTOB2"] = (int)jtauinfo.ptMinxTOB("2A");
538 jThrType["ptMinxTOB3"] = (int)jtauinfo.ptMinxTOB("3A");
540 const auto & wpstr = TrigConf::Selection::wpToString(wp);
541 jThrType["workingPoints"][wpstr] = json::array_t({});
542 for(auto & iso : jtauinfo.isolation(wp)) {
543 json jWPIso({});
544 std::stringstream stream;
545 stream << std::fixed << std::setprecision(3) << iso.value().isolation_d();
546 jWPIso["isolation"] = std::stod(stream.str());
547 jWPIso["isolation_fw"] = iso.value().isolation_fw();
548 jThrType["workingPoints"][wpstr] += jWPIso;
549 }
550 }
551 }
552
553 if(thrType == "cTAU") {
554 auto & eeminfo = l1menu.thrExtraInfo().cTAU();
556 const auto & wpstr = TrigConf::Selection::wpToString(wp);
557 jThrType["workingPoints"][wpstr] = json::array_t({});
558 for(auto & iso : eeminfo.isolation(wp)) {
559 json jWPIso({});
560 std::stringstream stream;
561 stream << std::fixed << std::setprecision(3) << iso.value().isolation_d();
562 jWPIso["isolation"] = std::stod(stream.str());
563 jWPIso["isolation_fw"] = iso.value().isolation_fw();
564 stream.str("");
565 stream << std::fixed << std::setprecision(3) << iso.value().isolation_jTAUCoreScale_d();
566 jWPIso["isolation_jTAUCoreScale"] = std::stod(stream.str());
567 jWPIso["isolation_jTAUCoreScale_fw"] = iso.value().isolation_jTAUCoreScale_fw();
568 stream.str("");
569 stream << std::fixed << std::setprecision(3) << iso.value().eTAU_rCoreMin_WP_d();
570 jWPIso["eTAU_rCoreMin"] = std::stod(stream.str());
571 jWPIso["eTAU_rCoreMin_WP_fw"] = iso.value().eTAU_rCoreMin_WP_fw();
572 stream.str("");
573 stream << std::fixed << std::setprecision(3) << iso.value().eTAU_rHadMin_WP_d();
574 jWPIso["eTAU_rHadMin"] = std::stod(stream.str());
575 jWPIso["eTAU_rHadMin_WP_fw"] = iso.value().eTAU_rHadMin_WP_fw();
576 jThrType["workingPoints"][wpstr] += jWPIso;
577 }
578 }
579 }
580
581 if(thrType == "jJ") {
582 auto & jjinfo = l1menu.thrExtraInfo().jJ();
583 jThrType["ptMinToTopo1"] = (int)jjinfo.ptMinToTopo("1A");
584 jThrType["ptMinToTopo2"] = (int)jjinfo.ptMinToTopo("2A");
585 jThrType["ptMinToTopo3"] = (int)jjinfo.ptMinToTopo("3A");
586 jThrType["ptMinxTOB1"] = (int)jjinfo.ptMinxTOB("1A");
587 jThrType["ptMinxTOB2"] = (int)jjinfo.ptMinxTOB("2A");
588 jThrType["ptMinxTOB3"] = (int)jjinfo.ptMinxTOB("3A");
589 }
590
591 if(thrType == "jLJ") {
592 auto & jljinfo = l1menu.thrExtraInfo().jLJ();
593 jThrType["ptMinToTopo1"] = (int)jljinfo.ptMinToTopo("1A");
594 jThrType["ptMinToTopo2"] = (int)jljinfo.ptMinToTopo("2A");
595 jThrType["ptMinToTopo3"] = (int)jljinfo.ptMinToTopo("3A");
596 jThrType["ptMinxTOB1"] = (int)jljinfo.ptMinxTOB("1A");
597 jThrType["ptMinxTOB2"] = (int)jljinfo.ptMinxTOB("2A");
598 jThrType["ptMinxTOB3"] = (int)jljinfo.ptMinxTOB("3A");
599 }
600
601 if(thrType == "gJ") {
602 auto & gjinfo = l1menu.thrExtraInfo().gJ();
603 jThrType["ptMinToTopo1"] = (int)gjinfo.ptMinToTopo(1);
604 jThrType["ptMinToTopo2"] = (int)gjinfo.ptMinToTopo(2);
605 }
606
607 if(thrType == "gLJ") {
608 auto & gljinfo = l1menu.thrExtraInfo().gLJ();
609 jThrType["ptMinToTopo1"] = (int)gljinfo.ptMinToTopo(1);
610 jThrType["ptMinToTopo2"] = (int)gljinfo.ptMinToTopo(2);
611 jThrType["seedThrA"] = (int)gljinfo.seedThr('A');
612 jThrType["seedThrB"] = (int)gljinfo.seedThr('B');
613 jThrType["seedThrC"] = (int)gljinfo.seedThr('C');
614 std::stringstream stream;
615 stream << std::fixed << std::setprecision(3) << gljinfo.rhoTowerMin('A');
616 jThrType["rhoTowerMinA"] = std::stod(stream.str());
617 stream.str("");
618 stream.clear();
619 stream << std::fixed << std::setprecision(3) << gljinfo.rhoTowerMin('B');
620 jThrType["rhoTowerMinB"] = std::stod(stream.str());
621 stream.str("");
622 stream.clear();
623 stream << std::fixed << std::setprecision(3) << gljinfo.rhoTowerMin('C');
624 jThrType["rhoTowerMinC"] = std::stod(stream.str());
625 stream.str("");
626 stream.clear();
627 stream << std::fixed << std::setprecision(3) << gljinfo.rhoTowerMax('A');
628 jThrType["rhoTowerMaxA"] = std::stod(stream.str());
629 stream.str("");
630 stream.clear();
631 stream << std::fixed << std::setprecision(3) << gljinfo.rhoTowerMax('B');
632 jThrType["rhoTowerMaxB"] = std::stod(stream.str());
633 stream.str("");
634 stream.clear();
635 stream << std::fixed << std::setprecision(3) << gljinfo.rhoTowerMax('C');
636 jThrType["rhoTowerMaxC"] = std::stod(stream.str());
637 }
638
639 if(thrType == "jXE") {
640 // nothing to do for now...
641 }
642
643 if(thrType == "jTE") {
644 auto & ei = l1menu.thrExtraInfo().jTE();
645 jThrType["etaBoundary1"] = ei.etaBoundary("1A");
646 jThrType["etaBoundary1_fw"] = ei.etaBoundary_fw("1A");
647 jThrType["etaBoundary2"] = ei.etaBoundary("2A");
648 jThrType["etaBoundary2_fw"] = ei.etaBoundary_fw("2A");
649 jThrType["etaBoundary3"] = ei.etaBoundary("3A");
650 jThrType["etaBoundary3_fw"] = ei.etaBoundary_fw("3A");
651 }
652
653 if(thrType == "gXE") {
654 auto & ei = l1menu.thrExtraInfo().gXE();
655 jThrType["seedThrA"] = (int)ei.seedThr('A');
656 jThrType["seedThrB"] = (int)ei.seedThr('B');
657 jThrType["seedThrC"] = (int)ei.seedThr('C');
658 jThrType["XERHO_sigmaPosA"] = ei.XERHO_param('A',true);
659 jThrType["XERHO_sigmaPosB"] = ei.XERHO_param('B',true);
660 jThrType["XERHO_sigmaPosC"] = ei.XERHO_param('C',true);
661 jThrType["XERHO_sigmaNegA"] = ei.XERHO_param('A',false);
662 jThrType["XERHO_sigmaNegB"] = ei.XERHO_param('B',false);
663 jThrType["XERHO_sigmaNegC"] = ei.XERHO_param('C',false);
664 jThrType["XEJWOJ_a_A"] = ei.JWOJ_param('A','a');
665 jThrType["XEJWOJ_a_B"] = ei.JWOJ_param('B','a');
666 jThrType["XEJWOJ_a_C"] = ei.JWOJ_param('C','a');
667 jThrType["XEJWOJ_b_A"] = ei.JWOJ_param('A','b');
668 jThrType["XEJWOJ_b_B"] = ei.JWOJ_param('B','b');
669 jThrType["XEJWOJ_b_C"] = ei.JWOJ_param('C','b');
670 jThrType["XEJWOJ_c_A"] = ei.JWOJ_param('A','c');
671 jThrType["XEJWOJ_c_B"] = ei.JWOJ_param('B','c');
672 jThrType["XEJWOJ_c_C"] = ei.JWOJ_param('C','c');
673 jThrType["XENOISECUT_noiseCutThrA"] = ei.noiseCutThr('A');
674 jThrType["XENOISECUT_noiseCutThrB"] = ei.noiseCutThr('B');
675 jThrType["XENOISECUT_noiseCutThrC"] = ei.noiseCutThr('C');
676 }
677
678 if(thrType == "gTE") {
679 // nothing to do for now...
680 }
681
682 std::vector<std::string> legacyCalo = {"EM", "JET", "TAU", "XE", "TE", "XS", "ZB", "JB", "JF", "JE", "R2TOPO"};
683 if( std::any_of(begin(legacyCalo), end(legacyCalo), [&thrType](const std::string &c) { return c==thrType; }) ) {
684 thresholds["legacyCalo"][thrType] = std::move(jThrType);
685 } else {
686 thresholds[thrType] = std::move(jThrType);
687 }
688 };
689
690 json boards = json::object_t{};
691 for( auto & bname : l1menu.boardNames() ) {
692 auto & bdef = l1menu.board(bname);
693 boards[bname] = json{ {"connectors", bdef.connectorNames()}, {"type", bdef.type()} };
694 if(bdef.legacy())
695 boards[bname]["legacy"] = true;
696 };
697
698 json connectors = json::object_t{};
699 for( auto & cname : l1menu.connectorNames() ) {
700 auto jConn = json{};
701 auto & cdef = l1menu.connector(cname);
702 jConn["type"] = cdef.type();
703 if(cdef.legacy())
704 jConn["legacy"] = true;
705 jConn["triggerlines"] = json::array_t();
706 if(cdef.maxClock() == 2){
707 if(cdef.maxFpga() == 2){
708 // legacy topo, TOPO2, TOPO3 and muctpi
709 for(size_t fpga = 0; fpga<cdef.maxFpga(); ++fpga) {
710 for(size_t clock = 0; clock<cdef.maxClock(); ++clock) {
711 for(auto & tl : cdef.triggerLines(fpga, clock)) {
712 jConn["triggerlines"] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()}, {"flatindex", tl.flatindex()}, {"fpga", tl.fpga()}, {"clock", tl.clock()}, });
713 }
714 }
715 }
716 } else {
717 // AlfaCpti and merger board
718 for(size_t fpga = 0; fpga<cdef.maxFpga(); ++fpga) {
719 for(size_t clock = 0; clock<cdef.maxClock(); ++clock) {
720 for(auto & tl : cdef.triggerLines(fpga, clock)) {
721 jConn["triggerlines"] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()}, {"flatindex", tl.flatindex()}, {"clock", tl.clock()}, });
722 }
723 }
724 }
725 }
726 } else {
727 for(auto & tl : cdef.triggerLines()) {
728 jConn["triggerlines"] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()}, {"flatindex", tl.flatindex()} });
729 }
730 }
731 connectors[cname] = std::move(jConn);
732 }
733
734 json ctp = json::object_t{};
735 {
736 for(size_t slot=7; slot<=9; ++slot) {
737 std::string sName = "slot" + std::to_string(slot);
738 ctp["inputs"]["ctpin"][sName] = json({});
739 for(size_t conn=0; conn<=3; ++conn) {
740 ctp["inputs"]["ctpin"][sName]["connector" + std::to_string(conn)] = l1menu.ctp().ctpin(slot,conn);
741 }
742 }
743 ctp["inputs"]["electrical"] = json::object_t{};
744 for(size_t conn=0; conn<3; ++conn) {
745 if(l1menu.ctp().electrical(conn)=="")
746 continue;
747 ctp["inputs"]["electrical"]["connector" + std::to_string(conn)] = l1menu.ctp().electrical(conn);
748 }
749 ctp["inputs"]["optical"] = json::object_t{};
750 for(size_t conn=0; conn<12; ++conn) {
751 if(l1menu.ctp().optical(conn)=="")
752 continue;
753 ctp["inputs"]["optical"]["connector" + std::to_string(conn)] = l1menu.ctp().optical(conn);
754 }
755 json ctpmon = json::object_t{};
756 for(auto & mon : l1menu.ctp().ctpMon()) {
757 ctpmon[mon.first] = json({{"multiplicity",mon.second.first},{"thr",mon.second.second}});
758 }
759 json ctpin = json::object_t{};
760 for(auto & mon : l1menu.ctp().ctpinMon()) {
761 ctpin[mon.first] = json({{"multiplicity", mon.second.first},{"thr", mon.second.second}});
762 }
763 ctp["monitoring"] = json({{"ctpmon", ctpmon}, {"ctpin", ctpin}});
764 }
765
766 json jtopo = json::object_t{};
767 if(l1menu.run()>1) {
768 std::map<L1TopoAlgorithm::AlgorithmType,std::string> algTypeNames = {
769 {L1TopoAlgorithm::AlgorithmType::SORTING, "sortingAlgorithms"},
770 {L1TopoAlgorithm::AlgorithmType::DECISION, "decisionAlgorithms"},
771 {L1TopoAlgorithm::AlgorithmType::MULTIPLICITY, "multiplicityAlgorithms"}
772 };
773 auto topoCategories = l1menu.isRun2() ? std::vector<std::string> {"R2TOPO"} : std::vector<std::string> {"TOPO", "MUTOPO", "MULTTOPO", "R2TOPO"};
774 for( const std::string& topoCat : topoCategories ) {
775 for(auto & algName : l1menu.topoAlgorithmNames(topoCat)) {
776 json jalg = json::object_t({});
777 auto & alg = l1menu.algorithm(algName,topoCat);
778 jalg["klass"] = alg.klass();
779 // input
781 if(alg.inputs().size()>0) {
782 jalg["input"] = alg.inputs()[0];
783 } else {
784 jalg["input"] = nullptr;
785 }
786 } else if(alg.type()==L1TopoAlgorithm::AlgorithmType::SORTING) {
787 jalg["input"] = alg.inputs()[0];
788 } else {
789 jalg["input"] = alg.inputs();
790 }
791 // output
792 if( alg.type() == L1TopoAlgorithm::AlgorithmType::DECISION ) {
793 jalg["output"] = alg.outputs();
794 } else {
795 jalg["output"] = alg.outputs()[0];
796 }
797 // generic parameters
798 if(topoCat == "MULTTOPO") {
799 jalg["nbits"] = alg.getAttribute<unsigned int>("nbits");
800 jalg["threshold"] = alg.getAttribute("threshold");
801 if(alg.klass()=="EnergyThreshold"){
802 for(const L1TopoAlgorithm::VariableParameter & vpar : alg.parameters()) {
803 if(vpar.name()=="flavour") jalg["flavour"] = XEFlavour::flavourIntToStr(vpar.value());
804 }
805 }
806 } else {
807 const auto & ds = alg.generics();
808 for(const auto & gpname : ds.getKeys()) {
809 auto gp = ds.getObject(gpname);
810 {
811 if(gp.hasAttribute("position")) {
812 jalg["fixedParameters"]["generics"][gpname]["position"] = gp.getAttribute<unsigned int>("position");
813 }
814 std::string pval = alg.genericParameter(gpname);
815 try{
816 int pvali = std::stoi(pval);
817 jalg["fixedParameters"]["generics"][gpname]["value"] = pvali;
818 } catch(std::invalid_argument &) {
819 jalg["fixedParameters"]["generics"][gpname]["value"] = pval;
820 }
821 }
822 }
823 }
824 // variable parameters
825 if(topoCat != "MULTTOPO") {
826 jalg["variableParameters"] = json::array_t({});
827 for(const L1TopoAlgorithm::VariableParameter & vpar : alg.parameters()) {
828 json jVPar({});
829 jVPar["name"] = vpar.name();
830 jVPar["value"] = vpar.value();
831 if(auto sel = vpar.selection_optional()) { jVPar["selection"] = *sel; }
832 jalg["variableParameters"] += jVPar;
833 }
834 }
835 jtopo[topoCat][algTypeNames[alg.type()]][algName] = std::move(jalg);
836 }
837 }
838 }
839
840 json j = json::object_t{};
841 j["filetype"] = "l1menu";
842 j["run"] = l1menu.run();
843 j["name"] = l1menu.name();
844 j["items"] = std::move(items);
845 j["thresholds"] = std::move(thresholds);
846 j["topoAlgorithms"] = std::move(jtopo);
847 j["boards"] = std::move(boards);
848 j["connectors"] = std::move(connectors);
849 j["ctp"] = std::move(ctp);
850
851 std::ofstream outfile(filename);
852 outfile << std::setw(4) << j << std::endl;
853
854 TRG_MSG_INFO("Saved file " << filename);
855 return true;
856}
857
858
859bool
860TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const TrigConf::L1BunchGroupSet & l1bgs) const {
861
862 json j;
863 j["filetype"] = "bunchgroupset";
864 j["name"] = l1bgs.name();
865
866 json groups;
867 for (size_t i = 0 ; i< l1bgs.size(); ++i) {
868 const auto & group = l1bgs.getBunchGroup(i);
869 json jgroup({});
870 jgroup["name"] = group->name();
871 jgroup["id"] = group->id();
872 jgroup["info"] = std::to_string(group->size()) + " bunches, " + std::to_string(group->nGroups()) + " groups";
873 json trains = json::array();
874 for (auto [first, len]: group->trains()) {
875 json train({});
876 train["first"] = first;
877 train["length"] = len;
878 trains.push_back(train);
879 }
880 jgroup["bcids"] = std::move(trains);
881 groups["BGRP"+std::to_string(group->id())] = std::move(jgroup);
882 }
883 j["bunchGroups"] = std::move(groups);
884 std::ofstream outfile(filename);
885 outfile << std::setw(4) << j << std::endl;
886 TRG_MSG_INFO("Saved file " << filename);
887 return true;
888}
889
890bool TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const TrigConf::L1PrescalesSet & l1ps) const {
891 json j;
892 j["filetype"] = "l1prescale";
893 j["name"] = l1ps.name();
894 json cuts;
895 for ( const auto & [itemName, ps]: l1ps.prescales()){
896 json cut;
897 cut["cut"] = ps.cut;
898 cut["enabled"] = ps.enabled;
899 cut["info"] = "prescale: " + std::to_string(ps.prescale);
900 cuts[itemName] = std::move(cut);
901 }
902 j["cutValues"] = std::move(cuts);
903 std::ofstream outfile(filename);
904 outfile << std::setw(4) << j << std::endl;
905 TRG_MSG_INFO("Saved file " << filename);
906 return true;
907}
nlohmann::json json
static Double_t rc
#define x
virtual const std::string & name() const final
bool writeJsonFile(const std::string &filename, const L1Menu &l1menu) const
L1 board configuration.
std::size_t size() const
Accessor to the number of defined bunchgroups.
const std::shared_ptr< L1BunchGroup > & getBunchGroup(const std::string &name) const
Accessor to the bunchgroup by name.
L1 menu configuration.
Definition L1Menu.h:28
L1 menu configuration.
const std::map< std::string, L1Prescale > & prescales() const
unsigned int ptBarrel() const
uint16_t isolationMask() const
Definition L1Threshold.h:44
const unsigned int & mask0() const
const std::string & seed() const
static std::string wpToString(WP)
TrigConfMessaging(const std::string &name)
Constructor with parameters.
static std::string flavourIntToStr(const unsigned int flavInt)
STL namespace.