20    if ( energyMeV % energyResolutionMeV != 0 ) {
 
   21       throw std::runtime_error(
"Energy " + 
std::to_string(energyMeV) + 
" MeV is not a multiple of the energy resolution " + 
std::to_string(energyResolutionMeV));
 
   23    return energyMeV / energyResolutionMeV;
 
   27 std::shared_ptr<TrigConf::L1Threshold>
 
   29                                         std::weak_ptr<L1ThrExtraInfoBase> extraInfo, 
const ptree & 
data )
 
   32       return std::make_shared<L1Threshold_EM>( 
name, 
type, extraInfo, 
data );
 
   35       return std::make_shared<L1Threshold_TAU>( 
name, 
type, extraInfo, 
data );
 
   38       return std::make_shared<L1Threshold_XE>( 
name, 
type, extraInfo, 
data );
 
   41       return std::make_shared<L1Threshold_JET>( 
name, 
type, extraInfo, 
data );
 
   44       return std::make_shared<L1Threshold_XS>( 
name, 
type, extraInfo, 
data );
 
   47       return std::make_shared<L1Threshold_TE>( 
name, 
type, extraInfo, 
data );
 
   50       return std::make_shared<L1Threshold_eEM>( 
name, 
type, extraInfo, 
data );
 
   53       return std::make_shared<L1Threshold_jEM>( 
name, 
type, extraInfo, 
data );
 
   56       return std::make_shared<L1Threshold_eTAU>( 
name, 
type, extraInfo, 
data );
 
   59       return std::make_shared<L1Threshold_jTAU>( 
name, 
type, extraInfo, 
data );
 
   62       return std::make_shared<L1Threshold_cTAU>( 
name, 
type, extraInfo, 
data );
 
   65       return std::make_shared<L1Threshold_jJ>( 
name, 
type, extraInfo, 
data );
 
   68       return std::make_shared<L1Threshold_jLJ>( 
name, 
type, extraInfo, 
data );
 
   71       return std::make_shared<L1Threshold_gJ>( 
name, 
type, extraInfo, 
data );
 
   74       return std::make_shared<L1Threshold_gLJ>( 
name, 
type, extraInfo, 
data );
 
   77       return std::make_shared<L1Threshold_jXE>( 
name, 
type, extraInfo, 
data );
 
   80       return std::make_shared<L1Threshold_jTE>( 
name, 
type, extraInfo, 
data );
 
   83       return std::make_shared<L1Threshold_gXE>( 
name, 
type, extraInfo, 
data );
 
   86       return std::make_shared<L1Threshold_gTE>( 
name, 
type, extraInfo, 
data );
 
   89       return std::make_shared<L1Threshold_MU>( 
name, 
type, extraInfo, 
data );
 
   92       return std::make_shared<L1Threshold_ZB>( 
name, 
type, extraInfo, 
data );
 
   94    if( 
type == 
"ZBTopo" )
 
   95       return std::make_shared<L1Threshold_ZBTopo>( 
name, 
type, extraInfo, 
data );
 
   97    static const std::string NIMtypes[] = { 
"BCM", 
"BCMCMB", 
"LUCID", 
"ZDC", 
"BPTX", 
"CALREQ", 
"MBTS", 
"MBTSSI", 
"NIM" };
 
  101       return std::make_shared<L1Threshold_NIM>( 
name, 
type, extraInfo, 
data );
 
  103    if( 
type == 
"internal" )
 
  104       return std::make_shared<L1Threshold_internal>( 
name, 
type, extraInfo, 
data );
 
  106    static const std::string noSpecialImp[] = { 
"JET", 
"XS", 
"TOPO", 
"MULTTOPO", 
"MUTOPO", 
"R2TOPO", 
"ALFA", 
"NSWMon", 
"LArSat"};
 
  110       return std::make_shared<L1Threshold>( 
name, 
type, extraInfo, 
data );
 
  112    throw std::runtime_error(
"Threshold " + 
name + 
" is not of a valid L1 threshold type: " + 
type);
 
  119      m_extraInfo(extraInfo),
 
  140    if( 
type() == 
"internal" ) {
 
  145    m_mapping = getAttribute<unsigned int>(
"mapping");
 
  159    if(! isInitialized() || empty() )
 
  167           content.first == 
"thresholds" ) {
 
  171       m_extraInfo.emplace( std::piecewise_construct,
 
  172                            std::forward_as_tuple(
content.first),
 
  173                            std::forward_as_tuple(
content.second));
 
  176    m_resolutionMeV = getAttribute<unsigned int>(
"resolutionMeV", 
true, 1000);
 
  177    if( hasAttribute(
"emscale") ) { 
 
  178       m_resolutionMeV = 1000 / getAttribute<unsigned int>(
"emscale");
 
  193       return m_extraInfo.size()>0;
 
  195    return m_extraInfo.count(
key)>0;
 
  198 std::optional<std::reference_wrapper<const TrigConf::DataStructure>>
 
  201    bool hasKey = m_extraInfo.count(
key)>0;
 
  202    return hasKey ? std::optional<std::reference_wrapper<const TrigConf::DataStructure>>{m_extraInfo.at(
key)} : std::nullopt;
 
  216      m_etaDepThrValue(
name + 
"#" + 
type + 
"_value")
 
  229    unsigned int gev2MeVThrVal(
double gevVal) {
 
  230       unsigned int mev_i = std::lround( 1000 * gevVal );
 
  231       if( gevVal != (mev_i / 1000.) ) {
 
  232          std::runtime_error(
"Value conversion failed");
 
  243    if( 
type() == 
"internal" ) {
 
  246    m_thrValue = gev2MeVThrVal( getAttribute<double>(
"value", 
true, 0) );
 
  247    m_input = getAttribute(
"input", 
true, 
"");
 
  248    if( 
const auto & thrVs = 
data().get_child_optional(
"thrValues") ) {
 
  249       for( 
auto & 
x : thrVs.get() ) {
 
  250          auto value = gev2MeVThrVal( 
x.second.get_child(
"value").get_value<
float>() );
 
  251          auto etamin = 
x.second.get_child(
"etamin").get_value<
unsigned int>();
 
  252          auto etamax = 
x.second.get_child(
"etamax").get_value<
unsigned int>();
 
  253          auto priority = 
x.second.get_child(
"priority").get_value<
unsigned int>();
 
  257    if( 
const auto & 
ranges = 
data().get_child_optional(
"ranges") ) {
 
  259       for( 
auto & 
x : 
ranges.get() ) {
 
  260          auto etamin = 
x.second.get_child(
"etamin").get_value<
unsigned int>();
 
  261          auto etamax = 
x.second.get_child(
"etamax").get_value<
unsigned int>();
 
  262          m_etaDepThrValue.addRangeValue(m_thrValue, 
etamin, etamax,  1,  
false);
 
  274    return thrValueMeV(
eta) / 1000.0f;
 
  279    auto extraInfo = m_extraInfo.lock();
 
  290    return m_etaDepThrValue.empty() ? m_thrValue : m_etaDepThrValue.at(
eta);
 
  296    for( 
auto & 
r : m_etaDepThrValue ) {
 
  297       thresholdValuesGeV.addRangeValue(
r.value() / 1000.0f, 
r.etaMin(), 
r.etaMax(), 
r.priority(), 
r.symmetric());
 
  299    return thresholdValuesGeV;
 
  304    return m_etaDepThrValue;
 
  310    for( 
auto & 
r : m_etaDepThrValue ) {
 
  311       thrValues100MeV.addRangeValue( 
energyInCounts( 
r.value(), 100 ), 
r.etaMin(), 
r.etaMax(), 
r.priority(), 
r.symmetric());
 
  313    return thrValues100MeV;
 
  318    auto extraInfo = m_extraInfo.lock();
 
  320    for( 
auto & 
r : m_etaDepThrValue ) {
 
  321       thrValuesCounts.addRangeValue( 
energyInCounts( 
r.value(), extraInfo->resolutionMeV() ), 
r.etaMin(), 
r.etaMax(), 
r.priority(), 
r.symmetric());
 
  323    return thrValuesCounts;
 
  328    m_isobit = 
pt.get_child(
"isobit").get_value<
int>();
 
  329    m_offset = 
pt.get_child(
"offset").get_value<
int>();
 
  330    m_slope =  
pt.get_child(
"slope").get_value<
int>();
 
  331    m_mincut =  
pt.get_child(
"mincut").get_value<
int>();
 
  332    m_upperlimit = 
pt.get_child(
"upperlimit").get_value<
int>();
 
  333    m_etamin =  
pt.get_child(
"etamin").get_value<
int>();
 
  334    m_etamax =  
pt.get_child(
"etamax").get_value<
int>();
 
  335    m_priority =  
pt.get_child(
"priority").get_value<
int>();
 
  340    os << 
"isolation bit " << iso.
isobit() << 
":  offset=" << iso.
offset() << 
", slope=" << iso.
slope() 
 
  342       << 
", etamin=" << iso.
etamin() << 
", etamax=" << iso.
etamax() << 
", priority=" << iso.
priority();
 
  401    throw std::runtime_error(
"Unknown working point " + 
std::to_string(
int(
wp)));
 
  409    if (wpStr == 
"Loose")
 
  411    if (wpStr == 
"Medium")
 
  413    if (wpStr == 
"Tight")
 
  415    if (wpStr == 
"HadLoose")
 
  417    if (wpStr == 
"HadMedium")
 
  419    if (wpStr == 
"HadTight")
 
  423    if (wpStr == 
"Loose12")
 
  425    if (wpStr == 
"Loose20")
 
  427    if (wpStr == 
"Loose30")
 
  429    if (wpStr == 
"Loose35")
 
  431    if (wpStr == 
"Loose50")
 
  433    if (wpStr == 
"Loose55")
 
  435    if (wpStr == 
"Medium12")
 
  437    if (wpStr == 
"Medium20")
 
  439    if (wpStr == 
"Medium30")
 
  441    if (wpStr == 
"Medium35")
 
  443    if (wpStr == 
"Medium50")
 
  445    if (wpStr == 
"Medium55")
 
  447    if (wpStr == 
"Tight12")
 
  449    if (wpStr == 
"Tight20")
 
  451    if (wpStr == 
"Tight30")
 
  453    if (wpStr == 
"Tight35")
 
  455    if (wpStr == 
"Tight50")
 
  457    if (wpStr == 
"Tight55")
 
  459    throw std::runtime_error(
"Unknown working point name " + wpStr);