CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CalibratedElectronProducer.cc
Go to the documentation of this file.
1 // This file is imported from:
2 
3 // -*- C++ -*-
4 //
5 // Package: EgammaElectronProducers
6 // Class: CalibratedElectronProducer
7 //
17 
25 
33 
34 #include <iostream>
35 
36 using namespace edm ;
37 using namespace std ;
38 using namespace reco ;
39 
41 {
42  inputElectrons_ = cfg.getParameter<edm::InputTag>("inputElectronsTag");
43 
44  nameEnergyReg_ = cfg.getParameter<edm::InputTag>("nameEnergyReg");
45  nameEnergyErrorReg_ = cfg.getParameter<edm::InputTag>("nameEnergyErrorReg");
46 
47  recHitCollectionEB_ = cfg.getParameter<edm::InputTag>("recHitCollectionEB");
48  recHitCollectionEE_ = cfg.getParameter<edm::InputTag>("recHitCollectionEE");
49 
50 
51  nameNewEnergyReg_ = cfg.getParameter<std::string>("nameNewEnergyReg");
52  nameNewEnergyErrorReg_ = cfg.getParameter<std::string>("nameNewEnergyErrorReg");
53  newElectronName_ = cfg.getParameter<std::string>("outputGsfElectronCollectionLabel");
54 
55 
56  dataset = cfg.getParameter<std::string>("inputDataset");
57  isMC = cfg.getParameter<bool>("isMC");
58  updateEnergyError = cfg.getParameter<bool>("updateEnergyError");
59  lumiRatio = cfg.getParameter<double>("lumiRatio");
60  correctionsType = cfg.getParameter<int>("correctionsType");
61  applyLinearityCorrection = cfg.getParameter<bool>("applyLinearityCorrection");
62  combinationType = cfg.getParameter<int>("combinationType");
63  verbose = cfg.getParameter<bool>("verbose");
64  synchronization = cfg.getParameter<bool>("synchronization");
65  combinationRegressionInputPath = cfg.getParameter<std::string>("combinationRegressionInputPath");
66  scaleCorrectionsInputPath = cfg.getParameter<std::string>("scaleCorrectionsInputPath");
67  linCorrectionsInputPath = cfg.getParameter<std::string>("linearityCorrectionsInputPath");
68 
69  //basic checks
70  if ( isMC && ( dataset != "Summer11" && dataset != "Fall11"
71  && dataset!= "Summer12" && dataset != "Summer12_DR53X_HCP2012"
72  && dataset != "Summer12_LegacyPaper" ) )
73  {
74  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError") << "Unknown MC dataset";
75  }
76  if ( !isMC && ( dataset != "Prompt" && dataset != "ReReco"
77  && dataset != "Jan16ReReco" && dataset != "ICHEP2012"
78  && dataset != "Moriond2013" && dataset != "22Jan2013ReReco" ) )
79  {
80  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError") << "Unknown Data dataset";
81  }
82 
83  // Linearity correction only applied on combined momentum obtain with regression combination
84  if(combinationType!=3 && applyLinearityCorrection)
85  {
86  std::cout << "[CalibratedElectronProducer] "
87  << "Warning: you chose combinationType!=3 and applyLinearityCorrection=True. Linearity corrections are only applied on top of combination 3." << std::endl;
88  }
89 
90  std::cout << "[CalibratedGsfElectronProducer] Correcting scale for dataset " << dataset << std::endl;
91 
92  //initializations
93  std::string pathToDataCorr;
94  switch (correctionsType)
95  {
96  case 0:
97  break;
98  case 1:
99  if ( verbose )
100  {
101  std::cout << "You choose regression 1 scale corrections" << std::endl;
102  }
103  break;
104  case 2:
105  if ( verbose )
106  {
107  std::cout << "You choose regression 2 scale corrections." << std::endl;
108  }
109  break;
110  case 3:
111  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError")
112  << "You choose standard non-regression ecal energy scale corrections. They are not implemented yet.";
113  break;
114  default:
115  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError")
116  << "Unknown correctionsType !!!" ;
117  }
118 
119  theEnCorrector = new ElectronEnergyCalibrator
120  (
121  edm::FileInPath(scaleCorrectionsInputPath.c_str()).fullPath().c_str(),
122  edm::FileInPath(linCorrectionsInputPath.c_str()).fullPath().c_str(),
123  dataset,
124  correctionsType,
125  applyLinearityCorrection,
126  lumiRatio,
127  isMC,
128  updateEnergyError,
129  verbose,
130  synchronization
131  );
132 
133  if ( verbose )
134  {
135  std::cout<<"[CalibratedGsfElectronProducer] "
136  << "ElectronEnergyCalibrator object is created" << std::endl;
137  }
138 
139  myEpCombinationTool = new EpCombinationTool();
140  myEpCombinationTool->init
141  (
142  edm::FileInPath(combinationRegressionInputPath.c_str()).fullPath().c_str(),
143  "CombinationWeight"
144  );
145 
146  myCombinator = new ElectronEPcombinator();
147 
148  if ( verbose )
149  {
150  std::cout << "[CalibratedGsfElectronProducer] "
151  << "Combination tools are created and initialized" << std::endl;
152  }
153 
154  produces<edm::ValueMap<double> >(nameNewEnergyReg_);
155  produces<edm::ValueMap<double> >(nameNewEnergyErrorReg_);
156  produces<GsfElectronCollection> (newElectronName_);
157  geomInitialized_ = false;
158 }
159 
161 {}
162 
164 {
165  if (!geomInitialized_)
166  {
167  edm::ESHandle<CaloTopology> theCaloTopology;
168  setup.get<CaloTopologyRecord>().get(theCaloTopology);
169  ecalTopology_ = & (*theCaloTopology);
170 
171  edm::ESHandle<CaloGeometry> theCaloGeometry;
172  setup.get<CaloGeometryRecord>().get(theCaloGeometry);
173  caloGeometry_ = & (*theCaloGeometry);
174  geomInitialized_ = true;
175  }
176 
177  // Read GsfElectrons
179  event.getByLabel(inputElectrons_,oldElectronsH) ;
180 
181  // Read RecHits
184  event.getByLabel( recHitCollectionEB_, pEBRecHits );
185  event.getByLabel( recHitCollectionEE_, pEERecHits );
186 
187  // ReadValueMaps
188  edm::Handle<edm::ValueMap<double> > valMapEnergyH;
189  event.getByLabel(nameEnergyReg_,valMapEnergyH);
190  edm::Handle<edm::ValueMap<double> > valMapEnergyErrorH;
191  event.getByLabel(nameEnergyErrorReg_,valMapEnergyErrorH);
192 
193  // Prepare output collections
194  std::auto_ptr<GsfElectronCollection> electrons( new reco::GsfElectronCollection ) ;
195  // Fillers for ValueMaps:
196  std::auto_ptr<edm::ValueMap<double> > regrNewEnergyMap(new edm::ValueMap<double>() );
197  edm::ValueMap<double>::Filler energyFiller(*regrNewEnergyMap);
198 
199  std::auto_ptr<edm::ValueMap<double> > regrNewEnergyErrorMap(new edm::ValueMap<double>() );
200  edm::ValueMap<double>::Filler energyErrorFiller(*regrNewEnergyErrorMap);
201 
202  // first clone the initial collection
203  unsigned nElectrons = oldElectronsH->size();
204  for( unsigned iele = 0; iele < nElectrons; ++iele )
205  {
206  electrons->push_back((*oldElectronsH)[iele]);
207  }
208 
209  std::vector<double> regressionValues;
210  std::vector<double> regressionErrorValues;
211  regressionValues.reserve(nElectrons);
212  regressionErrorValues.reserve(nElectrons);
213 
214  if ( correctionsType != 0 )
215  {
216  for ( unsigned iele = 0; iele < nElectrons ; ++iele)
217  {
218  reco::GsfElectron & ele ( (*electrons)[iele]);
219  reco::GsfElectronRef elecRef(oldElectronsH,iele);
220  double regressionEnergy = (*valMapEnergyH)[elecRef];
221  double regressionEnergyError = (*valMapEnergyErrorH)[elecRef];
222 
223  regressionValues.push_back(regressionEnergy);
224  regressionErrorValues.push_back(regressionEnergyError);
225 
226  // r9
227  const EcalRecHitCollection * recHits=0;
228  if( ele.isEB() )
229  {
230  recHits = pEBRecHits.product();
231  } else recHits = pEERecHits.product();
232 
233  SuperClusterHelper mySCHelper( &(ele), recHits, ecalTopology_, caloGeometry_ );
234 
235  int elClass = -1;
236  int run = event.run();
237 
238  float r9 = mySCHelper.r9();
239  double correctedEcalEnergy = ele.correctedEcalEnergy();
240  double correctedEcalEnergyError = ele.correctedEcalEnergyError();
241  double trackMomentum = ele.trackMomentumAtVtx().R();
242  double trackMomentumError = ele.trackMomentumError();
243  double combinedMomentum = ele.p();
244  double combinedMomentumError = ele.p4Error(ele.candidateP4Kind());
245  // FIXME : p4Error not filled for pure tracker electrons
246  // Recompute it using the parametrization implemented in
247  // RecoEgamma/EgammaElectronAlgos/src/ElectronEnergyCorrector.cc::simpleParameterizationUncertainty()
248  if( !ele.ecalDrivenSeed() )
249  {
250  double error = 999. ;
251  double momentum = (combinedMomentum<15. ? 15. : combinedMomentum);
252  if ( ele.isEB() )
253  {
254  float parEB[3] = { 5.24e-02, 2.01e-01, 1.00e-02};
255  error = momentum * sqrt( pow(parEB[0]/sqrt(momentum),2) + pow(parEB[1]/momentum,2) + pow(parEB[2],2) );
256  }
257  else if ( ele.isEE() )
258  {
259  float parEE[3] = { 1.46e-01, 9.21e-01, 1.94e-03} ;
260  error = momentum * sqrt( pow(parEE[0]/sqrt(momentum),2) + pow(parEE[1]/momentum,2) + pow(parEE[2],2) );
261  }
262  combinedMomentumError = error;
263  }
264 
265  if (ele.classification() == reco::GsfElectron::GOLDEN) {elClass = 0;}
266  if (ele.classification() == reco::GsfElectron::BIGBREM) {elClass = 1;}
267  if (ele.classification() == reco::GsfElectron::BADTRACK) {elClass = 2;}
268  if (ele.classification() == reco::GsfElectron::SHOWERING) {elClass = 3;}
269  if (ele.classification() == reco::GsfElectron::GAP) {elClass = 4;}
270 
271  SimpleElectron mySimpleElectron
272  (
273  run,
274  elClass,
275  r9,
276  correctedEcalEnergy,
277  correctedEcalEnergyError,
278  trackMomentum,
279  trackMomentumError,
280  regressionEnergy,
281  regressionEnergyError,
282  combinedMomentum,
283  combinedMomentumError,
284  ele.superCluster()->eta(),
285  ele.isEB(),
286  isMC,
287  ele.ecalDriven(),
288  ele.trackerDrivenSeed()
289  );
290 
291  // energy calibration for ecalDriven electrons
292  if ( ele.core()->ecalDrivenSeed() || correctionsType==2 || combinationType==3 )
293  {
294  theEnCorrector->calibrate(mySimpleElectron);
295 
296  // E-p combination
297 
298  switch ( combinationType )
299  {
300  case 0:
301  if ( verbose )
302  {
303  std::cout << "[CalibratedGsfElectronProducer] "
304  << "You choose not to combine." << std::endl;
305  }
306  break;
307  case 1:
308  if ( verbose )
309  {
310  std::cout << "[CalibratedGsfElectronProducer] "
311  << "You choose corrected regression energy for standard combination" << std::endl;
312  }
313  myCombinator->setCombinationMode(1);
314  myCombinator->combine(mySimpleElectron);
315  break;
316  case 2:
317  if ( verbose )
318  {
319  std::cout << "[CalibratedGsfElectronProducer] "
320  << "You choose uncorrected regression energy for standard combination" << std::endl;
321  }
322  myCombinator->setCombinationMode(2);
323  myCombinator->combine(mySimpleElectron);
324  break;
325  case 3:
326  if ( verbose )
327  {
328  std::cout << "[CalibratedGsfElectronProducer] "
329  << "You choose regression combination." << std::endl;
330  }
331  myEpCombinationTool->combine(mySimpleElectron);
332  theEnCorrector->correctLinearity(mySimpleElectron);
333  break;
334  default:
335  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError")
336  << "Unknown combination Type !!!" ;
337  }
338 
339  math::XYZTLorentzVector oldMomentum = ele.p4() ;
340  math::XYZTLorentzVector newMomentum_ ;
341  newMomentum_ = math::XYZTLorentzVector
342  ( oldMomentum.x()*mySimpleElectron.getCombinedMomentum()/oldMomentum.t(),
343  oldMomentum.y()*mySimpleElectron.getCombinedMomentum()/oldMomentum.t(),
344  oldMomentum.z()*mySimpleElectron.getCombinedMomentum()/oldMomentum.t(),
345  mySimpleElectron.getCombinedMomentum() ) ;
346 
347  ele.correctMomentum
348  (
349  newMomentum_,
350  mySimpleElectron.getTrackerMomentumError(),
351  mySimpleElectron.getCombinedMomentumError()
352  );
353 
354  if ( verbose )
355  {
356  std::cout << "[CalibratedGsfElectronProducer] Combined momentum after saving "
357  << ele.p4().t() << std::endl;
358  }
359  }// end of if (ele.core()->ecalDrivenSeed())
360  }// end of loop on electrons
361  } else
362  {
363  if ( verbose )
364  {
365  std::cout << "[CalibratedGsfElectronProducer] "
366  << "You choose not to correct. Uncorrected Regression Energy is taken." << std::endl;
367  }
368  }
369 
370  // Save the electrons
371  const edm::OrphanHandle<reco::GsfElectronCollection> gsfNewElectronHandle = event.put(electrons, newElectronName_) ;
372  energyFiller.insert(gsfNewElectronHandle,regressionValues.begin(),regressionValues.end());
373  energyFiller.fill();
374  energyErrorFiller.insert(gsfNewElectronHandle,regressionErrorValues.begin(),regressionErrorValues.end());
375  energyErrorFiller.fill();
376 
377  event.put(regrNewEnergyMap,nameNewEnergyReg_);
378  event.put(regrNewEnergyErrorMap,nameNewEnergyErrorReg_);
379 }
380 
T getParameter(std::string const &) const
virtual double p() const
magnitude of momentum vector
float trackMomentumError() const
Definition: GsfElectron.h:715
const LorentzVector & p4(P4Kind kind) const
Definition: GsfElectron.cc:204
P4Kind candidateP4Kind() const
Definition: GsfElectron.h:719
void correctMomentum(const LorentzVector &p4, float trackMomentumError, float p4Error)
Definition: GsfElectron.h:734
math::XYZVectorF trackMomentumAtVtx() const
Definition: GsfElectron.h:272
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:53
float p4Error(P4Kind kind) const
Definition: GsfElectron.cc:216
DEFINE_FWK_MODULE(HiMixingModule)
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
bool isEE() const
Definition: GsfElectron.h:331
bool isEB() const
Definition: GsfElectron.h:330
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
virtual void produce(edm::Event &, const edm::EventSetup &)
T sqrt(T t)
Definition: SSEVec.h:46
virtual SuperClusterRef superCluster() const
reference to a SuperCluster
Definition: GsfElectron.h:168
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
float correctedEcalEnergy() const
Definition: GsfElectron.h:713
Classification classification() const
Definition: GsfElectron.h:635
const T & get() const
Definition: EventSetup.h:55
tuple dataset
Definition: dataset.py:393
T const * product() const
Definition: Handle.h:74
virtual GsfElectronCoreRef core() const
Definition: GsfElectron.cc:8
float correctedEcalEnergyError() const
Definition: GsfElectron.h:714
bool trackerDrivenSeed() const
Definition: GsfElectron.h:173
tuple cout
Definition: gather_cfg.py:121
CalibratedElectronProducer(const edm::ParameterSet &)
bool ecalDriven() const
Definition: GsfElectron.cc:147
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
bool ecalDrivenSeed() const
Definition: GsfElectron.h:172