5 #include <unordered_set> 
    6 #include <boost/tokenizer.hpp> 
   14 #define BOOST_BIND_GLOBAL_PLACEHOLDERS // Needed to silence Boost pragma message 
   15 #include <boost/property_tree/json_parser.hpp> 
   30 #include <nlohmann/json.hpp> 
   36    std::tuple<std::string, std::vector<std::string>> 
 
   38       std::string definition{
""};
 
   39       std::vector<std::string> bgps;
 
   41       std::vector<const TrigConf::TriggerItemNode*> nodes;
 
   43       std::map<unsigned int, const TrigConf::TriggerItemNode*> nodeMap;
 
   44       for(
auto * 
node : nodes) {
 
   48       for ( 
auto & tok : boost::tokenizer<boost::char_separator<char> > (
item->definition(), boost::char_separator<char>(
" ", 
"()&|!")) ) {
 
   51             int idx = std::stoi(tok);
 
   53             if(
node->triggerThreshold()->
type()==
"BGRP") {
 
   54                bgps.push_back(
node->thresholdName());
 
   55                if(definition.back()==
'&') {
 
   56                   definition.pop_back();
 
   67       if(definition.front()==
'(' and definition.back()==
')') {
 
   68          definition = definition.substr(1,definition.size()-2);
 
   70       return make_tuple(definition, bgps);
 
   80                         const std::string& 
filename, 
bool writeTmpFile)
 
   84       std::cout << 
"No CTPConfig, no L1Menu file will be produced" << std::endl;
 
   94       item[
"name"] = sourceItem->name();
 
   95       item[
"legacy"] = 
true;
 
   96       item[
"ctpid"] = sourceItem->ctpId();
 
   97       auto [definition, bunchgroups] = decodeItemDefinition(sourceItem);
 
   98       item[
"definition"] = definition;
 
   99       item[
"bunchgroups"] = bunchgroups;
 
  101       item[
"partition"] = sourceItem->partition();
 
  102       std::string smon(
"LF:");
 
  103       smon += (sourceItem->monitor() & 0x04 ? 
'1' : 
'0');
 
  104       smon += (sourceItem->monitor() & 0x02 ? 
'1' : 
'0');
 
  105       smon += (sourceItem->monitor() & 0x01 ? 
'1' : 
'0');
 
  107       smon += (sourceItem->monitor() & 0x20 ? 
'1' : 
'0');
 
  108       smon += (sourceItem->monitor() & 0x10 ? 
'1' : 
'0');
 
  109       smon += (sourceItem->monitor() & 0x08 ? 
'1' : 
'0');
 
  110       item[
"monitor"] = smon;
 
  115    json thresholds = json::object_t{};
 
  116    std::unordered_set<std::string> legacyThrTypes{
"EM", 
"TAU", 
"JET", 
"JB", 
"JE", 
"JF", 
"XE", 
"XS", 
"TE", 
"ZB", 
"R2TOPO"};
 
  118       std::string thrType = sourceThr->type();
 
  119       if(thrType==
"BGRP" || thrType==
"RNDM") {
 
  122       if(thrType==
"MUON") {
 
  125       else if(thrType==
"TOPO") {
 
  129       bool isLegacyCalo = legacyThrTypes.count(thrType) > 0;
 
  130       json &jThisType = isLegacyCalo ? thresholds[
"legacyCalo"][thrType] : thresholds[thrType];
 
  131       bool firstOfItsType = jThisType.empty();
 
  134          jThisType[
"type"] = thrType;
 
  137       size_t mapping = sourceThr->mapping();
 
  142             jThisType[
"type"] = 
"MU";
 
  143             jThisType[
"exclusionLists"] = json::object_t{};
 
  144             jThisType[
"roads"][
"rpc"] = json::object_t{};
 
  145             jThisType[
"roads"][
"tgc"] = json::object_t{};
 
  147          int ptCut = sourceThr->triggerThresholdValue(0,0)->ptCutCount();
 
  148          thr[
"baThr"] = ptCut;
 
  149          thr[
"ecThr"] = ptCut;
 
  150          thr[
"fwThr"] = ptCut;
 
  154          thr[
"tgcFlags"] = 
"";
 
  155          thr[
"rpcFlags"] = 
"";
 
  156          thr[
"region"] = 
"ALL";
 
  160       else if (thrType == 
"EM")
 
  162          thr[
"thrValues"] = json::array_t{};
 
  167             jtv[
"value"] = 
static_cast<unsigned int>(tv->ptcut());
 
  168             std::string isobits = 
"00000";
 
  169             auto isomask = 
cl->isolationMask();
 
  170             for (
size_t b = 0; 
b < 5; ++
b)
 
  172                if (isomask & (1 << 
b))
 
  174                   isobits[4 - 
b] = 
'1';
 
  177             jtv[
"isobits"] = isobits;
 
  178             jtv[
"etamin"] = tv->etamin();
 
  179             jtv[
"etamax"] = tv->etamax();
 
  180             jtv[
"phimin"] = tv->phimin();
 
  181             jtv[
"phimax"] = tv->phimax();
 
  182             jtv[
"priority"] = 
static_cast<unsigned int>(tv->priority());
 
  183             thr[
"thrValues"] += jtv;
 
  186       else if (thrType == 
"TAU")
 
  189          int ptCut = (
int)
cl->ptcut();
 
  190          thr[
"value"] = ptCut;
 
  191          std::string isobits = 
"00000";
 
  192          auto isomask = 
cl->isolationMask();
 
  193          for (
size_t b = 0; 
b < 5; ++
b)
 
  195             if (isomask & (1 << 
b))
 
  197                isobits[4 - 
b] = 
'1';
 
  200          thr[
"isobits"] = isobits;
 
  202       else if (thrType == 
"JET" || thrType == 
"JB" ||  thrType == 
"JF")
 
  204          thr[
"thrValues"] = json::array_t{};
 
  209             jtv[
"value"] = 
static_cast<unsigned int>(tv->ptcut());
 
  210             jtv[
"etamin"] = tv->
etamin();
 
  211             jtv[
"etamax"] = tv->etamax();
 
  212             jtv[
"phimin"] = tv->phimin();
 
  213             jtv[
"phimax"] = tv->phimax();
 
  215             jtv[
"priority"] = 
static_cast<unsigned int>(tv->priority());
 
  216             thr[
"thrValues"] += jtv;
 
  219       else if (thrType == 
"XE" || thrType == 
"TE" ||  thrType == 
"XS" || thrType == 
"JE")
 
  221          thr[
"value"] = 
static_cast<unsigned int>(sourceThr->thresholdValueVector().at(0)->ptcut());
 
  223       else if (thrType == 
"ZB")
 
  225          thr[
"seed"] = sourceThr->zbSeedingThresholdName();
 
  226          thr[
"seedMultiplicity"] = sourceThr->zbSeedingThresholdMulti();
 
  227          thr[
"seedBcdelay"] = sourceThr->bcDelay();
 
  229       jThisType[
"thresholds"][sourceThr->name()] = 
thr;
 
  234    thresholds[
"legacyCalo"][
"EM"][
"ptMinToTopo"] = ci.
minTobEM().
ptmin;
 
  235    thresholds[
"legacyCalo"][
"EM"][
"resolutionMeV"] = (
int)(1000/ci.
globalEmScale());
 
  236    thresholds[
"legacyCalo"][
"TAU"][
"ptMinToTopo"] = ci.
minTobTau().
ptmin;
 
  240       json isoHAforEM{ {
"thrtype", 
"HAIsoForEMthr"}, {
"Parametrization", json::array_t{}} };
 
  241       json isoEMforEM{ {
"thrtype", 
"EMIsoForEMthr"}, {
"Parametrization", json::array_t{}} };
 
  242       json isoEMforTAU{ {
"thrtype", 
"EMIsoForTAUthr"}, {
"Parametrization", json::array_t{}} };
 
  244          json p{ {
"etamax", iso.etamax()}, {
"etamin", iso.etamin()}, {
"isobit", iso.isobit()}, {
"mincut", iso.mincut()}, 
 
  245                {
"offset", iso.offset()}, {
"priority", iso.priority()}, {
"slope", iso.slope()}, {
"upperlimit", iso.upperlimit()} };
 
  246          isoHAforEM[
"Parametrization"] += 
p;
 
  249          json p{ {
"etamax", iso.etamax()}, {
"etamin", iso.etamin()}, {
"isobit", iso.isobit()}, {
"mincut", iso.mincut()}, 
 
  250                {
"offset", iso.offset()}, {
"priority", iso.priority()}, {
"slope", iso.slope()}, {
"upperlimit", iso.upperlimit()} };
 
  251          isoEMforEM[
"Parametrization"] += 
p;
 
  254          json p{ {
"etamax", iso.etamax()}, {
"etamin", iso.etamin()}, {
"isobit", iso.isobit()}, {
"mincut", iso.mincut()}, 
 
  255                {
"offset", iso.offset()}, {
"priority", iso.priority()}, {
"slope", iso.slope()}, {
"upperlimit", iso.upperlimit()} };
 
  256          isoEMforTAU[
"Parametrization"] += 
p;
 
  258       thresholds[
"legacyCalo"][
"EM"][
"isolation"][
"HAIsoForEMthr"] =  std::move(isoHAforEM);
 
  259       thresholds[
"legacyCalo"][
"EM"][
"isolation"][
"EMIsoForEMthr"] =  std::move(isoEMforEM);
 
  260       thresholds[
"legacyCalo"][
"TAU"][
"isolation"][
"EMIsoForTAUthr"] =  std::move(isoEMforTAU);
 
  263    thresholds[
"legacyCalo"][
"XS"][
"significance"] = json::object_t{
 
  264        {
"xsSigmaScale", xs.
xsSigmaScale()}, {
"xsSigmaOffset", xs.
xsSigmaOffset()}, {
"xeMin", xs.
xeMin()}, {
"xeMax", xs.
xeMax()}, {
"teSqrtMin", xs.
teSqrtMin()}, {
"teSqrtMax", xs.
teSqrtMax()}};
 
  267    json boards = json::object_t{};
 
  268    boards[
"Ctpin7"] = json::object_t{ {
"type", 
"CTPIN"}, {
"legacy", 
true},
 
  269                                       {
"connectors", std::vector<std::string>{
"EM1", 
"EM2", 
"TAU1", 
"TAU2"}} };
 
  270    boards[
"Ctpin8"] = json::object_t{ {
"type", 
"CTPIN"}, {
"legacy", 
true},
 
  271                                       {
"connectors", std::vector<std::string>{
"JET1", 
"JET2", 
"EN1", 
"EN2"}} };
 
  272    boards[
"Ctpin9"] = json::object_t{ {
"type", 
"CTPIN"}, {
"legacy", 
true},
 
  273                                       {
"connectors", std::vector<std::string>{
"MUCTPI", 
"CTPCAL", 
"NIM1", 
"NIM2"}} };
 
  274    boards[
"LegacyTopo0"] = json::object_t{ {
"type", 
"TOPO"}, {
"legacy", 
true},
 
  275                                            {
"connectors", std::vector<std::string>{
"LegacyTopo0"}} };
 
  276    boards[
"LegacyTopo1"] = json::object_t{ {
"type", 
"TOPO"}, {
"legacy", 
true},
 
  277                                            {
"connectors", std::vector<std::string>{
"LegacyTopo1"}} };
 
  280    json connectors = json::object_t{};
 
  281    std::map<std::string,std::vector<const TrigConf::TriggerThreshold*>> triggerlinesMap;
 
  283       if(sourceThr->isInternal()) {
 
  286       std::string cableName = sourceThr->cableName();
 
  287       if(cableName==
"ALFA") {
 
  288          cableName = 
"AlfaCtpin";
 
  290       else if(cableName==
"TOPO1") {
 
  291          cableName = 
"LegacyTopo0";
 
  293       else if(cableName==
"TOPO2") {
 
  294          cableName = 
"LegacyTopo1";
 
  296       triggerlinesMap[cableName].push_back(sourceThr);
 
  298    for( 
auto & [
type, triggerlines] : triggerlinesMap) {
 
  302          if(!connectors.contains(
type)) {
 
  303             if(
thr->input()==
"ctpcore") {
 
  304                connectors[
type][
"type"] =  
"electrical";
 
  305                if(
type==
"AlfaCtpin") {
 
  306                   connectors[
type][
"triggerlines"][
"clock0"] = json::array_t{};
 
  307                   connectors[
type][
"triggerlines"][
"clock1"] = json::array_t{};
 
  309                   connectors[
type][
"triggerlines"][
"fpga0"][
"clock0"] = json::array_t{};
 
  310                   connectors[
type][
"triggerlines"][
"fpga0"][
"clock1"] = json::array_t{};
 
  311                   connectors[
type][
"triggerlines"][
"fpga1"][
"clock0"] = json::array_t{};
 
  312                   connectors[
type][
"triggerlines"][
"fpga1"][
"clock1"] = json::array_t{};
 
  314             } 
else if(
thr->input()==
"ctpin") {
 
  315                connectors[
type][
"type"] =  
"ctpin";
 
  316                connectors[
type][
"triggerlines"] = json::array_t{};
 
  318                throw std::runtime_error(
"Unknown connector type" + 
thr->input());
 
  320             connectors[
type][
"legacy"] = 
true;
 
  323          size_t nbits = 
thr->cableEnd() - 
thr->cableStart() + 1;
 
  324          if(
thr->input()==
"ctpcore") {
 
  325             unsigned int clock = 
thr->clock();
 
  326             if(
type==
"AlfaCtpin") {
 
  327                json tl{{
"name", 
thr->name()}, {
"startbit", 
start}, {
"nbits", nbits}};
 
  335                json tl{{
"name", 
"R2TOPO_" + 
thr->name()}, {
"startbit", 
start}, {
"nbits", nbits}};
 
  339             json tl{{
"name", 
thr->name()}, {
"startbit", 
start}, {
"nbits", nbits}};
 
  340             connectors[
type][
"triggerlines"] += 
tl;
 
  346    json::object_t decAlgos;
 
  347    json::object_t sortAlgos;
 
  350       jAlg[
"algId"] = 
alg.algoID();
 
  351       jAlg[
"klass"] = 
alg.type();
 
  352       jAlg[
"fixedParameters"][
"generics"] = json::object_t{};
 
  357             auto vInt = std::stoi(fixP.value);
 
  358             jAlg[
"fixedParameters"][
"generics"][fixP.name] = json::object_t{{
"value", vInt}, {
"position", 
pos++}};
 
  360          catch (std::invalid_argument &)
 
  362             jAlg[
"fixedParameters"][
"generics"][fixP.name] = json::object_t{{
"value", fixP.value}, {
"position", 
pos++}};
 
  365       jAlg[
"variableParameters"] = json::array_t{};
 
  368          if (regP.name == 
"MaxMSqr") {
 
  369            unsigned val = std::stoul(regP.value);
 
  373            jAlg[
"variableParameters"] += json::object_t{{
"name", regP.name}, {
"selection", regP.selection}, {
"value", 
val}};
 
  376            jAlg[
"variableParameters"] += json::object_t{{
"name", regP.name}, {
"selection", regP.selection}, {
"value", std::stoi(regP.value)}};
 
  379       if(
alg.isSortAlg()) {
 
  380          jAlg[
"input"] = 
alg.getInputNames()[0];
 
  381          jAlg[
"output"] = 
alg.output();
 
  382          sortAlgos[
alg.name()] =  std::move(jAlg);
 
  383       } 
else if(
alg.isDecAlg()) {
 
  384          jAlg[
"input"] = 
alg.getInputNames();
 
  385          jAlg[
"output"] = 
alg.getOutputNames();
 
  386          decAlgos[
alg.name()] =  std::move(jAlg);
 
  391       topo[
"R2TOPO"][
"decisionAlgorithms"] = decAlgos;
 
  392       topo[
"R2TOPO"][
"sortingAlgorithms"] = sortAlgos;
 
  397    ctp[
"inputs"][
"ctpin"][
"slot7"] = json::object_t{{
"connector0", 
"EM1"}, {
"connector1", 
"EM2"}, 
 
  398                                                     {
"connector2", 
"TAU1"}, {
"connector3", 
"TAU2"}};
 
  399    ctp[
"inputs"][
"ctpin"][
"slot8"] = json::object_t{{
"connector0", 
"JET1"}, {
"connector1", 
"JET2"}, 
 
  400                                                     {
"connector2", 
"EN1"}, {
"connector3", 
"EN2"}};
 
  401    ctp[
"inputs"][
"ctpin"][
"slot9"] = json::object_t{{
"connector0", 
"MUCTPI"}, {
"connector1", 
"CTPCAL"}, 
 
  402                                                     {
"connector2", 
"NIM1"}, {
"connector3", 
"NIM2"}};
 
  404       ctp[
"inputs"][
"electrical"] = json::object_t{{
"connector0", 
"AlfaCtpin"}, {
"connector1", 
"LegacyTopo0"}, {
"connector2", 
"LegacyTopo1"}};
 
  406       ctp[
"inputs"][
"electrical"] = json::object_t{};
 
  408    ctp[
"inputs"][
"optical"] = json::object_t{};
 
  409    ctp[
"monitoring"][
"ctpmon"] = json::object_t{};
 
  413    menu[
"filetype"] = 
"l1menu";
 
  417    menu[
"thresholds"] =  std::move(thresholds);
 
  418    menu[
"topoAlgorithms"] =  std::move(
topo);
 
  419    menu[
"boards"] =  std::move(boards);
 
  420    menu[
"connectors"] =  std::move(connectors);
 
  427       std::cout << 
"Wrote tmp" << 
filename << std::endl;
 
  429    std::stringstream 
ss;
 
  432    boost::property_tree::read_json(
ss, 
top);
 
  441 std::vector<std::pair<int, int>>
 
  444    if ( bunches.empty() ) {
 
  447    if (bunches.size() == 1) {
 
  448       return { {bunches.front(), bunches.front()} };
 
  452    std::vector<std::pair<int, int>> 
ranges;
 
  453    std::vector<int> 
sorted = bunches;
 
  456    std::vector<int> differences;
 
  457    std::adjacent_difference( 
sorted.begin(), 
sorted.end(), std::back_inserter(differences));
 
  461    for (
size_t i = 1; 
i < differences.size(); ++
i) {
 
  462       if (differences[
i] == 1) 
continue;
 
  475       std::cout << 
"BunchgroupSet is empty, no file will be produced" << std::endl;
 
  480    bgset[
"filetype"] =
"bunchgroupset";
 
  481    bgset[
"name"] = bgs.
name();
 
  484    const std::vector<TrigConf::BunchGroup>& bgVec = bgs.
bunchGroups();
 
  485    for (
auto & 
group : bgVec) {
 
  488       jGroup[
"name"] =
group.name();
 
  489       jGroup[
"id"] =
group.internalNumber();
 
  492       json jBCIDS = json::array_t{};
 
  496       jGroup[
"bcids"] =  std::move(jBCIDS);
 
  500    bgset[
"bunchGroups"] = std::move(jGroups);
 
  504       outfile << std::setw(4) << bgset << std::endl;
 
  505       std::cout << 
"Wrote tmp" << 
filename << std::endl;
 
  507    std::stringstream 
ss;
 
  510    boost::property_tree::read_json(
ss, 
top);
 
  523       std::cout << 
"L1PrescaleSet is empty, no file will be produced" << std::endl;
 
  528    psset[
"filetype"] = 
"l1prescale";
 
  529    psset[
"name"] = l1pss.
name();
 
  533       auto itemPtr = ctpConfig->
menu().
item(
id);
 
  534       if ( itemPtr != 
nullptr ) {
 
  535          int32_t 
cut = l1pss.
cuts().at(
id);
 
  536          jCut[
"cut"] = abs(
cut);
 
  537          jCut[
"enabled"] = 
cut > 0;
 
  538          double ps = 
static_cast<double>(0xFFFFFF) / ( 0x1000000 - 
cut );
 
  540          jCuts[itemPtr->name()] = std::move(jCut);
 
  543    psset[
"cutValues"] = std::move(jCuts);
 
  547       outfile << std::setw(4) << psset << std::endl;
 
  548       std::cout << 
"Wrote tmp" << 
filename << std::endl;
 
  550    std::stringstream 
ss;
 
  553    boost::property_tree::read_json(
ss, 
top);