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