89 const std::string& filename,
bool writeTmpFile)
93 std::cout <<
"No CTPConfig, no L1Menu file will be produced" << std::endl;
100 json items = json::object_t{};
103 item[
"name"] = sourceItem->name();
104 item[
"legacy"] =
true;
105 item[
"ctpid"] = sourceItem->ctpId();
106 auto [definition, bunchgroups] = decodeItemDefinition(sourceItem);
107 item[
"definition"] = definition;
108 item[
"bunchgroups"] = bunchgroups;
110 item[
"partition"] = sourceItem->partition();
111 std::string smon(
"LF:");
112 smon += (sourceItem->monitor() & 0x04 ?
'1' :
'0');
113 smon += (sourceItem->monitor() & 0x02 ?
'1' :
'0');
114 smon += (sourceItem->monitor() & 0x01 ?
'1' :
'0');
116 smon += (sourceItem->monitor() & 0x20 ?
'1' :
'0');
117 smon += (sourceItem->monitor() & 0x10 ?
'1' :
'0');
118 smon += (sourceItem->monitor() & 0x08 ?
'1' :
'0');
119 item[
"monitor"] = smon;
120 items[sourceItem->name()] = item;
124 json thresholds = json::object_t{};
125 std::unordered_set<std::string> legacyThrTypes{
"EM",
"TAU",
"JET",
"JB",
"JE",
"JF",
"XE",
"XS",
"TE",
"ZB",
"R2TOPO"};
127 std::string thrType = sourceThr->type();
128 if(thrType==
"BGRP" || thrType==
"RNDM") {
131 if(thrType==
"MUON") {
134 else if(thrType==
"TOPO") {
138 bool isLegacyCalo = legacyThrTypes.count(thrType) > 0;
139 json &jThisType = isLegacyCalo ? thresholds[
"legacyCalo"][thrType] : thresholds[thrType];
140 bool firstOfItsType = jThisType.empty();
143 jThisType[
"type"] = thrType;
146 size_t mapping = sourceThr->mapping();
147 thr[
"mapping"] = mapping;
151 jThisType[
"type"] =
"MU";
152 jThisType[
"exclusionLists"] = json::object_t{};
153 jThisType[
"roads"][
"rpc"] = json::object_t{};
154 jThisType[
"roads"][
"tgc"] = json::object_t{};
156 int ptCut = sourceThr->triggerThresholdValue(0,0)->ptCutCount();
157 thr[
"baThr"] = ptCut;
158 thr[
"ecThr"] = ptCut;
159 thr[
"fwThr"] = ptCut;
160 thr[
"baIdx"] = mapping;
161 thr[
"ecIdx"] = mapping;
162 thr[
"fwIdx"] = mapping;
163 thr[
"tgcFlags"] =
"";
164 thr[
"rpcFlags"] =
"";
165 thr[
"region"] =
"ALL";
166 jThisType[
"roads"][
"rpc"][std::to_string(ptCut)] = mapping;
167 jThisType[
"roads"][
"tgc"][std::to_string(ptCut)] = mapping;
169 else if (thrType ==
"EM")
171 thr[
"thrValues"] = json::array_t{};
175 if (not cl)
continue;
177 jtv[
"value"] =
static_cast<unsigned int>(tv->ptcut());
178 std::string isobits =
"00000";
179 auto isomask = cl->isolationMask();
180 for (
size_t b = 0; b < 5; ++b)
182 if (isomask & (1 << b))
184 isobits[4 - b] =
'1';
187 jtv[
"isobits"] = isobits;
188 jtv[
"etamin"] = tv->etamin();
189 jtv[
"etamax"] = tv->etamax();
190 jtv[
"phimin"] = tv->phimin();
191 jtv[
"phimax"] = tv->phimax();
192 jtv[
"priority"] =
static_cast<unsigned int>(tv->priority());
193 thr[
"thrValues"] += jtv;
196 else if (thrType ==
"TAU")
199 if (not cl)
continue;
200 int ptCut = (int)cl->ptcut();
201 thr[
"value"] = ptCut;
202 std::string isobits =
"00000";
203 auto isomask = cl->isolationMask();
204 for (
size_t b = 0; b < 5; ++b)
206 if (isomask & (1 << b))
208 isobits[4 - b] =
'1';
211 thr[
"isobits"] = isobits;
213 else if (thrType ==
"JET" || thrType ==
"JB" || thrType ==
"JF")
215 thr[
"thrValues"] = json::array_t{};
219 if (not jetThrVal)
continue;
221 jtv[
"value"] =
static_cast<unsigned int>(tv->ptcut());
222 jtv[
"etamin"] = tv->etamin();
223 jtv[
"etamax"] = tv->etamax();
224 jtv[
"phimin"] = tv->phimin();
225 jtv[
"phimax"] = tv->phimax();
227 jtv[
"priority"] =
static_cast<unsigned int>(tv->priority());
228 thr[
"thrValues"] += jtv;
231 else if (thrType ==
"XE" || thrType ==
"TE" || thrType ==
"XS" || thrType ==
"JE")
233 thr[
"value"] =
static_cast<unsigned int>(sourceThr->thresholdValueVector().at(0)->ptcut());
235 else if (thrType ==
"ZB")
237 thr[
"seed"] = sourceThr->zbSeedingThresholdName();
238 thr[
"seedMultiplicity"] = sourceThr->zbSeedingThresholdMulti();
239 thr[
"seedBcdelay"] = sourceThr->bcDelay();
241 jThisType[
"thresholds"][sourceThr->name()] = thr;
246 thresholds[
"legacyCalo"][
"EM"][
"ptMinToTopo"] = ci.
minTobEM().
ptmin;
247 thresholds[
"legacyCalo"][
"EM"][
"resolutionMeV"] = (int)(1000/ci.
globalEmScale());
248 thresholds[
"legacyCalo"][
"TAU"][
"ptMinToTopo"] = ci.
minTobTau().
ptmin;
252 json isoHAforEM{ {
"thrtype",
"HAIsoForEMthr"}, {
"Parametrization", json::array_t{}} };
253 json isoEMforEM{ {
"thrtype",
"EMIsoForEMthr"}, {
"Parametrization", json::array_t{}} };
254 json isoEMforTAU{ {
"thrtype",
"EMIsoForTAUthr"}, {
"Parametrization", json::array_t{}} };
256 json p{ {
"etamax", iso.etamax()}, {
"etamin", iso.etamin()}, {
"isobit", iso.isobit()}, {
"mincut", iso.mincut()},
257 {
"offset", iso.offset()}, {
"priority", iso.priority()}, {
"slope", iso.slope()}, {
"upperlimit", iso.upperlimit()} };
258 isoHAforEM[
"Parametrization"] += p;
261 json p{ {
"etamax", iso.etamax()}, {
"etamin", iso.etamin()}, {
"isobit", iso.isobit()}, {
"mincut", iso.mincut()},
262 {
"offset", iso.offset()}, {
"priority", iso.priority()}, {
"slope", iso.slope()}, {
"upperlimit", iso.upperlimit()} };
263 isoEMforEM[
"Parametrization"] += p;
266 json p{ {
"etamax", iso.etamax()}, {
"etamin", iso.etamin()}, {
"isobit", iso.isobit()}, {
"mincut", iso.mincut()},
267 {
"offset", iso.offset()}, {
"priority", iso.priority()}, {
"slope", iso.slope()}, {
"upperlimit", iso.upperlimit()} };
268 isoEMforTAU[
"Parametrization"] += p;
270 thresholds[
"legacyCalo"][
"EM"][
"isolation"][
"HAIsoForEMthr"] = std::move(isoHAforEM);
271 thresholds[
"legacyCalo"][
"EM"][
"isolation"][
"EMIsoForEMthr"] = std::move(isoEMforEM);
272 thresholds[
"legacyCalo"][
"TAU"][
"isolation"][
"EMIsoForTAUthr"] = std::move(isoEMforTAU);
275 thresholds[
"legacyCalo"][
"XS"][
"significance"] = json::object_t{
276 {
"xsSigmaScale", xs.
xsSigmaScale()}, {
"xsSigmaOffset", xs.
xsSigmaOffset()}, {
"xeMin", xs.
xeMin()}, {
"xeMax", xs.
xeMax()}, {
"teSqrtMin", xs.
teSqrtMin()}, {
"teSqrtMax", xs.
teSqrtMax()}};
279 json boards = json::object_t{};
280 boards[
"Ctpin7"] = json::object_t{ {
"type",
"CTPIN"}, {
"legacy",
true},
281 {
"connectors", std::vector<std::string>{
"EM1",
"EM2",
"TAU1",
"TAU2"}} };
282 boards[
"Ctpin8"] = json::object_t{ {
"type",
"CTPIN"}, {
"legacy",
true},
283 {
"connectors", std::vector<std::string>{
"JET1",
"JET2",
"EN1",
"EN2"}} };
284 boards[
"Ctpin9"] = json::object_t{ {
"type",
"CTPIN"}, {
"legacy",
true},
285 {
"connectors", std::vector<std::string>{
"MUCTPI",
"CTPCAL",
"NIM1",
"NIM2"}} };
286 boards[
"LegacyTopo0"] = json::object_t{ {
"type",
"TOPO"}, {
"legacy",
true},
287 {
"connectors", std::vector<std::string>{
"LegacyTopo0"}} };
288 boards[
"LegacyTopo1"] = json::object_t{ {
"type",
"TOPO"}, {
"legacy",
true},
289 {
"connectors", std::vector<std::string>{
"LegacyTopo1"}} };
292 json connectors = json::object_t{};
293 std::map<std::string,std::vector<const TrigConf::TriggerThreshold*>> triggerlinesMap;
295 if(sourceThr->isInternal()) {
298 std::string cableName = sourceThr->cableName();
299 if(cableName==
"ALFA") {
300 cableName =
"AlfaCtpin";
302 else if(cableName==
"TOPO1") {
303 cableName =
"LegacyTopo0";
305 else if(cableName==
"TOPO2") {
306 cableName =
"LegacyTopo1";
308 triggerlinesMap[cableName].push_back(sourceThr);
310 for(
auto & [
type, triggerlines] : triggerlinesMap) {
311 std::sort(std::begin(triggerlines), std::end(triggerlines),
314 if(!connectors.contains(
type)) {
315 if(thr->input()==
"ctpcore") {
316 connectors[
type][
"type"] =
"electrical";
317 if(
type==
"AlfaCtpin") {
318 connectors[
type][
"triggerlines"][
"clock0"] = json::array_t{};
319 connectors[
type][
"triggerlines"][
"clock1"] = json::array_t{};
321 connectors[
type][
"triggerlines"][
"fpga0"][
"clock0"] = json::array_t{};
322 connectors[
type][
"triggerlines"][
"fpga0"][
"clock1"] = json::array_t{};
323 connectors[
type][
"triggerlines"][
"fpga1"][
"clock0"] = json::array_t{};
324 connectors[
type][
"triggerlines"][
"fpga1"][
"clock1"] = json::array_t{};
326 }
else if(thr->input()==
"ctpin") {
327 connectors[
type][
"type"] =
"ctpin";
328 connectors[
type][
"triggerlines"] = json::array_t{};
330 throw std::runtime_error(
"Unknown connector type" + thr->input());
332 connectors[
type][
"legacy"] =
true;
334 size_t start = thr->cableStart();
335 size_t nbits = thr->cableEnd() - thr->cableStart() + 1;
336 if(thr->input()==
"ctpcore") {
337 unsigned int clock = thr->clock();
338 if(
type==
"AlfaCtpin") {
339 json tl{{
"name", thr->name()}, {
"startbit", start}, {
"nbits", nbits}};
340 connectors[
type][
"triggerlines"][
"clock" + std::to_string(clock)] += tl;
347 json tl{{
"name",
"R2TOPO_" + thr->name()}, {
"startbit", start}, {
"nbits", nbits}};
348 connectors[
type][
"triggerlines"][
"fpga" + std::to_string(fpga)][
"clock" + std::to_string(clock)] += tl;
351 json tl{{
"name", thr->name()}, {
"startbit", start}, {
"nbits", nbits}};
352 connectors[
type][
"triggerlines"] += tl;
358 json::object_t decAlgos;
359 json::object_t sortAlgos;
362 jAlg[
"algId"] = alg.algoID();
363 jAlg[
"klass"] = alg.type();
364 jAlg[
"fixedParameters"][
"generics"] = json::object_t{};
369 auto vInt = std::stoi(fixP.value);
370 jAlg[
"fixedParameters"][
"generics"][fixP.name] = json::object_t{{
"value", vInt}, {
"position", pos++}};
372 catch (std::invalid_argument &)
374 jAlg[
"fixedParameters"][
"generics"][fixP.name] = json::object_t{{
"value", fixP.value}, {
"position", pos++}};
377 jAlg[
"variableParameters"] = json::array_t{};
380 if (regP.name ==
"MaxMSqr") {
381 unsigned val = std::stoul(regP.value);
385 jAlg[
"variableParameters"] += json::object_t{{
"name", regP.name}, {
"selection", regP.selection}, {
"value", val}};
388 jAlg[
"variableParameters"] += json::object_t{{
"name", regP.name}, {
"selection", regP.selection}, {
"value", std::stoi(regP.value)}};
391 if(alg.isSortAlg()) {
392 jAlg[
"input"] = alg.getInputNames()[0];
393 jAlg[
"output"] = alg.output();
394 sortAlgos[alg.name()] = std::move(jAlg);
395 }
else if(alg.isDecAlg()) {
396 jAlg[
"input"] = alg.getInputNames();
397 jAlg[
"output"] = alg.getOutputNames();
398 decAlgos[alg.name()] = std::move(jAlg);
401 json topo = json::object_t{};
403 topo[
"R2TOPO"][
"decisionAlgorithms"] = decAlgos;
404 topo[
"R2TOPO"][
"sortingAlgorithms"] = sortAlgos;
408 json ctp = json::object_t{};
409 ctp[
"inputs"][
"ctpin"][
"slot7"] = json::object_t{{
"connector0",
"EM1"}, {
"connector1",
"EM2"},
410 {
"connector2",
"TAU1"}, {
"connector3",
"TAU2"}};
411 ctp[
"inputs"][
"ctpin"][
"slot8"] = json::object_t{{
"connector0",
"JET1"}, {
"connector1",
"JET2"},
412 {
"connector2",
"EN1"}, {
"connector3",
"EN2"}};
413 ctp[
"inputs"][
"ctpin"][
"slot9"] = json::object_t{{
"connector0",
"MUCTPI"}, {
"connector1",
"CTPCAL"},
414 {
"connector2",
"NIM1"}, {
"connector3",
"NIM2"}};
416 ctp[
"inputs"][
"electrical"] = json::object_t{{
"connector0",
"AlfaCtpin"}, {
"connector1",
"LegacyTopo0"}, {
"connector2",
"LegacyTopo1"}};
418 ctp[
"inputs"][
"electrical"] = json::object_t{};
420 ctp[
"inputs"][
"optical"] = json::object_t{};
421 ctp[
"monitoring"][
"ctpmon"] = json::object_t{};
425 menu[
"filetype"] =
"l1menu";
428 menu[
"items"] = std::move(items);
429 menu[
"thresholds"] = std::move(thresholds);
430 menu[
"topoAlgorithms"] = std::move(topo);
431 menu[
"boards"] = std::move(boards);
432 menu[
"connectors"] = std::move(connectors);
433 menu[
"ctp"] = std::move(ctp);
437 std::ofstream outfile(
"tmp" + filename);
438 outfile << std::setw(4) <<
menu << std::endl;
439 std::cout <<
"Wrote tmp" << filename << std::endl;
441 std::stringstream
ss;
444 boost::property_tree::read_json(
ss,
top);
447 writer.writeJsonFile(filename, l1menu);
456 if ( bunches.empty() ) {
459 if (bunches.size() == 1) {
460 return { {bunches.front(), bunches.front()} };
464 std::vector<std::pair<int, int>> ranges;
465 std::vector<int> sorted = bunches;
468 std::vector<int> differences;
469 std::adjacent_difference( sorted.begin(), sorted.end(), std::back_inserter(differences));
471 int start = sorted.front();
473 for (
size_t i = 1; i < differences.size(); ++i) {
474 if (differences[i] == 1)
continue;
475 ranges.emplace_back( std::pair(start, sorted[i-1]) );
478 ranges.emplace_back( std::pair(start, sorted.back()) );