CMS 3D CMS Logo

L1GctJetFinderParams.cc
Go to the documentation of this file.
2 
3 #include <iostream>
4 #include <iomanip>
5 #include <cmath>
6 
8 
11 
12 using std::ios;
13 
14 const unsigned L1GctJetFinderParams::NUMBER_ETA_VALUES = 11;
16 
18  : rgnEtLsb_(0.),
19  htLsb_(0.),
20  cenJetEtSeed_(0.),
21  forJetEtSeed_(0.),
22  tauJetEtSeed_(0.),
23  tauIsoEtThreshold_(0.),
24  htJetEtThreshold_(0.),
25  mhtJetEtThreshold_(0.),
26  cenForJetEtaBoundary_(0),
27  corrType_(0),
28  jetCorrCoeffs_(),
29  tauCorrCoeffs_(),
30  convertToEnergy_(false),
31  energyConversionCoeffs_() {}
32 
34  double htLsb,
35  double cJetSeed,
36  double fJetSeed,
37  double tJetSeed,
38  double tauIsoEtThresh,
39  double htJetEtThresh,
40  double mhtJetEtThresh,
41  unsigned etaBoundary,
42  unsigned corrType,
43  const std::vector<std::vector<double> >& jetCorrCoeffs,
44  const std::vector<std::vector<double> >& tauCorrCoeffs,
45  bool convertToEnergy,
46  const std::vector<double>& energyConvCoeffs)
47  : rgnEtLsb_(rgnEtLsb),
48  htLsb_(htLsb),
49  cenJetEtSeed_(cJetSeed),
50  forJetEtSeed_(fJetSeed),
51  tauJetEtSeed_(tJetSeed),
52  tauIsoEtThreshold_(tauIsoEtThresh),
53  htJetEtThreshold_(htJetEtThresh),
54  mhtJetEtThreshold_(mhtJetEtThresh),
55  cenForJetEtaBoundary_(etaBoundary),
56  corrType_(corrType),
57  jetCorrCoeffs_(jetCorrCoeffs),
58  tauCorrCoeffs_(tauCorrCoeffs),
59  convertToEnergy_(convertToEnergy),
60  energyConversionCoeffs_(energyConvCoeffs) {
61  // check number of eta bins
64  LogDebug("L1-O2O") << "GCT jet corrections constructed with " << jetCorrCoeffs_.size() << " bins, expected "
65  << NUMBER_ETA_VALUES << std::endl;
66  LogDebug("L1-O2O") << "GCT tau corrections constructed with " << tauCorrCoeffs_.size() << " bins, expected "
67  << N_CENTRAL_ETA_VALUES << std::endl;
68  LogDebug("L1-O2O") << "GCT energy corrections constructed with " << energyConversionCoeffs_.size()
69  << " bins, expected " << NUMBER_ETA_VALUES << std::endl;
70 
71  throw cms::Exception("InconsistentConfig")
72  << "L1GctJetFinderParams constructed with wrong number of eta bins : " << jetCorrCoeffs_.size() << " jets, "
73  << tauCorrCoeffs_.size() << " taus, " << energyConversionCoeffs_.size() << " energy conversion bins"
74  << std::endl;
75  }
76 
77  // check number of coefficients against expectation
78  unsigned expCoeffs = 0;
79  if (corrType_ == 2)
80  expCoeffs = 8; // ORCA style
81  if (corrType_ == 3)
82  expCoeffs = 4; // Simple
83  if (corrType_ == 4)
84  expCoeffs = 15; // piecewise-cubic
85  if (corrType_ == 5)
86  expCoeffs = 6; // PF
87 
88  // correction types 1 and 4 can have any number of parameters
89  if (corrType_ != 1 && corrType_ != 4) {
90  std::vector<std::vector<double> >::const_iterator itr;
91  for (itr = jetCorrCoeffs_.begin(); itr != jetCorrCoeffs_.end(); ++itr) {
92  if (itr->size() != expCoeffs) {
93  throw cms::Exception("InconsistentConfig")
94  << "L1GctJetFinderParams constructed with " << itr->size() << " jet correction coefficients, when "
95  << expCoeffs << " expected" << std::endl;
96  }
97  }
98  for (itr = tauCorrCoeffs_.begin(); itr != tauCorrCoeffs_.end(); ++itr) {
99  if (itr->size() != expCoeffs) {
100  throw cms::Exception("InconsistentConfig")
101  << "L1GctJetFinderParams constructed with " << itr->size() << " tau correction coefficients, when "
102  << expCoeffs << " expected" << std::endl;
103  }
104  }
105  }
106 }
107 
109 
110 //---------------------------------------------------------------------------------------------
111 //
112 // set methods
113 //
114 
115 void L1GctJetFinderParams::setRegionEtLsb(const double rgnEtLsb) { rgnEtLsb_ = rgnEtLsb; }
116 
118  const double fJetSeed,
119  const double tJetSeed,
120  const unsigned etaBoundary) {
121  cenJetEtSeed_ = cJetSeed;
122  forJetEtSeed_ = fJetSeed;
123  tauJetEtSeed_ = tJetSeed;
124  cenForJetEtaBoundary_ = etaBoundary;
125 }
126 
128  const std::vector<std::vector<double> >& jetCorrCoeffs,
129  const std::vector<std::vector<double> >& tauCorrCoeffs) {
130  corrType_ = corrType;
131  jetCorrCoeffs_ = jetCorrCoeffs;
132  tauCorrCoeffs_ = tauCorrCoeffs;
133 }
134 
135 void L1GctJetFinderParams::setJetEtConvertToEnergyOn(const std::vector<double>& energyConvCoeffs) {
136  convertToEnergy_ = true;
137  energyConversionCoeffs_ = energyConvCoeffs;
138 }
139 
141  convertToEnergy_ = false;
142  energyConversionCoeffs_.clear();
143 }
144 
145 void L1GctJetFinderParams::setHtSumParams(const double htLsb, const double htJetEtThresh, const double mhtJetEtThresh) {
146  htLsb_ = htLsb;
147  htJetEtThreshold_ = htJetEtThresh;
148  mhtJetEtThreshold_ = mhtJetEtThresh;
149 }
150 
151 void L1GctJetFinderParams::setTauAlgorithmParams(const double tauIsoEtThresh) { tauIsoEtThreshold_ = tauIsoEtThresh; }
152 
153 void L1GctJetFinderParams::setParams(const double rgnEtLsb,
154  const double htLsb,
155  const double cJetSeed,
156  const double fJetSeed,
157  const double tJetSeed,
158  const double tauIsoEtThresh,
159  const double htJetEtThresh,
160  const double mhtJetEtThresh,
161  const unsigned etaBoundary,
162  const unsigned corrType,
163  const std::vector<std::vector<double> >& jetCorrCoeffs,
164  const std::vector<std::vector<double> >& tauCorrCoeffs) {
165  setRegionEtLsb(rgnEtLsb);
166  setSlidingWindowParams(cJetSeed, fJetSeed, tJetSeed, etaBoundary);
167  setJetEtCalibrationParams(corrType, jetCorrCoeffs, tauCorrCoeffs);
168  setHtSumParams(htLsb, htJetEtThresh, mhtJetEtThresh);
169  setTauAlgorithmParams(tauIsoEtThresh);
170 }
171 
172 //---------------------------------------------------------------------------------------------
173 //
174 // Jet Et correction methods
175 //
176 
177 double L1GctJetFinderParams::correctedEtGeV(const double et, const unsigned eta, const bool tauVeto) const {
178  if (eta >= NUMBER_ETA_VALUES) {
179  return 0;
180  } else {
181  double result = 0;
182  if ((eta >= cenForJetEtaBoundary_) || tauVeto) {
183  // Use jetCorrCoeffs for central and forward jets.
184  // In forward eta bins we ignore the tau flag (as in the firmware)
186  } else {
187  // Use tauCorrCoeffs for tau jets (in central eta bins)
189  }
190  if (convertToEnergy_) {
192  }
193  return result;
194  }
195 }
196 
198 uint16_t L1GctJetFinderParams::correctedEtGct(const double correctedEt) const {
199  double scaledEt = correctedEt / htLsb_;
200 
201  uint16_t jetEtOut = static_cast<uint16_t>(scaledEt);
202 
205  } else {
206  return jetEtOut;
207  }
208 }
209 
210 // private methods
211 
212 double L1GctJetFinderParams::correctionFunction(const double Et, const std::vector<double>& coeffs) const {
213  double result = 0;
214  switch (corrType_) {
215  case 0: // no correction
216  result = Et;
217  break;
218  case 1: // power series correction
219  result = powerSeriesCorrect(Et, coeffs);
220  break;
221  case 2: // ORCA style correction
222  result = orcaStyleCorrect(Et, coeffs);
223  break;
224  case 3: // simple correction (JetMEt style)
225  result = simpleCorrect(Et, coeffs);
226  break;
227  case 4: // piecwise cubic correction a la Greg Landsberg et al
228  result = piecewiseCubicCorrect(Et, coeffs);
229  break;
230  case 5: // PF correction
231  result = pfCorrect(Et, coeffs);
232  break;
233  default:
234  result = Et;
235  }
236  return result;
237 }
238 
239 double L1GctJetFinderParams::powerSeriesCorrect(const double Et, const std::vector<double>& coeffs) const {
240  double corrEt = Et;
241  for (unsigned i = 0; i < coeffs.size(); i++) {
242  corrEt += coeffs.at(i) * pow(Et, (int)i);
243  }
244  return corrEt;
245 }
246 
247 double L1GctJetFinderParams::orcaStyleCorrect(const double Et, const std::vector<double>& coeffs) const {
248  // The coefficients are arranged in groups of four
249  // The first in each group is a threshold value of Et.
250 
251  std::vector<double>::const_iterator next_coeff = coeffs.begin();
252  while (next_coeff != coeffs.end()) {
253  double threshold = *next_coeff++;
254  double A = *next_coeff++;
255  double B = *next_coeff++;
256  double C = *next_coeff++;
257  if (Et > threshold) {
258  // This function is an inverse quadratic:
259  // (input Et) = A + B*(output Et) + C*(output Et)^2
260  return 2 * (Et - A) / (B + sqrt(B * B - 4 * A * C + 4 * Et * C));
261  }
262  // If we are below all specified thresholds (or the vector is empty), return output=input.
263  }
264  return Et;
265 }
266 
267 double L1GctJetFinderParams::simpleCorrect(const double Et, const std::vector<double>& coeffs) const {
268  // function is :
269  // Et_out = A + B/[ (log10(Et_in))^C + D ] + E/Et_in
270  //
271  // fitcor_as_str = "[0]+[1]/(pow(log10(x),[2])+[3]) + [4]/x"
272  //
273 
274  return coeffs.at(0) + coeffs.at(1) / (pow(log10(Et), coeffs.at(2)) + coeffs.at(3)) + (coeffs.at(4) / Et);
275 }
276 
277 double L1GctJetFinderParams::piecewiseCubicCorrect(const double Et, const std::vector<double>& coeffs) const {
278  // The correction fuction is a set of 3rd order polynomials
279  // Et_out = Et_in + (p0 + p1*Et_in + p2*Et_in^2 + p3*Et_in^3)
280  // with different coefficients for different energy ranges.
281  // The parameters are arranged in groups of five.
282  // The first in each group is a threshold value of input Et,
283  // followed by the four coefficients for the cubic function.
284  double etOut = Et;
285  std::vector<double>::const_iterator next_coeff = coeffs.begin();
286  while (next_coeff != coeffs.end()) {
287  // Read the coefficients from the vector
288  double threshold = *next_coeff++;
289  double A = *next_coeff++; //p0
290  double B = *next_coeff++; //p1
291  double C = *next_coeff++; //p2
292  double D = *next_coeff++; //p3
293 
294  // Check we are in the right energy range and make correction
295  if (Et > threshold) {
296  etOut += (A + etOut * (B + etOut * (C + etOut * D)));
297  break;
298  }
299  }
300  return etOut;
301 }
302 
303 double L1GctJetFinderParams::pfCorrect(const double et, const std::vector<double>& coeffs) const {
304  //
305  // corr_factor = [0]+[1]/(pow(log10(x),2)+[2])+[3]*exp(-[4]*(log10(x)-[5])*(log10(x)-[5]))
306  // Et_out = Et_in * corr_factor
307  //
308 
309  return et * (coeffs.at(0) + coeffs.at(1) / (pow(log10(et), 2) + coeffs.at(2)) +
310  coeffs.at(3) * exp(-coeffs.at(4) * (log10(et) - coeffs.at(5)) * (log10(et) - coeffs.at(5))));
311 }
312 
313 std::ostream& operator<<(std::ostream& os, const L1GctJetFinderParams& fn) {
314  // os << std::setprecision(2);
315 
316  os << "=== Level-1 GCT : Jet Finder Parameters ===" << std::endl;
317  os << "RCT region LSB : " << std::fixed << fn.getRgnEtLsbGeV() << " GeV" << std::endl;
318  os << "Central jet seed threshold : " << std::fixed << fn.getCenJetEtSeedGeV() << " GeV" << std::endl;
319  os << "Tau jet seed threshold : " << std::fixed << fn.getTauJetEtSeedGeV() << " GeV" << std::endl;
320  os << "Forward jet seed threshold : " << std::fixed << fn.getForJetEtSeedGeV() << " GeV" << std::endl;
321  os << "Tau isolation threshold : " << std::fixed << fn.getTauIsoEtThresholdGeV() << " GeV" << std::endl;
322  os << "Ht jet Et threshold : " << std::fixed << fn.getHtJetEtThresholdGeV() << " GeV" << std::endl;
323  os << "MHt jet Et threshold : " << std::fixed << fn.getMHtJetEtThresholdGeV() << " GeV" << std::endl;
324  os << "Ht LSB : " << std::fixed << fn.getHtLsbGeV() << " GeV" << std::endl;
325  os << "Central/Forward boundary : " << std::fixed << fn.getCenForJetEtaBoundary() << std::endl;
326 
327  os << std::endl;
328 
329  os << std::setprecision(6);
330  os << ios::scientific;
331 
332  os << "=== Level-1 GCT : Jet Et Calibration Function ===" << std::endl;
333  if (fn.getCorrType() == 0) {
334  os << "No jet energy corrections applied" << std::endl;
335  } else {
336  switch (fn.getCorrType()) {
337  case 1:
338  os << "Function = Power series" << std::endl;
339  break;
340  case 2:
341  os << "Function = ORCA" << std::endl;
342  break;
343  case 3:
344  os << "Function = Simple" << std::endl;
345  break;
346  case 4:
347  os << "Function = PiecewiseCubic" << std::endl;
348  break;
349  case 5:
350  os << "Function = PF" << std::endl;
351  break;
352  default:
353  os << "Unrecognised" << std::endl;
354  break;
355  }
356  std::vector<std::vector<double> > jetCoeffs = fn.getJetCorrCoeffs();
357  std::vector<std::vector<double> > tauCoeffs = fn.getTauCorrCoeffs();
358 
359  os << "Non-tau jet correction coefficients" << std::endl;
360  for (unsigned i = 0; i < jetCoeffs.size(); i++) {
361  os << "Eta =" << std::setw(2) << i;
362  if (jetCoeffs.at(i).empty()) {
363  os << ", no coefficients";
364  } else {
365  os << " Coefficients = ";
366  for (unsigned j = 0; j < jetCoeffs.at(i).size(); j++) {
367  os << jetCoeffs.at(i).at(j) << ", ";
368  }
369  }
370  os << std::endl;
371  }
372  os << "Tau jet correction coefficients" << std::endl;
373  for (unsigned i = 0; i < tauCoeffs.size(); i++) {
374  os << "Eta =" << std::setw(2) << i;
375  if (tauCoeffs.at(i).empty()) {
376  os << ", no coefficients";
377  } else {
378  os << " Coefficients = ";
379  for (unsigned j = 0; j < tauCoeffs.at(i).size(); j++) {
380  os << tauCoeffs.at(i).at(j) << ", ";
381  }
382  }
383  os << std::endl;
384  }
385  }
386 
387  os.unsetf(ios::fixed | ios::scientific);
388 
389  return os;
390 }
double piecewiseCubicCorrect(const double Et, const std::vector< double > &coeffs) const
static const unsigned N_CENTRAL_ETA_VALUES
Number of eta bins used in correction.
void setHtSumParams(const double htLsb, const double htJetEtThresh, const double mhtJetEtThresh)
double correctedEtGeV(const double et, const unsigned eta, const bool tauVeto) const
Eta takes a value from 0-10, corresponding to jet regions running from eta=0.0 to eta=5...
Definition: APVGainStruct.h:7
uint16_t correctedEtGct(const double correctedEt) const
Convert the corrected Et value to a linear Et for Ht summing.
void setRegionEtLsb(const double rgnEtLsb)
double correctionFunction(const double Et, const std::vector< double > &coeffs) const
constexpr int pow(int x)
Definition: conifer.h:24
std::vector< std::vector< double > > tauCorrCoeffs_
double pfCorrect(const double Et, const std::vector< double > &coeffs) const
void setParams(const double rgnEtLsb, const double htLsb, const double cJetSeed, const double fJetSeed, const double tJetSeed, const double tauIsoEtThresh, const double htJetEtThresh, const double mhtJetEtThresh, const unsigned etaBoundary, const unsigned corrType, const std::vector< std::vector< double > > &jetCorrCoeffs, const std::vector< std::vector< double > > &tauCorrCoeffs)
T sqrt(T t)
Definition: SSEVec.h:19
void setJetEtConvertToEnergyOn(const std::vector< double > &energyConvCoeffs)
static const unsigned jetCalibratedEtMax
double orcaStyleCorrect(const double Et, const std::vector< double > &coeffs) const
static const unsigned NUMBER_ETA_VALUES
Number of eta bins used in correction.
double powerSeriesCorrect(const double Et, const std::vector< double > &coeffs) const
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
void setJetEtCalibrationParams(const unsigned corrType, const std::vector< std::vector< double > > &jetCorrCoeffs, const std::vector< std::vector< double > > &tauCorrCoeffs)
double simpleCorrect(const double Et, const std::vector< double > &coeffs) const
std::vector< std::vector< double > > jetCorrCoeffs_
void setTauAlgorithmParams(const double tauIsoEtThresh)
Definition: APVGainStruct.h:7
void setSlidingWindowParams(const double cJetSeed, const double fJetSeed, const double tJetSeed, const unsigned etaBoundary)
std::vector< double > energyConversionCoeffs_
std::ostream & operator<<(std::ostream &os, const L1GctJetFinderParams &fn)
Overload << operator.
#define LogDebug(id)