CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ElectronEnergyCalibrator.cc
Go to the documentation of this file.
2 
3 #include <CLHEP/Random/RandGaussQ.h>
4 #include <CLHEP/Random/RandFlat.h>
5 #include <CLHEP/Random/Random.h>
9 
10 /****************************************************************************
11  *
12  * Propagate SC calibration from Zee fit to the electrons
13  *
14  ****************************************************************************/
15 
16 #include <string>
17 #include <vector>
18 #include <fstream>
19 #include <sstream>
20 #include <iostream>
21 
22 using std::string;
23 using std::vector;
24 using std::ifstream;
25 using std::istringstream;
26 using std::cout;
27 using namespace edm;
28 
30 {
31  if ( !isMC_ ) // DATA
32  {
33  if ( verbose_ )
34  {
35  std::cout << "[ElectronEnergyCalibrator] Initialization in DATA mode" << std::endl;
36  }
37 
38  ifstream fin(pathData_.c_str());
39 
40  if (!fin){
41  throw cms::Exception("Configuration")
42  << "[ElectronEnergyCalibrator] Cannot open the file "
43  << pathData_ << "\n It is not found, missed or corrupted" ;
44  } else
45  {
46  if ( verbose_ )
47  {
48  std::cout << "[ElectronEnergyCalibrator] File "
49  << pathData_ << " succesfully opened" << std::endl;
50  }
51 
52  string s;
53  vector<string> selements;
54  string delimiter = ",";
55  nCorrValRaw = 0;
56 
57  while ( !fin.eof() )
58  {
59  getline(fin, s);
60  if ( !s.empty() )
61  {
62  splitString(s, selements, delimiter);
63  corrValArray[nCorrValRaw].nRunMin = stringToDouble(selements[0]);
64  corrValArray[nCorrValRaw].nRunMax = stringToDouble(selements[1]);
65  corrValArray[nCorrValRaw].corrCat0 = stringToDouble(selements[2]);
66  corrValArray[nCorrValRaw].corrCat1 = stringToDouble(selements[3]);
67  corrValArray[nCorrValRaw].corrCat2 = stringToDouble(selements[4]);
68  corrValArray[nCorrValRaw].corrCat3 = stringToDouble(selements[5]);
69  corrValArray[nCorrValRaw].corrCat4 = stringToDouble(selements[6]);
70  corrValArray[nCorrValRaw].corrCat5 = stringToDouble(selements[7]);
71  corrValArray[nCorrValRaw].corrCat6 = stringToDouble(selements[8]);
72  corrValArray[nCorrValRaw].corrCat7 = stringToDouble(selements[9]);
73 
74  nCorrValRaw++;
75 
76  selements.clear();
77  }
78  }
79 
80  fin.close();
81 
82  if ( verbose_ )
83  {
84  std::cout << "[ElectronEnergyCalibrator] File closed" << std::endl;
85  }
86 
87  }
88  // linearity corrections data
89  if(applyLinearityCorrection_)
90  {
91  ifstream finlin(pathLinData_.c_str());
92 
93  if (!finlin)
94  {
95  throw cms::Exception("Configuration")
96  << "[ElectronEnergyCalibrator] Cannot open the file "<< pathLinData_ << "\n It is not found, missed or corrupted" ;
97  } else
98  {
99  if (verbose_)
100  {
101  std::cout<<"[ElectronEnergyCalibrator] File with Linearity Corrections "<<pathLinData_<<" succesfully opened"<<std::endl;
102  }
103 
104  string s;
105  vector<string> selements;
106  string delimiter = ",";
107  nLinCorrValRaw = 0;
108 
109  while ( !finlin.eof() )
110  {
111  getline(finlin, s);
112  if ( !s.empty() )
113  {
114  splitString(s, selements, delimiter);
115 
116  linCorrValArray[nLinCorrValRaw].ptMin = stringToDouble(selements[0]);
117  linCorrValArray[nLinCorrValRaw].ptMax = stringToDouble(selements[1]);
118  linCorrValArray[nLinCorrValRaw].corrCat0 = stringToDouble(selements[2]);
119  linCorrValArray[nLinCorrValRaw].corrCat1 = stringToDouble(selements[3]);
120  linCorrValArray[nLinCorrValRaw].corrCat2 = stringToDouble(selements[4]);
121  linCorrValArray[nLinCorrValRaw].corrCat3 = stringToDouble(selements[5]);
122  linCorrValArray[nLinCorrValRaw].corrCat4 = stringToDouble(selements[6]);
123  linCorrValArray[nLinCorrValRaw].corrCat5 = stringToDouble(selements[7]);
124 
125  nLinCorrValRaw++;
126 
127  selements.clear();
128  }
129  }
130 
131  finlin.close();
132 
133  if (verbose_)
134  {
135  std::cout<<"[ElectronEnergyCalibrator] File closed"<<std::endl;
136  }
137  }
138  }
139  } else // MC
140  {
141  if ( verbose_ )
142  {
143  std::cout << "[ElectronEnergyCalibrator] Initialization in MC mode" << std::endl;
144  }
145  }
146 }
147 
148 void ElectronEnergyCalibrator::splitString(const string &fullstr, vector<string> &elements, const string &delimiter)
149 {
150  string::size_type lastpos = fullstr.find_first_not_of(delimiter, 0);
151  string::size_type pos = fullstr.find_first_of(delimiter, lastpos);
152 
153  while ( ( string::npos != pos ) || ( string::npos != lastpos ) )
154  {
155  elements.push_back(fullstr.substr(lastpos, pos-lastpos));
156  lastpos = fullstr.find_first_not_of(delimiter, pos);
157  pos = fullstr.find_first_of(delimiter, lastpos);
158  }
159 }
160 
162 {
163  istringstream stm;
164  double val = 0;
165  stm.str(str);
166  stm >> val;
167  return val;
168 }
169 
171 {
172  double scale = 1.0;
173  double dsigMC=0.;
174  double corrMC=0.;
175  double run_ = electron.getRunNumber();
176  bool isEB = electron.isEB();
177  double eta = electron.getEta();
178  double r9 = electron.getR9();
179 
180  switch ( correctionsType_ )
181  {
182  case 1:
183  if ( verbose_ )
184  {
185  std::cout << "[ElectronEnergyCalibrator] Using regression energy for calibration" << std::endl;
186  }
187  newEnergy_ = electron.getRegEnergy();
188  newEnergyError_ = electron.getRegEnergyError();
189  break;
190  case 2:
191  if( verbose_ )
192  {
193  std::cout << "[ElectronEnergyCalibrator] Using scale corrections for new regression" << std::endl;
194  }
195  newEnergy_ = electron.getRegEnergy();
196  newEnergyError_ = electron.getRegEnergyError();
197  break;
198  case 3:
199  if ( verbose_ )
200  {
201  std::cout << "[ElectronEnergyCalibrator] Using standard ecal energy for calibration" << std::endl;
202  }
203  newEnergy_ = electron.getSCEnergy();
204  newEnergyError_ = electron.getSCEnergyError();
205  break;
206  }
207 
209  if ( !rng.isAvailable() )
210  {
211  throw cms::Exception("Configuration")
212  << "XXXXXXX requires the RandomNumberGeneratorService\n"
213  "which is not present in the configuration file. You must add the service\n"
214  "in the configuration file or remove the modules that require it.";
215  }
216 
217  if (!isMC_ )
218  {
219  for ( int i=0; i < nCorrValRaw; i++ )
220  {
221  if ( (run_ >= corrValArray[i].nRunMin ) && ( run_ <= corrValArray[i].nRunMax ) )
222  {
223  if ( isEB )
224  {
225  if ( fabs(eta) < 1 )
226  {
227  if ( r9<0.94 )
228  {
229  scale = corrValArray[i].corrCat0;
230  } else
231  {
232  scale = corrValArray[i].corrCat1;
233  }
234  } else
235  {
236  if ( r9<0.94 )
237  {
238  scale = corrValArray[i].corrCat2;
239  } else
240  {
241  scale = corrValArray[i].corrCat3;
242  }
243  }
244  } else
245  {
246  if ( fabs(eta) < 2 )
247  {
248  if ( r9<0.94 )
249  {
250  scale = corrValArray[i].corrCat4;
251  } else
252  {
253  scale = corrValArray[i].corrCat5;
254  }
255  } else
256  {
257  if ( r9<0.94 )
258  {
259  scale = corrValArray[i].corrCat6;
260  } else
261  {
262  scale = corrValArray[i].corrCat7;
263  }
264  }
265  }
266  }
267  }
268  newEnergy_ = newEnergy_*scale;
269  }
270 
271  switch ( correctionsType_ )
272  {
273  case 1:
274  // Implementation of the MC smearing for regression energy type 1
275  if ( dataset_ == "Summer12_DR53X_HCP2012" || dataset_ == "Moriond2013" )
276  {
277  if ( !isMC_ )
278  {
279  if ( run_ <= 203002 )
280  {
281  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0103;
282  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0090;
283  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0190;
284  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0156;
285  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0269;
286  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0287;
287  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0364;
288  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0321;
289  } else
290  {
291  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0109;
292  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0099;
293  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0182;
294  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0200;
295  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0282;
296  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0309;
297  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0386;
298  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0359;
299  }
300  } else
301  {
302  CLHEP::RandFlat flatRandom(rng->getEngine(streamID));
303  double rn = flatRandom.fire();
304  if ( rn > lumiRatio_ )
305  {
306  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0109;
307  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0099;
308  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0182;
309  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0200;
310  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0282;
311  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0309;
312  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0386;
313  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0359;
314  } else
315  {
316  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0103;
317  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0090;
318  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0190;
319  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0156;
320  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0269;
321  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0287;
322  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0364;
323  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0321;
324  }
325  if ( lumiRatio_ == 0.0 )
326  {
327  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0103;
328  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0090;
329  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0190;
330  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0156;
331  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0269;
332  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0287;
333  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0364;
334  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0321;
335  }
336  if ( lumiRatio_ == 1.0 )
337  {
338  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0109;
339  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0099;
340  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0182;
341  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0200;
342  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0282;
343  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0309;
344  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0386;
345  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0359;
346  }
347  }
348  }
349  break;
350 
351  case 2:
352  // Implementation of the MC smearing for regression energy type 2
353  if ( dataset_ == "Summer12_LegacyPaper" || dataset_ == "22Jan2013ReReco" )
354  {
355  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0094;
356  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0092;
357  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0182;
358  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0139;
359  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0220;
360  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0229;
361  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0290;
362  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0234;
363  }
364  break;
365 
366  case 3:
367  // standard SC energy scale corrections implementation
368  if ( dataset_ == "Summer11" || dataset_ == "ReReco" )
369  { // values from https://indico.cern.ch/conferenceDisplay.py?confId=146386
370  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.01;
371  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0099;
372  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0217;
373  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0157;
374  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0326;
375  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0330;
376  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0331;
377  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0378;
378  } else if ( dataset_ == "Fall11" || dataset_ == "Jan16ReReco" )
379  { // values from https://hypernews.cern.ch/HyperNews/CMS/get/higgs2g/634.html, consistant with Jan16ReReco corrections
380  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0096;
381  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0074;
382  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0196;
383  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0141;
384  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0279;
385  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0268;
386  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0301;
387  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0293;
388  } else if ( dataset_ == "Summer12" || dataset_ == "ICHEP2012" )
389  { // new values from https://twiki.cern.ch/twiki/pub/CMS/EcalEnergyResolutionWithZee/oriented-ICHEP-scales_resolution.pdf
390  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0119;
391  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0107;
392  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0240;
393  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0149;
394  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0330;
395  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0375;
396  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0602;
397  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0607;
398  } else if ( dataset_ == "Summer12_DR53X_HCP2012" || dataset_ == "Moriond2013" )
399  {
400  if ( isEB && fabs(eta) < 1 && r9 < 0.94 ) dsigMC = 0.0099;
401  if ( isEB && fabs(eta) < 1 && r9 >= 0.94 ) dsigMC = 0.0103;
402  if ( isEB && fabs(eta) >= 1 && r9 < 0.94 ) dsigMC = 0.0219;
403  if ( isEB && fabs(eta) >= 1 && r9 >= 0.94 ) dsigMC = 0.0158;
404  if ( !isEB && fabs(eta) < 2 && r9 < 0.94 ) dsigMC = 0.0222;
405  if ( !isEB && fabs(eta) < 2 && r9 >= 0.94 ) dsigMC = 0.0298;
406  if ( !isEB && fabs(eta) >= 2 && r9 < 0.94 ) dsigMC = 0.0318;
407  if ( !isEB && fabs(eta) >= 2 && r9 >= 0.94 ) dsigMC = 0.0302;
408  }
409  break;
410  }
411 
412  if ( isMC_ )
413  {
414  CLHEP::RandGaussQ gaussDistribution(rng->getEngine(streamID), 1.,dsigMC);
415  corrMC = gaussDistribution.fire();
416  if ( verbose_ )
417  {
418  std::cout << "[ElectronEnergyCalibrator] unsmeared energy " << newEnergy_ << std::endl;
419  }
420  if ( synchronization_ )
421  {
422  std::cout << "[ElectronEnergyCalibrator] "
423  << "======================= SYNCRONIZATION MODE! ======================="
424  << std::endl;
425  newEnergy_ = newEnergy_*(1+dsigMC);
426  } else
427  {
428  newEnergy_ = newEnergy_*corrMC;
429  }
430  if ( verbose_ )
431  {
432  std::cout << "[ElectronEnergyCalibrator] smeared energy " << newEnergy_ << std::endl;
433  }
434  }
435 
436  // correct energy error for MC and for data as error is obtained from (ideal) MC parametrisation
437  if ( updateEnergyErrors_ )
438  {
439  newEnergyError_ = sqrt(newEnergyError_*newEnergyError_ + dsigMC*dsigMC*newEnergy_*newEnergy_);
440  }
441  if ( verbose_ )
442  {
443  std::cout << "[ElectronEnergyCalibrator] initial energy "
444  << electron.getRegEnergy() << " recalibrated energy " << newEnergy_ << std::endl;
445  }
446  if ( verbose_ )
447  {
448  std::cout << "[ElectronEnergyCalibrator] initial energy error "
449  << electron.getRegEnergyError() << " recalibrated energy error "
450  << newEnergyError_ << std::endl;
451  }
452 
453  electron.setNewEnergy(newEnergy_);
454  electron.setNewEnergyError(newEnergyError_);
455 }
456 
458 {
459  if(!isMC_ && applyLinearityCorrection_)
460  {
461  bool isEB = electron.isEB();
462  double eta = electron.getEta();
463  double theta = 2*atan(exp(-eta));
464  double p = electron.getCombinedMomentum();
465  double pt = p * fabs(sin(theta));
466  int classification = electron.getElClass();
467  double linscale = 0.;
468 
469  for (int i=0; i < nLinCorrValRaw; i++)
470  {
471  if ((pt >= linCorrValArray[i].ptMin) && (pt <= linCorrValArray[i].ptMax))
472  {
473  if (isEB)
474  {
475  if (fabs(eta) < 1)
476  {
477  if (classification<2)
478  {
479  linscale = linCorrValArray[i].corrCat0;
480  } else
481  {
482  linscale = linCorrValArray[i].corrCat3;
483  }
484  } else
485  {
486  if (classification<2)
487  {
488  linscale = linCorrValArray[i].corrCat1;
489  } else
490  {
491  linscale = linCorrValArray[i].corrCat4;
492  }
493  }
494  } else // !isEB
495  {
496  if (classification<2)
497  {
498  linscale = linCorrValArray[i].corrCat2;
499  } else
500  {
501  linscale = linCorrValArray[i].corrCat5;
502  }
503  }
504  }
505  }
506  double newP = p/(1.+linscale);
507  if (verbose_)
508  {
509  std::cout << "[ElectronEnergyCalibrator] Applying a linearity correction of " << 1./(1.+linscale) << " to " << pt << " GeV in pt" << std::endl;
510  }
511  electron.setCombinedMomentum(newP);
512  if (verbose_)
513  {
514  std::cout << "[ElectronEnergyCalibrator] calibrated transverse momentum " << pt << " GeV recalibrated for linearity to momentum " << electron.getCombinedMomentum()*fabs(sin(theta)) << " GeV" << std::endl;
515  }
516  }
517 }
double getSCEnergy()
int i
Definition: DBlmapReader.cc:9
double getRegEnergyError()
void setNewEnergyError(double newEnergyError)
void setCombinedMomentum(double combinedMomentum)
void setNewEnergy(double newEnergy)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Theta< T > theta() const
list elements
Definition: asciidump.py:414
void calibrate(SimpleElectron &electron, edm::StreamID const &)
std::vector< std::string > splitString(const std::string &fLine)
uint16_t size_type
double getCombinedMomentum()
void splitString(const string &fullstr, vector< string > &elements, const string &delimiter)
T sqrt(T t)
Definition: SSEVec.h:48
bool isAvailable() const
Definition: Service.h:46
double stringToDouble(const string &str)
void correctLinearity(SimpleElectron &electron)
double getSCEnergyError()
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &) const =0
Use this engine in event methods.
tuple cout
Definition: gather_cfg.py:121
double getRegEnergy()