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 
31 
32 #include <iostream>
33 
35 {
36  inputElectronsToken_ = consumes<reco::GsfElectronCollection>(cfg.getParameter<edm::InputTag>("inputElectronsTag"));
37 
38  energyRegToken_ = consumes<edm::ValueMap<double> >(cfg.getParameter<edm::InputTag>("nameEnergyReg"));
39  energyErrorRegToken_ = consumes<edm::ValueMap<double> >(cfg.getParameter<edm::InputTag>("nameEnergyErrorReg"));
40 
41  recHitCollectionEBToken_ = consumes<EcalRecHitCollection>(cfg.getParameter<edm::InputTag>("recHitCollectionEB"));
42  recHitCollectionEEToken_ = consumes<EcalRecHitCollection>(cfg.getParameter<edm::InputTag>("recHitCollectionEE"));
43 
44 
45  nameNewEnergyReg_ = cfg.getParameter<std::string>("nameNewEnergyReg");
46  nameNewEnergyErrorReg_ = cfg.getParameter<std::string>("nameNewEnergyErrorReg");
47  newElectronName_ = cfg.getParameter<std::string>("outputGsfElectronCollectionLabel");
48 
49 
50  dataset = cfg.getParameter<std::string>("inputDataset");
51  isMC = cfg.getParameter<bool>("isMC");
52  updateEnergyError = cfg.getParameter<bool>("updateEnergyError");
53  lumiRatio = cfg.getParameter<double>("lumiRatio");
54  correctionsType = cfg.getParameter<int>("correctionsType");
55  applyLinearityCorrection = cfg.getParameter<bool>("applyLinearityCorrection");
56  combinationType = cfg.getParameter<int>("combinationType");
57  verbose = cfg.getParameter<bool>("verbose");
58  synchronization = cfg.getParameter<bool>("synchronization");
59  combinationRegressionInputPath = cfg.getParameter<std::string>("combinationRegressionInputPath");
60  scaleCorrectionsInputPath = cfg.getParameter<std::string>("scaleCorrectionsInputPath");
61  linCorrectionsInputPath = cfg.getParameter<std::string>("linearityCorrectionsInputPath");
62 
63  //basic checks
64  if ( isMC && ( dataset != "Summer11" && dataset != "Fall11"
65  && dataset!= "Summer12" && dataset != "Summer12_DR53X_HCP2012"
66  && dataset != "Summer12_LegacyPaper" ) )
67  {
68  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError") << "Unknown MC dataset";
69  }
70  if ( !isMC && ( dataset != "Prompt" && dataset != "ReReco"
71  && dataset != "Jan16ReReco" && dataset != "ICHEP2012"
72  && dataset != "Moriond2013" && dataset != "22Jan2013ReReco" ) )
73  {
74  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError") << "Unknown Data dataset";
75  }
76 
77  // Linearity correction only applied on combined momentum obtain with regression combination
78  if(combinationType!=3 && applyLinearityCorrection)
79  {
80  std::cout << "[CalibratedElectronProducer] "
81  << "Warning: you chose combinationType!=3 and applyLinearityCorrection=True. Linearity corrections are only applied on top of combination 3." << std::endl;
82  }
83 
84  std::cout << "[CalibratedGsfElectronProducer] Correcting scale for dataset " << dataset << std::endl;
85 
86  //initializations
87  std::string pathToDataCorr;
88  switch (correctionsType)
89  {
90  case 0:
91  break;
92  case 1:
93  if ( verbose )
94  {
95  std::cout << "You choose regression 1 scale corrections" << std::endl;
96  }
97  break;
98  case 2:
99  if ( verbose )
100  {
101  std::cout << "You choose regression 2 scale corrections." << std::endl;
102  }
103  break;
104  case 3:
105  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError")
106  << "You choose standard non-regression ecal energy scale corrections. They are not implemented yet.";
107  break;
108  default:
109  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError")
110  << "Unknown correctionsType !!!" ;
111  }
112 
114  (
115  edm::FileInPath(scaleCorrectionsInputPath.c_str()).fullPath().c_str(),
116  edm::FileInPath(linCorrectionsInputPath.c_str()).fullPath().c_str(),
117  dataset,
120  lumiRatio,
121  isMC,
123  verbose,
125  );
126 
127  if ( verbose )
128  {
129  std::cout<<"[CalibratedGsfElectronProducer] "
130  << "ElectronEnergyCalibrator object is created" << std::endl;
131  }
132 
135  (
136  edm::FileInPath(combinationRegressionInputPath.c_str()).fullPath().c_str(),
137  "CombinationWeight"
138  );
139 
141 
142  if ( verbose )
143  {
144  std::cout << "[CalibratedGsfElectronProducer] "
145  << "Combination tools are created and initialized" << std::endl;
146  }
147 
148  produces<edm::ValueMap<double> >(nameNewEnergyReg_);
149  produces<edm::ValueMap<double> >(nameNewEnergyErrorReg_);
150  produces<reco::GsfElectronCollection> (newElectronName_);
151  geomInitialized_ = false;
152 }
153 
155 {}
156 
158 {
159  if (!geomInitialized_)
160  {
161  edm::ESHandle<CaloTopology> theCaloTopology;
162  setup.get<CaloTopologyRecord>().get(theCaloTopology);
163  ecalTopology_ = & (*theCaloTopology);
164 
165  edm::ESHandle<CaloGeometry> theCaloGeometry;
166  setup.get<CaloGeometryRecord>().get(theCaloGeometry);
167  caloGeometry_ = & (*theCaloGeometry);
168  geomInitialized_ = true;
169  }
170 
171  // Read GsfElectrons
173  event.getByToken(inputElectronsToken_,oldElectronsH) ;
174 
175  // Read RecHits
178  event.getByToken( recHitCollectionEBToken_, pEBRecHits );
179  event.getByToken( recHitCollectionEEToken_, pEERecHits );
180 
181  // ReadValueMaps
182  edm::Handle<edm::ValueMap<double> > valMapEnergyH;
183  event.getByToken(energyRegToken_,valMapEnergyH);
184  edm::Handle<edm::ValueMap<double> > valMapEnergyErrorH;
185  event.getByToken(energyErrorRegToken_,valMapEnergyErrorH);
186 
187  // Prepare output collections
188  std::auto_ptr<reco::GsfElectronCollection> electrons( new reco::GsfElectronCollection ) ;
189  // Fillers for ValueMaps:
190  std::auto_ptr<edm::ValueMap<double> > regrNewEnergyMap(new edm::ValueMap<double>() );
191  edm::ValueMap<double>::Filler energyFiller(*regrNewEnergyMap);
192 
193  std::auto_ptr<edm::ValueMap<double> > regrNewEnergyErrorMap(new edm::ValueMap<double>() );
194  edm::ValueMap<double>::Filler energyErrorFiller(*regrNewEnergyErrorMap);
195 
196  // first clone the initial collection
197  unsigned nElectrons = oldElectronsH->size();
198  for( unsigned iele = 0; iele < nElectrons; ++iele )
199  {
200  electrons->push_back((*oldElectronsH)[iele]);
201  }
202 
203  std::vector<double> regressionValues;
204  std::vector<double> regressionErrorValues;
205  regressionValues.reserve(nElectrons);
206  regressionErrorValues.reserve(nElectrons);
207 
208  if ( correctionsType != 0 )
209  {
210  for ( unsigned iele = 0; iele < nElectrons ; ++iele)
211  {
212  reco::GsfElectron & ele ( (*electrons)[iele]);
213  reco::GsfElectronRef elecRef(oldElectronsH,iele);
214  double regressionEnergy = (*valMapEnergyH)[elecRef];
215  double regressionEnergyError = (*valMapEnergyErrorH)[elecRef];
216 
217  regressionValues.push_back(regressionEnergy);
218  regressionErrorValues.push_back(regressionEnergyError);
219 
220  // r9
221  const EcalRecHitCollection * recHits=0;
222  if( ele.isEB() )
223  {
224  recHits = pEBRecHits.product();
225  } else recHits = pEERecHits.product();
226 
227  SuperClusterHelper mySCHelper( &(ele), recHits, ecalTopology_, caloGeometry_ );
228 
229  int elClass = -1;
230  int run = event.run();
231 
232  float r9 = mySCHelper.r9();
233  double correctedEcalEnergy = ele.correctedEcalEnergy();
234  double correctedEcalEnergyError = ele.correctedEcalEnergyError();
235  double trackMomentum = ele.trackMomentumAtVtx().R();
236  double trackMomentumError = ele.trackMomentumError();
237  double combinedMomentum = ele.p();
238  double combinedMomentumError = ele.p4Error(ele.candidateP4Kind());
239  // FIXME : p4Error not filled for pure tracker electrons
240  // Recompute it using the parametrization implemented in
241  // RecoEgamma/EgammaElectronAlgos/src/ElectronEnergyCorrector.cc::simpleParameterizationUncertainty()
242  if( !ele.ecalDrivenSeed() )
243  {
244  double error = 999. ;
245  double momentum = (combinedMomentum<15. ? 15. : combinedMomentum);
246  if ( ele.isEB() )
247  {
248  float parEB[3] = { 5.24e-02, 2.01e-01, 1.00e-02};
249  error = momentum * sqrt( pow(parEB[0]/sqrt(momentum),2) + pow(parEB[1]/momentum,2) + pow(parEB[2],2) );
250  }
251  else if ( ele.isEE() )
252  {
253  float parEE[3] = { 1.46e-01, 9.21e-01, 1.94e-03} ;
254  error = momentum * sqrt( pow(parEE[0]/sqrt(momentum),2) + pow(parEE[1]/momentum,2) + pow(parEE[2],2) );
255  }
256  combinedMomentumError = error;
257  }
258 
259  if (ele.classification() == reco::GsfElectron::GOLDEN) {elClass = 0;}
260  if (ele.classification() == reco::GsfElectron::BIGBREM) {elClass = 1;}
261  if (ele.classification() == reco::GsfElectron::BADTRACK) {elClass = 2;}
262  if (ele.classification() == reco::GsfElectron::SHOWERING) {elClass = 3;}
263  if (ele.classification() == reco::GsfElectron::GAP) {elClass = 4;}
264 
265  SimpleElectron mySimpleElectron
266  (
267  run,
268  elClass,
269  r9,
270  correctedEcalEnergy,
271  correctedEcalEnergyError,
272  trackMomentum,
273  trackMomentumError,
274  regressionEnergy,
275  regressionEnergyError,
276  combinedMomentum,
277  combinedMomentumError,
278  ele.superCluster()->eta(),
279  ele.isEB(),
280  isMC,
281  ele.ecalDriven(),
282  ele.trackerDrivenSeed()
283  );
284 
285  // energy calibration for ecalDriven electrons
286  if ( ele.core()->ecalDrivenSeed() || correctionsType==2 || combinationType==3 )
287  {
288  theEnCorrector->calibrate(mySimpleElectron, event.streamID());
289 
290  // E-p combination
291 
292  switch ( combinationType )
293  {
294  case 0:
295  if ( verbose )
296  {
297  std::cout << "[CalibratedGsfElectronProducer] "
298  << "You choose not to combine." << std::endl;
299  }
300  break;
301  case 1:
302  if ( verbose )
303  {
304  std::cout << "[CalibratedGsfElectronProducer] "
305  << "You choose corrected regression energy for standard combination" << std::endl;
306  }
308  myCombinator->combine(mySimpleElectron);
309  break;
310  case 2:
311  if ( verbose )
312  {
313  std::cout << "[CalibratedGsfElectronProducer] "
314  << "You choose uncorrected regression energy for standard combination" << std::endl;
315  }
317  myCombinator->combine(mySimpleElectron);
318  break;
319  case 3:
320  if ( verbose )
321  {
322  std::cout << "[CalibratedGsfElectronProducer] "
323  << "You choose regression combination." << std::endl;
324  }
325  myEpCombinationTool->combine(mySimpleElectron);
326  theEnCorrector->correctLinearity(mySimpleElectron);
327  break;
328  default:
329  throw cms::Exception("CalibratedgsfElectronProducer|ConfigError")
330  << "Unknown combination Type !!!" ;
331  }
332 
333  math::XYZTLorentzVector oldMomentum = ele.p4() ;
334  math::XYZTLorentzVector newMomentum_ ;
335  newMomentum_ = math::XYZTLorentzVector
336  ( oldMomentum.x()*mySimpleElectron.getCombinedMomentum()/oldMomentum.t(),
337  oldMomentum.y()*mySimpleElectron.getCombinedMomentum()/oldMomentum.t(),
338  oldMomentum.z()*mySimpleElectron.getCombinedMomentum()/oldMomentum.t(),
339  mySimpleElectron.getCombinedMomentum() ) ;
340 
341  ele.correctMomentum
342  (
343  newMomentum_,
344  mySimpleElectron.getTrackerMomentumError(),
345  mySimpleElectron.getCombinedMomentumError()
346  );
347 
348  if ( verbose )
349  {
350  std::cout << "[CalibratedGsfElectronProducer] Combined momentum after saving "
351  << ele.p4().t() << std::endl;
352  }
353  }// end of if (ele.core()->ecalDrivenSeed())
354  }// end of loop on electrons
355  } else
356  {
357  if ( verbose )
358  {
359  std::cout << "[CalibratedGsfElectronProducer] "
360  << "You choose not to correct. Uncorrected Regression Energy is taken." << std::endl;
361  }
362  }
363 
364  // Save the electrons
365  const edm::OrphanHandle<reco::GsfElectronCollection> gsfNewElectronHandle = event.put(electrons, newElectronName_) ;
366  energyFiller.insert(gsfNewElectronHandle,regressionValues.begin(),regressionValues.end());
367  energyFiller.fill();
368  energyErrorFiller.insert(gsfNewElectronHandle,regressionErrorValues.begin(),regressionErrorValues.end());
369  energyErrorFiller.fill();
370 
371  event.put(regrNewEnergyMap,nameNewEnergyReg_);
372  event.put(regrNewEnergyErrorMap,nameNewEnergyErrorReg_);
373 }
374 
T getParameter(std::string const &) const
float trackMomentumError() const
Definition: GsfElectron.h:773
tuple cfg
Definition: looper.py:293
const LorentzVector & p4(P4Kind kind) const
Definition: GsfElectron.cc:224
P4Kind candidateP4Kind() const
Definition: GsfElectron.h:777
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void correctMomentum(const LorentzVector &p4, float trackMomentumError, float p4Error)
Definition: GsfElectron.h:795
math::XYZVectorF trackMomentumAtVtx() const
Definition: GsfElectron.h:289
bool init(const GBRForest *forest)
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:52
void combine(SimpleElectron &mySimpleElectron) const
float p4Error(P4Kind kind) const
Definition: GsfElectron.cc:236
void calibrate(SimpleElectron &electron, edm::StreamID const &)
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
edm::EDGetTokenT< EcalRecHitCollection > recHitCollectionEEToken_
bool isEE() const
Definition: GsfElectron.h:351
edm::EDGetTokenT< edm::ValueMap< double > > energyRegToken_
bool isEB() const
Definition: GsfElectron.h:350
edm::EDGetTokenT< EcalRecHitCollection > recHitCollectionEBToken_
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
virtual void produce(edm::Event &, const edm::EventSetup &)
T sqrt(T t)
Definition: SSEVec.h:18
virtual SuperClusterRef superCluster() const
reference to a SuperCluster
Definition: GsfElectron.h:182
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
void correctLinearity(SimpleElectron &electron)
edm::EDGetTokenT< edm::ValueMap< double > > energyErrorRegToken_
float correctedEcalEnergy() const
Definition: GsfElectron.h:771
void setCombinationMode(int mode)
T const * product() const
Definition: Handle.h:81
Classification classification() const
Definition: GsfElectron.h:694
const T & get() const
Definition: EventSetup.h:56
virtual GsfElectronCoreRef core() const
Definition: GsfElectron.cc:8
virtual double p() const final
magnitude of momentum vector
float correctedEcalEnergyError() const
Definition: GsfElectron.h:772
edm::EDGetTokenT< reco::GsfElectronCollection > inputElectronsToken_
ElectronEnergyCalibrator * theEnCorrector
StreamID streamID() const
Definition: Event.h:80
void combine(SimpleElectron &electron)
bool trackerDrivenSeed() const
Definition: GsfElectron.h:187
tuple cout
Definition: gather_cfg.py:145
CalibratedElectronProducer(const edm::ParameterSet &)
bool ecalDriven() const
Definition: GsfElectron.cc:173
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
bool ecalDrivenSeed() const
Definition: GsfElectron.h:186