Skip to content

Commit b081df8

Browse files
authored
Merge pull request #49069 from missirol/fix_l1tMaxMassCut
improve handling of correlation-conditions cut values in `l1t::TriggerMenuParser`
2 parents db86a8b + 97d01c8 commit b081df8

File tree

2 files changed

+104
-73
lines changed

2 files changed

+104
-73
lines changed

L1Trigger/L1TGlobal/plugins/TriggerMenuParser.cc

Lines changed: 95 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -33,36 +33,32 @@
3333
* $Revision$
3434
*
3535
*/
36-
37-
// this class header
3836
#include "TriggerMenuParser.h"
3937

40-
// system include files
41-
#include <string>
42-
#include <vector>
43-
44-
#include <iostream>
38+
#include <cmath>
39+
#include <cstdint>
4540
#include <fstream>
4641
#include <iomanip>
47-
#include <cmath>
42+
#include <iostream>
43+
#include <limits>
44+
#include <string>
45+
#include <vector>
4846

4947
#include "L1Trigger/L1TGlobal/interface/GlobalCondition.h"
5048

5149
#include "FWCore/MessageLogger/interface/MessageLogger.h"
52-
#include "FWCore/MessageLogger/interface/MessageDrop.h"
53-
54-
#include "tmEventSetup/tmEventSetup.hh"
55-
#include "tmEventSetup/esTypes.hh"
50+
#include "FWCore/Utilities/interface/isFinite.h"
5651

5752
#include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h"
5853
#include "CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h"
5954
#include "CondFormats/L1TObjects/interface/L1TUtmCondition.h"
6055
#include "CondFormats/L1TObjects/interface/L1TUtmObject.h"
6156
#include "CondFormats/L1TObjects/interface/L1TUtmCut.h"
6257
#include "CondFormats/L1TObjects/interface/L1TUtmScale.h"
63-
#include "tmGrammar/Algorithm.hh"
6458

65-
#include <cstdint>
59+
#include "tmEventSetup/tmEventSetup.hh"
60+
#include "tmEventSetup/esTypes.hh"
61+
#include "tmGrammar/Algorithm.hh"
6662

