CMS 3D CMS Logo

L1GTDeltaCut.h
Go to the documentation of this file.
1 #ifndef L1Trigger_Phase2L1GT_L1GTDeltaCut_h
2 #define L1Trigger_Phase2L1GT_L1GTDeltaCut_h
3 
7 
9 
11 
13 
14 #include "L1GTSingleInOutLUT.h"
15 #include "L1GTOptionalParam.h"
16 
17 #include <optional>
18 
19 namespace l1t {
20 
21  class L1GTDeltaCut {
22  public:
23  static constexpr uint32_t DETA_LUT_SPLIT = 1 << 13; // hw 2pi
24 
26  const edm::ParameterSet& lutConfig,
27  const L1GTScales& scales,
28  bool enable_sanity_checks = false,
29  bool inv_mass_checks = false)
30  : scales_(scales),
31  coshEtaLUT_(lutConfig.getParameterSet("cosh_eta_lut")),
32  coshEtaLUT2_(lutConfig.getParameterSet("cosh_eta_lut2")),
33  cosPhiLUT_(lutConfig.getParameterSet("cos_phi_lut")),
34  minDEta_(getOptionalParam<int, double>(
35  "minDEta", config, [&scales](double value) { return scales.to_hw_eta(value); })),
36  maxDEta_(getOptionalParam<int, double>(
37  "maxDEta", config, [&scales](double value) { return scales.to_hw_eta(value); })),
38  minDPhi_(getOptionalParam<int, double>(
39  "minDPhi", config, [&scales](double value) { return scales.to_hw_phi(value); })),
40  maxDPhi_(getOptionalParam<int, double>(
41  "maxDPhi", config, [&scales](double value) { return scales.to_hw_phi(value); })),
42  minDz_(getOptionalParam<int, double>(
43  "minDz", config, [&scales](double value) { return scales.to_hw_z0(value); })),
44  maxDz_(getOptionalParam<int, double>(
45  "maxDz", config, [&scales](double value) { return scales.to_hw_z0(value); })),
46  minDRSquared_(getOptionalParam<int, double>(
47  "minDR", config, [&scales](double value) { return scales.to_hw_dRSquared(value); })),
48  maxDRSquared_(getOptionalParam<int, double>(
49  "maxDR", config, [&scales](double value) { return scales.to_hw_dRSquared(value); })),
50  minInvMassSqrDiv2_(getOptionalParam<double, double>(
51  "minInvMass", config, [&scales](double value) { return scales.to_hw_InvMassSqrDiv2(value); })),
52  maxInvMassSqrDiv2_(getOptionalParam<double, double>(
53  "maxInvMass", config, [&scales](double value) { return scales.to_hw_InvMassSqrDiv2(value); })),
54  minTransMassSqrDiv2_(getOptionalParam<double, double>(
55  "minTransMass", config, [&scales](double value) { return scales.to_hw_TransMassSqrDiv2(value); })),
56  maxTransMassSqrDiv2_(getOptionalParam<double, double>(
57  "maxTransMass", config, [&scales](double value) { return scales.to_hw_TransMassSqrDiv2(value); })),
58  minPTSquared_(getOptionalParam<double, double>(
59  "minCombPt", config, [&scales](double value) { return scales.to_hw_PtSquared(value); })),
60  maxPTSquared_(getOptionalParam<double, double>(
61  "maxCombPt", config, [&scales](double value) { return scales.to_hw_PtSquared(value); })),
62  os_(config.getParameter<bool>("os")),
63  ss_(config.getParameter<bool>("ss")),
64  enable_sanity_checks_(enable_sanity_checks),
66 
67  bool checkObjects(const P2GTCandidate& obj1,
68  const P2GTCandidate& obj2,
69  InvariantMassErrorCollection& massErrors) const {
70  bool res = true;
71 
72  std::optional<uint32_t> dEta;
73 
75  dEta = (obj1.hwEta() > obj2.hwEta()) ? obj1.hwEta().to_int() - obj2.hwEta().to_int()
76  : obj2.hwEta().to_int() - obj1.hwEta().to_int();
77  res &= minDEta_ ? dEta > minDEta_ : true;
78  res &= maxDEta_ ? dEta < maxDEta_ : true;
79  }
80 
81  constexpr int HW_PI = 1 << (P2GTCandidate::hwPhi_t::width - 1); // assumes phi in [-pi, pi)
82 
83  // Ensure dPhi is always the smaller angle, i.e. always between [0, pi]
84  std::optional<uint32_t> dPhi;
85 
88  dPhi = HW_PI - abs(abs(obj1.hwPhi().to_int() - obj2.hwPhi().to_int()) - HW_PI);
89  }
90 
91  res &= minDPhi_ ? dPhi > minDPhi_ : true;
92  res &= maxDPhi_ ? dPhi < maxDPhi_ : true;
93 
94  if (minDz_ || maxDz_) {
95  uint32_t dZ = abs(obj1.hwZ0() - obj2.hwZ0());
96  res &= minDz_ ? dZ > minDz_ : true;
97  res &= maxDz_ ? dZ < maxDz_ : true;
98  }
99 
100  if (minDRSquared_ || maxDRSquared_) {
101  uint32_t dRSquared = dEta.value() * dEta.value() + dPhi.value() * dPhi.value();
102  res &= minDRSquared_ ? dRSquared > minDRSquared_ : true;
103  res &= maxDRSquared_ ? dRSquared < maxDRSquared_ : true;
104  }
105 
106  res &= os_ ? obj1.hwCharge() != obj2.hwCharge() : true;
107  res &= ss_ ? obj1.hwCharge() == obj2.hwCharge() : true;
108 
109  int32_t lutCoshDEta = 0;
110  if (dEta) {
111  lutCoshDEta = dEta < DETA_LUT_SPLIT ? coshEtaLUT_[dEta.value()] : coshEtaLUT2_[dEta.value() - DETA_LUT_SPLIT];
112  }
113 
114  // Optimization: (cos(x + pi) = -cos(x), x in [0, pi))
115  int32_t lutCosDPhi = 0;
116  if (dPhi) {
117  lutCosDPhi = dPhi >= HW_PI ? -cosPhiLUT_[dPhi.value()] : cosPhiLUT_[dPhi.value()];
118  }
119 
120  if (enable_sanity_checks_ && dEta && dPhi) {
121  // Check whether the LUT error is smaller or equal than the expected maximum LUT error
122  double coshEtaLUTMax = dEta < DETA_LUT_SPLIT ? coshEtaLUT_.hwMax_error() : coshEtaLUT2_.hwMax_error();
123  double etaLUTScale = dEta < DETA_LUT_SPLIT ? coshEtaLUT_.output_scale() : coshEtaLUT2_.output_scale();
124 
125  if (std::abs(lutCoshDEta - etaLUTScale * std::cosh(dEta.value() * scales_.eta_lsb())) > coshEtaLUTMax) {
126  edm::LogError("COSH LUT") << "Difference larger than max LUT error: " << coshEtaLUTMax
127  << ", lut: " << lutCoshDEta
128  << ", calc: " << etaLUTScale * std::cosh(dEta.value() * scales_.eta_lsb())
129  << ", dEta: " << dEta.value() << ", scale: " << etaLUTScale;
130  }
131 
132  if (std::abs(lutCosDPhi - cosPhiLUT_.output_scale() * std::cos(dPhi.value() * scales_.phi_lsb())) >
134  edm::LogError("COS LUT") << "Difference larger than max LUT error: " << cosPhiLUT_.hwMax_error()
135  << ", lut: " << lutCosDPhi << ", calc: "
136  << cosPhiLUT_.output_scale() * std::cos(dPhi.value() * scales_.phi_lsb());
137  }
138  }
139 
141  int64_t invMassSqrDiv2;
142  if (dEta < DETA_LUT_SPLIT) {
143  // dEta [0, 2pi)
144  invMassSqrDiv2 = obj1.hwPT().to_int64() * obj2.hwPT().to_int64() * (lutCoshDEta - lutCosDPhi);
146  ? invMassSqrDiv2 > std::round(minInvMassSqrDiv2_.value() * coshEtaLUT_.output_scale())
147  : true;
149  ? invMassSqrDiv2 < std::round(maxInvMassSqrDiv2_.value() * coshEtaLUT_.output_scale())
150  : true;
151  } else {
152  // dEta [2pi, 4pi), ignore cos
153  invMassSqrDiv2 = obj1.hwPT().to_int64() * obj2.hwPT().to_int64() * lutCoshDEta;
155  ? invMassSqrDiv2 > std::round(minInvMassSqrDiv2_.value() * coshEtaLUT2_.output_scale())
156  : true;
158  ? invMassSqrDiv2 < std::round(maxInvMassSqrDiv2_.value() * coshEtaLUT2_.output_scale())
159  : true;
160  }
161 
162  if (inv_mass_checks_) {
163  double precInvMass =
164  scales_.pT_lsb() *
165  std::sqrt(2 * obj1.hwPT().to_double() * obj2.hwPT().to_double() *
166  (std::cosh(dEta.value() * scales_.eta_lsb()) - std::cos(dPhi.value() * scales_.phi_lsb())));
167 
168  double lutInvMass = scales_.pT_lsb() * std::sqrt(2 * static_cast<double>(invMassSqrDiv2) /
171 
172  double error = std::abs(precInvMass - lutInvMass);
173  massErrors.emplace_back(InvariantMassError{error, error / precInvMass, precInvMass});
174  }
175  }
176 
177  if (minPTSquared_ || maxPTSquared_) {
178  int64_t pTSquared = obj1.hwPT().to_int64() * obj1.hwPT().to_int64() *
179  static_cast<int64_t>(std::round(cosPhiLUT_.output_scale())) +
180  obj2.hwPT().to_int64() * obj2.hwPT().to_int64() *
181  static_cast<int64_t>(std::round(cosPhiLUT_.output_scale())) +
182  2 * obj1.hwPT().to_int64() * obj2.hwPT().to_int64() * lutCosDPhi;
183  res &= minPTSquared_ ? pTSquared > std::round(minPTSquared_.value() * cosPhiLUT_.output_scale()) : true;
184  res &= maxPTSquared_ ? pTSquared < std::round(maxPTSquared_.value() * cosPhiLUT_.output_scale()) : true;
185  }
186 
188  int64_t transMassDiv2 = obj1.hwPT().to_int64() * obj2.hwPT().to_int64() *
189  (static_cast<int64_t>(coshEtaLUT_.output_scale()) - lutCosDPhi);
191  ? transMassDiv2 > std::round(minTransMassSqrDiv2_.value() * coshEtaLUT_.output_scale())
192  : true;
194  ? transMassDiv2 < std::round(maxTransMassSqrDiv2_.value() * coshEtaLUT_.output_scale())
195  : true;
196  }
197 
198  return res;
199  }
200 
202  edm::ParameterSetDescription coshLUTDesc;
204  desc.add<edm::ParameterSetDescription>("cosh_eta_lut", coshLUTDesc);
205 
206  edm::ParameterSetDescription coshLUT2Desc;
208  desc.add<edm::ParameterSetDescription>("cosh_eta_lut2", coshLUT2Desc);
209 
210  edm::ParameterSetDescription cosLUTDesc;
212  desc.add<edm::ParameterSetDescription>("cos_phi_lut", cosLUTDesc);
213  }
214 
216  desc.addOptional<double>("minDEta");
217  desc.addOptional<double>("maxDEta");
218  desc.addOptional<double>("minDPhi");
219  desc.addOptional<double>("maxDPhi");
220  desc.addOptional<double>("minDR");
221  desc.addOptional<double>("maxDR");
222  desc.addOptional<double>("minDz");
223  desc.addOptional<double>("maxDz");
224  desc.addOptional<double>("minInvMass");
225  desc.addOptional<double>("maxInvMass");
226  desc.addOptional<double>("minTransMass");
227  desc.addOptional<double>("maxTransMass");
228  desc.addOptional<double>("minCombPt");
229  desc.addOptional<double>("maxCombPt");
230  desc.add<bool>("os", false);
231  desc.add<bool>("ss", false);
232  }
233 
234  private:
236 
237  const L1GTSingleInOutLUT coshEtaLUT_; // [0, 2pi)
238  const L1GTSingleInOutLUT coshEtaLUT2_; // [2pi, 4pi)
240 
241  const std::optional<int> minDEta_;
242  const std::optional<int> maxDEta_;
243  const std::optional<int> minDPhi_;
244  const std::optional<int> maxDPhi_;
245  const std::optional<int> minDz_;
246  const std::optional<int> maxDz_;
247 
248  const std::optional<int> minDRSquared_;
249  const std::optional<int> maxDRSquared_;
250 
251  const std::optional<double> minInvMassSqrDiv2_;
252  const std::optional<double> maxInvMassSqrDiv2_;
253  const std::optional<double> minTransMassSqrDiv2_;
254  const std::optional<double> maxTransMassSqrDiv2_;
255 
256  const std::optional<double> minPTSquared_;
257  const std::optional<double> maxPTSquared_;
258 
259  const bool os_; // Opposite sign
260  const bool ss_; // Same sign
261 
263  const bool inv_mass_checks_;
264  };
265 
266 } // namespace l1t
267 
268 #endif // L1Trigger_Phase2L1GT_L1GTDeltaCut_h
static constexpr uint32_t DETA_LUT_SPLIT
Definition: L1GTDeltaCut.h:23
double eta_lsb() const
Definition: L1GTScales.h:64
const std::optional< double > minPTSquared_
Definition: L1GTDeltaCut.h:256
const std::optional< int > minDz_
Definition: L1GTDeltaCut.h:245
double pT_lsb() const
Definition: L1GTScales.h:62
double phi_lsb() const
Definition: L1GTScales.h:63
const std::optional< double > maxTransMassSqrDiv2_
Definition: L1GTDeltaCut.h:254
const std::optional< int > minDRSquared_
Definition: L1GTDeltaCut.h:248
const std::optional< int > maxDRSquared_
Definition: L1GTDeltaCut.h:249
hwEta_t hwEta() const
const bool enable_sanity_checks_
Definition: L1GTDeltaCut.h:262
const std::optional< int > minDPhi_
Definition: L1GTDeltaCut.h:243
delete x;
Definition: CaloConfig.h:22
Definition: config.py:1
const L1GTSingleInOutLUT coshEtaLUT_
Definition: L1GTDeltaCut.h:237
Log< level::Error, false > LogError
std::vector< InvariantMassError > InvariantMassErrorCollection
Definition: Electron.h:6
std::optional< T > getOptionalParam(const std::string &name, const edm::ParameterSet &config, std::function< T(K)> conv)
const std::optional< int > minDEta_
Definition: L1GTDeltaCut.h:241
const std::optional< double > minInvMassSqrDiv2_
Definition: L1GTDeltaCut.h:251
T sqrt(T t)
Definition: SSEVec.h:19
hwCharge_t hwCharge() const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Definition: value.py:1
bool checkObjects(const P2GTCandidate &obj1, const P2GTCandidate &obj2, InvariantMassErrorCollection &massErrors) const
Definition: L1GTDeltaCut.h:67
const L1GTSingleInOutLUT coshEtaLUT2_
Definition: L1GTDeltaCut.h:238
const std::optional< int > maxDEta_
Definition: L1GTDeltaCut.h:242
const std::optional< double > maxPTSquared_
Definition: L1GTDeltaCut.h:257
L1GTDeltaCut(const edm::ParameterSet &config, const edm::ParameterSet &lutConfig, const L1GTScales &scales, bool enable_sanity_checks=false, bool inv_mass_checks=false)
Definition: L1GTDeltaCut.h:25
static void fillLUTDescriptions(edm::ParameterSetDescription &desc)
hwZ0_t hwZ0() const
const std::optional< int > maxDPhi_
Definition: L1GTDeltaCut.h:244
ParameterSet const & getParameterSet(ParameterSetID const &id)
const std::optional< double > maxInvMassSqrDiv2_
Definition: L1GTDeltaCut.h:252
static void fillLUTDescriptions(edm::ParameterSetDescription &desc)
Definition: L1GTDeltaCut.h:201
static void fillPSetDescription(edm::ParameterSetDescription &desc)
Definition: L1GTDeltaCut.h:215
const std::optional< int > maxDz_
Definition: L1GTDeltaCut.h:246
const std::optional< double > minTransMassSqrDiv2_
Definition: L1GTDeltaCut.h:253
const L1GTSingleInOutLUT cosPhiLUT_
Definition: L1GTDeltaCut.h:239
hwPhi_t hwPhi() const
const L1GTScales & scales_
Definition: L1GTDeltaCut.h:235
const bool inv_mass_checks_
Definition: L1GTDeltaCut.h:263
hwPT_t hwPT() const