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