6763
// constructor
6864
l1t::TriggerMenuParser::TriggerMenuParser()
@@ -3101,40 +3097,36 @@ bool l1t::TriggerMenuParser::parseCorrelation(L1TUtmCondition corrCond, unsigned
31013097
//
31023098
// Until utm has method to calculate these, do the integer value calculation with precision.
31033099
//
3104-
double minV = cut.getMinimum().value;
3105-
double maxV = cut.getMaximum().value;
3106-
3107-
//Scale down very large numbers out of xml
3108-
if (maxV > 1.0e8)
3109-
maxV = 1.0e8;
3100+
double const minV = cut.getMinimum().value;
3101+
double const maxV = cut.getMaximum().value;
31103102

31113103
if (cut.getCutType() == esCutType::DeltaEta) {
31123104
LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaEta Cut minV = " << minV
31133105
<< " Max = " << maxV << " precMin = " << cut.getMinimum().index
31143106
<< " precMax = " << cut.getMaximum().index << std::endl;
3115-
corrParameter.minEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3116-
corrParameter.maxEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3107+
corrParameter.minEtaCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3108+
corrParameter.maxEtaCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
31173109
corrParameter.precEtaCut = cut.getMinimum().index;
31183110
cutType = cutType | 0x1;
31193111
} else if (cut.getCutType() == esCutType::DeltaPhi) {
31203112
LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaPhi Cut minV = " << minV
31213113
<< " Max = " << maxV << " precMin = " << cut.getMinimum().index
31223114
<< " precMax = " << cut.getMaximum().index << std::endl;
3123-
corrParameter.minPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3124-
corrParameter.maxPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3115+
corrParameter.minPhiCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3116+
corrParameter.maxPhiCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
31253117
corrParameter.precPhiCut = cut.getMinimum().index;
31263118
cutType = cutType | 0x2;
31273119
} else if (cut.getCutType() == esCutType::DeltaR) {
31283120
LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaR Cut minV = " << minV
31293121
<< " Max = " << maxV << " precMin = " << cut.getMinimum().index
31303122
<< " precMax = " << cut.getMaximum().index << std::endl;
3131-
corrParameter.minDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3132-
corrParameter.maxDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3123+
corrParameter.minDRCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3124+
corrParameter.maxDRCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
31333125
corrParameter.precDRCut = cut.getMinimum().index;
31343126
cutType = cutType | 0x4;
31353127
} else if (cut.getCutType() == esCutType::TwoBodyPt) {
3136-
corrParameter.minTBPTCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3137-
corrParameter.maxTBPTCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3128+
corrParameter.minTBPTCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3129+
corrParameter.maxTBPTCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
31383130
corrParameter.precTBPTCut = cut.getMinimum().index;
31393131
LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tTPBT Cut minV = " << minV
31403132
<< " Max = " << maxV << " precMin = " << cut.getMinimum().index
@@ -3145,8 +3137,8 @@ bool l1t::TriggerMenuParser::parseCorrelation(L1TUtmCondition corrCond, unsigned
31453137
LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
31463138
<< " Max = " << maxV << " precMin = " << cut.getMinimum().index
31473139
<< " precMax = " << cut.getMaximum().index << std::endl;
3148-
corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3149-
corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3140+
corrParameter.minMassCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3141+
corrParameter.maxMassCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
31503142
corrParameter.precMassCut = cut.getMinimum().index;
31513143
// cutType = cutType | 0x8;
31523144
if (corrCond.getType() == esConditionType::TransverseMass) {
@@ -3160,8 +3152,8 @@ bool l1t::TriggerMenuParser::parseCorrelation(L1TUtmCondition corrCond, unsigned
31603152
LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
31613153
<< " Max = " << maxV << " precMin = " << cut.getMinimum().index
31623154
<< " precMax = " << cut.getMaximum().index << std::endl;
3163-
corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3164-
corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3155+
corrParameter.minMassCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3156+
corrParameter.maxMassCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
31653157
corrParameter.precMassCut = cut.getMinimum().index;
31663158
cutType = cutType | 0x40; // Note: 0x40 (MassUpt) is next available bit after 0x20 (TwoBodyPt)
31673159
} // Careful: cutType carries same info as esCutType, but is hard coded!!
@@ -3404,23 +3396,24 @@ bool l1t::TriggerMenuParser::parseCorrelationThreeBody(L1TUtmCondition corrCond,
34043396
//
34053397
// Until utm has method to calculate these, do the integer value calculation with precision.
34063398
//
3407-
double minV = cut.getMinimum().value;
3408-
double maxV = cut.getMaximum().value;
3409-
//Scale down very large numbers out of xml
3410-
if (maxV > 1.0e8)
3411-
maxV = 1.0e8;
3399+
double const minV = cut.getMinimum().value;
3400+
double const maxV = cut.getMaximum().value;
34123401

34133402
if (cut.getCutType() == esCutType::Mass) {
34143403
LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
34153404
<< "\tMass Cut maxV = " << maxV << " precMin = " << cut.getMinimum().index
34163405
<< " precMax = " << cut.getMaximum().index << std::endl;
3417-
corrThreeBodyParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3418-
corrThreeBodyParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3406+
corrThreeBodyParameter.minMassCutValue =
3407+
multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3408+
corrThreeBodyParameter.maxMassCutValue =
3409+
multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
34193410
corrThreeBodyParameter.precMassCut = cut.getMinimum().index;
34203411
cutType = cutType | 0x8;
34213412
} else if (cut.getCutType() == esCutType::MassDeltaR) {
3422-
corrThreeBodyParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3423-
corrThreeBodyParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3413+
corrThreeBodyParameter.minMassCutValue =
3414+
multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3415+
corrThreeBodyParameter.maxMassCutValue =
3416+
multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
34243417
corrThreeBodyParameter.precMassCut = cut.getMinimum().index;
34253418
cutType = cutType | 0x80;
34263419
}
@@ -3564,59 +3557,61 @@ bool l1t::TriggerMenuParser::parseCorrelationWithOverlapRemoval(const L1TUtmCond
35643557
//
35653558
// Unitl utm has method to calculate these, do the integer value calculation with precision.
35663559
//
3567-
double minV = cut.getMinimum().value;
3568-
double maxV = cut.getMaximum().value;
3569-
3570-
//Scale down very large numbers out of xml
3571-
if (maxV > 1.0e8)
3572-
maxV = 1.0e8;
3560+
double const minV = cut.getMinimum().value;
3561+
double const maxV = cut.getMaximum().value;
35733562

35743563
if (cut.getCutType() == esCutType::DeltaEta) {
35753564
//std::cout << "DeltaEta Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3576-
corrParameter.minEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3577-
corrParameter.maxEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3565+
corrParameter.minEtaCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3566+
corrParameter.maxEtaCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
35783567
corrParameter.precEtaCut = cut.getMinimum().index;
35793568
cutType = cutType | 0x1;
35803569
} else if (cut.getCutType() == esCutType::DeltaPhi) {
35813570
//std::cout << "DeltaPhi Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3582-
corrParameter.minPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3583-
corrParameter.maxPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3571+
corrParameter.minPhiCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3572+
corrParameter.maxPhiCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
35843573
corrParameter.precPhiCut = cut.getMinimum().index;
35853574
cutType = cutType | 0x2;
35863575
} else if (cut.getCutType() == esCutType::DeltaR) {
35873576
//std::cout << "DeltaR Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3588-
corrParameter.minDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3589-
corrParameter.maxDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3577+
corrParameter.minDRCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3578+
corrParameter.maxDRCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
35903579
corrParameter.precDRCut = cut.getMinimum().index;
35913580
cutType = cutType | 0x4;
35923581
} else if (cut.getCutType() == esCutType::Mass) {
35933582
//std::cout << "Mass Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3594-
corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3595-
corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3583+
corrParameter.minMassCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3584+
corrParameter.maxMassCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
35963585
corrParameter.precMassCut = cut.getMinimum().index;
35973586
cutType = cutType | 0x8;
35983587
} else if (cut.getCutType() == esCutType::MassDeltaR) {
3599-
corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3600-
corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3588+
corrParameter.minMassCutValue = multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3589+
corrParameter.maxMassCutValue = multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
36013590
corrParameter.precMassCut = cut.getMinimum().index;
36023591
cutType = cutType | 0x80;
36033592
}
36043593
if (cut.getCutType() == esCutType::OvRmDeltaEta) {
36053594
//std::cout << "OverlapRemovalDeltaEta Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3606-
corrParameter.minOverlapRemovalEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3607-
corrParameter.maxOverlapRemovalEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3595+
corrParameter.minOverlapRemovalEtaCutValue =
3596+
multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3597+
corrParameter.maxOverlapRemovalEtaCutValue =
3598+
multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
36083599
corrParameter.precOverlapRemovalEtaCut = cut.getMinimum().index;
36093600
cutType = cutType | 0x10;
36103601
} else if (cut.getCutType() == esCutType::OvRmDeltaPhi) {
36113602
//std::cout << "OverlapRemovalDeltaPhi Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3612-
corrParameter.minOverlapRemovalPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3613-
corrParameter.maxOverlapRemovalPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3603+
corrParameter.minOverlapRemovalPhiCutValue =
3604+
multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3605+
corrParameter.maxOverlapRemovalPhiCutValue =
3606+
multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
36143607
corrParameter.precOverlapRemovalPhiCut = cut.getMinimum().index;
36153608
cutType = cutType | 0x20;
36163609
} else if (cut.getCutType() == esCutType::OvRmDeltaR) {
36173610
//std::cout << "DeltaR Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3618-
corrParameter.minOverlapRemovalDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3619-
corrParameter.maxOverlapRemovalDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3611+
corrParameter.minOverlapRemovalDRCutValue =
3612+
multiply_and_clamp_longlong(minV, pow(10., cut.getMinimum().index), true);
3613+
corrParameter.maxOverlapRemovalDRCutValue =
3614+
multiply_and_clamp_longlong(maxV, pow(10., cut.getMaximum().index), false);
36203615
corrParameter.precOverlapRemovalDRCut = cut.getMinimum().index;
36213616
cutType = cutType | 0x40;
36223617
}
@@ -3854,4 +3849,40 @@ bool l1t::TriggerMenuParser::parseAlgorithm(L1TUtmAlgorithm algorithm, unsigned
38543849

38553850
return true;
38563851
}
3857-
// static class members
3852+
3853+
long long l1t::TriggerMenuParser::multiply_and_clamp_longlong(double const d1,
3854+
double const d2,
3855+
bool const returnMinIfInvalid) const {
3856+
// min/max allowed values for the output of the method,
3857+
// corresponding to the largest (smallest) value representable
3858+
// as a double below (above) the max (min) of the long long type
3859+
static const double minll_d =
3860+
std::nextafter(double(std::numeric_limits<long long>::min()), std::numeric_limits<double>::infinity());
3861+
static const double maxll_d =
3862+
std::nextafter(double(std::numeric_limits<long long>::max()), -std::numeric_limits<double>::infinity());
3863+
3864+
double const prod = d1 * d2;
3865+
3866+
if (edm::isNotFinite(prod)) {
3867+
double const ret = returnMinIfInvalid ? minll_d : maxll_d;
3868+
edm::LogError("l1t::TriggerMenuParser")
3869+
<< "multiply_and_clamp_longlong(" << d1 << ", " << d2 << ", " << returnMinIfInvalid << "): returning " << ret
3870+
<< " (product of input values, i.e. " << prod << ", is not a finite number)."
3871+
<< " The emulation of the L1-uGT decisions might be incorrect !";
3872+
return ret;
3873+
}
3874+
3875+
if (prod < minll_d) {
3876+
edm::LogWarning("l1t::TriggerMenuParser")
3877+
<< "multiply_and_clamp_longlong(" << d1 << ", " << d2 << ", " << returnMinIfInvalid << "): returning "
3878+
<< minll_d << " (product of input values, i.e. " << prod << ", is smaller than the min allowed value)";
3879+
return minll_d;
3880+
} else if (prod > maxll_d) {
3881+
edm::LogWarning("l1t::TriggerMenuParser")
3882+
<< "multiply_and_clamp_longlong(" << d1 << ", " << d2 << ", " << returnMinIfInvalid << "): returning "
3883+
<< maxll_d << " (product of input values, i.e. " << prod << ", is larger than the max allowed value)";
3884+
return maxll_d;
3885+
}
3886+
3887+
return prod;
3888+
}

L1Trigger/L1TGlobal/plugins/TriggerMenuParser.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef L1TGlobal_TriggerMenuParser_h
2-
#define L1TGlobal_TriggerMenuParser_h
1+
#ifndef L1Trigger_L1TGlobal_TriggerMenuParser_h
2+
#define L1Trigger_L1TGlobal_TriggerMenuParser_h
33

44
/**
55
* \class TriggerMenuParser
@@ -26,12 +26,11 @@
2626
*
2727
*/
2828

29-
// system include files
29+
#include <map>
3030
#include <string>
3131
#include <vector>
3232

3333
#include "L1Trigger/L1TGlobal/interface/TriggerMenuFwd.h"
34-
3534
#include "L1Trigger/L1TGlobal/interface/MuonTemplate.h"
3635
#include "L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h"
3736
#include "L1Trigger/L1TGlobal/interface/CaloTemplate.h"
@@ -43,12 +42,8 @@
4342
#include "L1Trigger/L1TGlobal/interface/CorrelationThreeBodyTemplate.h"
4443
#include "L1Trigger/L1TGlobal/interface/CorrelationWithOverlapRemovalTemplate.h"
4544
#include "L1Trigger/L1TGlobal/interface/ExternalTemplate.h"
46-
4745
#include "L1Trigger/L1TGlobal/interface/GlobalScales.h"
4846

49-
#include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h"
50-
51-
#include <cmath>
5247
#include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h"
5348
#include "CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h"
5449
#include "CondFormats/L1TObjects/interface/L1TUtmCondition.h"
@@ -371,6 +366,11 @@ namespace l1t {
371366
TrigFunc_t func,
372367
unsigned int prec);
373368

369+
// Multiply two doubles, and return the result as a "long long" integer
370+
// Note: the output value is clamped within values close to the
371+
// min/max values of the "long long" type in order to avoid overflow
372+
long long multiply_and_clamp_longlong(double const d1, double const d2, bool const returnMinIfInvalid) const;
373+
374374
private:
375375
/// hardware limits
376376

@@ -444,4 +444,4 @@ namespace l1t {
444444
};
445445

446446
} // namespace l1t
447-
#endif /*L1TGlobal_TriggerMenuParser_h*/
447+
#endif

0 commit comments

Comments
 (0)