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 }
674
675 if(thrType == "gTE") {
676 // nothing to do for now...
677 }
678
679 std::vector<std::string> legacyCalo = {"EM", "JET", "TAU", "XE", "TE", "XS", "ZB", "JB", "JF", "JE", "R2TOPO"};
680 if( std::any_of(begin(legacyCalo), end(legacyCalo), [&thrType](const std::string &c) { return c==thrType; }) ) {
681 thresholds["legacyCalo"][thrType] = std::move(jThrType);
682 } else {
683 thresholds[thrType] = std::move(jThrType);
684 }
685 };
686
687 json boards = json::object_t{};
688 for( auto & bname : l1menu.boardNames() ) {
689 auto & bdef = l1menu.board(bname);
690 boards[bname] = json{ {"connectors", bdef.connectorNames()}, {"type", bdef.type()} };
691 if(bdef.legacy())
692 boards[bname]["legacy"] = true;
693 };
694
695 json connectors = json::object_t{};
696 for( auto & cname : l1menu.connectorNames() ) {
697 auto jConn = json{};
698 auto & cdef = l1menu.connector(cname);
699 jConn["type"] = cdef.type();
700 if(cdef.legacy())
701 jConn["legacy"] = true;
702 jConn["triggerlines"] = json::array_t();
703 if(cdef.maxClock() == 2){
704 if(cdef.maxFpga() == 2){
705 // legacy topo, TOPO2, TOPO3 and muctpi
706 for(size_t fpga = 0; fpga<cdef.maxFpga(); ++fpga) {
707 for(size_t clock = 0; clock<cdef.maxClock(); ++clock) {
708 for(auto & tl : cdef.triggerLines(fpga, clock)) {
709 jConn["triggerlines"] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()}, {"flatindex", tl.flatindex()}, {"fpga", tl.fpga()}, {"clock", tl.clock()}, });
710 }
711 }
712 }
713 } else {
714 // AlfaCpti and merger board
715 for(size_t fpga = 0; fpga<cdef.maxFpga(); ++fpga) {
716 for(size_t clock = 0; clock<cdef.maxClock(); ++clock) {
717 for(auto & tl : cdef.triggerLines(fpga, clock)) {
718 jConn["triggerlines"] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()}, {"flatindex", tl.flatindex()}, {"clock", tl.clock()}, });
719 }
720 }
721 }
722 }
723 } else {
724 for(auto & tl : cdef.triggerLines()) {
725 jConn["triggerlines"] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()}, {"flatindex", tl.flatindex()} });
726 }
727 }
728 connectors[cname] = std::move(jConn);
729 }
730
731 json ctp = json::object_t{};
732 {
733 for(size_t slot=7; slot<=9; ++slot) {
734 std::string sName = "slot" + std::to_string(slot);
735 ctp["inputs"]["ctpin"][sName] = json({});
736 for(size_t conn=0; conn<=3; ++conn) {
737 ctp["inputs"]["ctpin"][sName]["connector" + std::to_string(conn)] = l1menu.ctp().ctpin(slot,conn);
738 }
739 }
740 ctp["inputs"]["electrical"] = json::object_t{};
741 for(size_t conn=0; conn<3; ++conn) {
742 if(l1menu.ctp().electrical(conn)=="")
743 continue;
744 ctp["inputs"]["electrical"]["connector" + std::to_string(conn)] = l1menu.ctp().electrical(conn);
745 }
746 ctp["inputs"]["optical"] = json::object_t{};
747 for(size_t conn=0; conn<12; ++conn) {
748 if(l1menu.ctp().optical(conn)=="")
749 continue;
750 ctp["inputs"]["optical"]["connector" + std::to_string(conn)] = l1menu.ctp().optical(conn);
751 }
752 json ctpmon = json::object_t{};
753 for(auto & mon : l1menu.ctp().ctpMon()) {
754 ctpmon[mon.first] = json({{"multiplicity",mon.second.first},{"thr",mon.second.second}});
755 }
756 json ctpin = json::object_t{};
757 for(auto & mon : l1menu.ctp().ctpinMon()) {
758 ctpin[mon.first] = json({{"multiplicity", mon.second.first},{"thr", mon.second.second}});
759 }
760 ctp["monitoring"] = json({{"ctpmon", ctpmon}, {"ctpin", ctpin}});
761 }
762
763 json jtopo = json::object_t{};
764 if(l1menu.run()>1) {
765 std::map<L1TopoAlgorithm::AlgorithmType,std::string> algTypeNames = {
766 {L1TopoAlgorithm::AlgorithmType::SORTING, "sortingAlgorithms"},
767 {L1TopoAlgorithm::AlgorithmType::DECISION, "decisionAlgorithms"},
768 {L1TopoAlgorithm::AlgorithmType::MULTIPLICITY, "multiplicityAlgorithms"}
769 };
770 auto topoCategories = l1menu.isRun2() ? std::vector<std::string> {"R2TOPO"} : std::vector<std::string> {"TOPO", "MUTOPO", "MULTTOPO", "R2TOPO"};
771 for( const std::string& topoCat : topoCategories ) {
772 for(auto & algName : l1menu.topoAlgorithmNames(topoCat)) {
773 json jalg = json::object_t({});
774 auto & alg = l1menu.algorithm(algName,topoCat);
775 jalg["klass"] = alg.klass();
776 // input
778 if(alg.inputs().size()>0) {
779 jalg["input"] = alg.inputs()[0];
780 } else {
781 jalg["input"] = nullptr;
782 }
783 } else if(alg.type()==L1TopoAlgorithm::AlgorithmType::SORTING) {
784 jalg["input"] = alg.inputs()[0];
785 } else {
786 jalg["input"] = alg.inputs();
787 }
788 // output
789 if( alg.type() == L1TopoAlgorithm::AlgorithmType::DECISION ) {
790 jalg["output"] = alg.outputs();
791 } else {
792 jalg["output"] = alg.outputs()[0];
793 }
794 // generic parameters
795 if(topoCat == "MULTTOPO") {
796 jalg["nbits"] = alg.getAttribute<unsigned int>("nbits");
797 jalg["threshold"] = alg.getAttribute("threshold");
798 if(alg.klass()=="EnergyThreshold"){
799 for(const L1TopoAlgorithm::VariableParameter & vpar : alg.parameters()) {
800 if(vpar.name()=="flavour") jalg["flavour"] = XEFlavour::flavourIntToStr(vpar.value());
801 }
802 }
803 } else {
804 const auto & ds = alg.generics();
805 for(const auto & gpname : ds.getKeys()) {
806 auto gp = ds.getObject(gpname);
807 {
808 if(gp.hasAttribute("position")) {
809 jalg["fixedParameters"]["generics"][gpname]["position"] = gp.getAttribute<unsigned int>("position");
810 }
811 std::string pval = alg.genericParameter(gpname);
812 try{
813 int pvali = std::stoi(pval);
814 jalg["fixedParameters"]["generics"][gpname]["value"] = pvali;
815 } catch(std::invalid_argument &) {
816 jalg["fixedParameters"]["generics"][gpname]["value"] = pval;
817 }
818 }
819 }
820 }
821 // variable parameters
822 if(topoCat != "MULTTOPO") {
823 jalg["variableParameters"] = json::array_t({});
824 for(const L1TopoAlgorithm::VariableParameter & vpar : alg.parameters()) {
825 json jVPar({});
826 jVPar["name"] = vpar.name();
827 jVPar["value"] = vpar.value();
828 if(auto sel = vpar.selection_optional()) { jVPar["selection"] = *sel; }
829 jalg["variableParameters"] += jVPar;
830 }
831 }
832 jtopo[topoCat][algTypeNames[alg.type()]][algName] = std::move(jalg);
833 }
834 }
835 }
836
837 json j = json::object_t{};
838 j["filetype"] = "l1menu";
839 j["run"] = l1menu.run();
840 j["name"] = l1menu.name();
841 j["items"] = std::move(items);
842 j["thresholds"] = std::move(thresholds);
843 j["topoAlgorithms"] = std::move(jtopo);
844 j["boards"] = std::move(boards);
845 j["connectors"] = std::move(connectors);
846 j["ctp"] = std::move(ctp);
847
848 std::ofstream outfile(filename);
849 outfile << std::setw(4) << j << std::endl;
850
851 TRG_MSG_INFO("Saved file " << filename);
852 return true;
853}
854
855
856bool
857TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const TrigConf::L1BunchGroupSet & l1bgs) const {
858
859 json j;
860 j["filetype"] = "bunchgroupset";
861 j["name"] = l1bgs.name();
862
863 json groups;
864 for (size_t i = 0 ; i< l1bgs.size(); ++i) {
865 const auto & group = l1bgs.getBunchGroup(i);
866 json jgroup({});
867 jgroup["name"] = group->name();
868 jgroup["id"] = group->id();
869 jgroup["info"] = std::to_string(group->size()) + " bunches, " + std::to_string(group->nGroups()) + " groups";
870 json trains = json::array();
871 for (auto [first, len]: group->trains()) {
872 json train({});
873 train["first"] = first;
874 train["length"] = len;
875 trains.push_back(train);
876 }
877 jgroup["bcids"] = std::move(trains);
878 groups["BGRP"+std::to_string(group->id())] = std::move(jgroup);
879 }
880 j["bunchGroups"] = std::move(groups);
881 std::ofstream outfile(filename);
882 outfile << std::setw(4) << j << std::endl;
883 TRG_MSG_INFO("Saved file " << filename);
884 return true;
885}
886
887bool TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const TrigConf::L1PrescalesSet & l1ps) const {
888 json j;
889 j["filetype"] = "l1prescale";
890 j["name"] = l1ps.name();
891 json cuts;
892 for ( const auto & [itemName, ps]: l1ps.prescales()){
893 json cut;
894 cut["cut"] = ps.cut;
895 cut["enabled"] = ps.enabled;
896 cut["info"] = "prescale: " + std::to_string(ps.prescale);
897 cuts[itemName] = std::move(cut);
898 }
899 j["cutValues"] = std::move(cuts);
900 std::ofstream outfile(filename);
901 outfile << std::setw(4) << j << std::endl;
902 TRG_MSG_INFO("Saved file " << filename);
903 return true;
904}
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.