CMS 3D CMS Logo

PFEGammaProducer.cc
Go to the documentation of this file.
2 
3 
19 
24 
26 #include <sstream>
27 
28 //#define PFLOW_DEBUG
29 
30 #ifdef PFLOW_DEBUG
31 #define LOGDRESSED(x) edm::LogInfo(x)
32 #else
33 #define LOGDRESSED(x) LogDebug(x)
34 #endif
35 
38  : inputTagBlocks_ (consumes<reco::PFBlockCollection>(iConfig.getParameter<edm::InputTag>("blocks")))
39  , eetopsSrc_ (consumes<reco::PFCluster::EEtoPSAssociation>(
40  iConfig.getParameter<edm::InputTag>("EEtoPS_source")))
41  , vertices_ (consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertexCollection")))
42  , useVerticesForNeutral_ (iConfig.getParameter<bool>("useVerticesForNeutral"))
43  , primaryVertex_ (reco::Vertex())
44  , ebeeClustersCollection_("EBEEClusters")
45  , esClustersCollection_ ("ESClusters")
46 {
47 
48  PFEGammaAlgo::PFEGConfigInfo algo_config;
49 
51  iConfig.getParameter<bool>("produceEGCandsWithNoSuperCluster");
52 
53  // register products
54  produces<reco::PFCandidateCollection>();
55  produces<reco::PFCandidateEGammaExtraCollection>();
56  produces<reco::SuperClusterCollection>();
57  produces<reco::CaloClusterCollection>(ebeeClustersCollection_);
58  produces<reco::CaloClusterCollection>(esClustersCollection_);
59  produces<reco::ConversionCollection>();
60 
61  //PFElectrons Configuration
62  algo_config.mvaEleCut
63  = iConfig.getParameter<double>("pf_electron_mvaCut");
64 
65 
66  algo_config.applyCrackCorrections
67  = iConfig.getParameter<bool>("pf_electronID_crackCorrection");
68 
69  algo_config.mvaConvCut = iConfig.getParameter<double>("pf_conv_mvaCut");
70 
71  algo_config.thePFEnergyCalibration.reset(new PFEnergyCalibration());
72 
73  //PFEGamma
74  setPFEGParameters(algo_config);
75 
76 }
77 
78 void
80  const edm::EventSetup& iSetup) {
81 
82  LOGDRESSED("PFEGammaProducer")
83  <<"START event: "
84  <<iEvent.id().event()
85  <<" in run "<<iEvent.id().run()<<std::endl;
86 
87 
88  // output collections
89  auto egCandidates_ = std::make_unique<reco::PFCandidateCollection>();
90  auto egExtra_ = std::make_unique<reco::PFCandidateEGammaExtraCollection>();
91  auto sClusters_ = std::make_unique<reco::SuperClusterCollection>();
92 
93  // Get the EE-PS associations
95  iEvent.getByToken(eetopsSrc_,eetops);
96  pfeg_->setEEtoPSAssociation(eetops);
97 
98  // preshower conditions
99  edm::ESHandle<ESEEIntercalibConstants> esEEInterCalibHandle_;
100  iSetup.get<ESEEIntercalibConstantsRcd>().get(esEEInterCalibHandle_);
101  pfeg_->setAlphaGamma_ESplanes_fromDB(esEEInterCalibHandle_.product());
102 
103  edm::ESHandle<ESChannelStatus> esChannelStatusHandle_;
104  iSetup.get<ESChannelStatusRcd>().get(esChannelStatusHandle_);
105  pfeg_->setESChannelStatus(esChannelStatusHandle_.product());
106 
107  // Get The vertices from the event
108  // and assign dynamic vertex parameters
110  bool gotVertices = iEvent.getByToken(vertices_,vertices);
111  if(!gotVertices) {
112  std::ostringstream err;
113  err<<"Cannot find vertices for this event.Continuing Without them ";
114  edm::LogError("PFEGammaProducer")<<err.str()<<std::endl;
115  }
116 
117  //Assign the PFAlgo Parameters
118  setPFVertexParameters(vertices.product());
119 
120  // get the collection of blocks
121 
123 
124  LOGDRESSED("PFEGammaProducer")<<"getting blocks"<<std::endl;
125  bool found = iEvent.getByToken( inputTagBlocks_, blocks );
126 
127  if(!found ) {
128 
129  std::ostringstream err;
130  err<<"cannot find blocks: (tag index)"
131  << std::hex<< inputTagBlocks_.index() << std::dec;
132  edm::LogError("PFEGammaProducer")<<err.str()<<std::endl;
133 
134  throw cms::Exception( "MissingProduct", err.str());
135  }
136 
137  LOGDRESSED("PFEGammaProducer")
138  <<"EGPFlow is starting..."<<std::endl;
139 
140 #ifdef PFLOW_DEBUG
141  assert( blocks.isValid() && "edm::Handle to blocks was null!");
142  std::ostringstream str;
143  //str<<(*pfAlgo_)<<std::endl;
144  // cout << (*pfAlgo_) << std::endl;
145  LOGDRESSED("PFEGammaProducer") <<str.str()<<std::endl;
146 #endif
147 
148  // sort elements in three lists:
149  std::list< reco::PFBlockRef > hcalBlockRefs;
150  std::list< reco::PFBlockRef > ecalBlockRefs;
151  std::list< reco::PFBlockRef > hoBlockRefs;
152  std::list< reco::PFBlockRef > otherBlockRefs;
153 
154  for( unsigned i=0; i<blocks->size(); ++i ) {
155  // reco::PFBlockRef blockref( blockh,i );
156  //reco::PFBlockRef blockref = createBlockRef( *blocks, i);
157  reco::PFBlockRef blockref(blocks, i);
158 
160  elements = blockref->elements();
161 
162  LOGDRESSED("PFEGammaProducer")
163  << "Found " << elements.size()
164  << " PFBlockElements in block: " << i << std::endl;
165 
166  bool singleEcalOrHcal = false;
167  if( elements.size() == 1 ){
168  switch( elements[0].type() ) {
170  edm::LogError("PFEGammaProducer")
171  << "PFBLOCKALGO BUG!!!! Found a SuperCluster in a block by itself!";
175  ecalBlockRefs.push_back( blockref );
176  singleEcalOrHcal = true;
177  break;
181  if (elements[0].clusterRef()->flags() & reco::CaloCluster::badHcalMarker) continue;
182  hcalBlockRefs.push_back( blockref );
183  singleEcalOrHcal = true;
184  break;
186  // Single HO elements are likely to be noise. Not considered for now.
187  hoBlockRefs.push_back( blockref );
188  singleEcalOrHcal = true;
189  break;
190  default:
191  break;
192  }
193  }
194 
195  if(!singleEcalOrHcal) {
196  otherBlockRefs.push_back( blockref );
197  }
198  }//loop blocks
199 
200  // loop on blocks that are not single ecal, single ps1, single ps2 , or
201  // single hcal and produce unbiased collection of EGamma Candidates
202 
203  //printf("loop over blocks\n");
204  unsigned nblcks = 0;
205 
206  // this auto is a const reco::PFBlockRef&
207  for( const auto& blockref : otherBlockRefs ) {
208  ++nblcks;
209  // this auto is a: const edm::OwnVector< reco::PFBlockElement >&
210  const auto& elements = blockref->elements();
211  // make a copy of the link data, which will be edited.
212  //PFBlock::LinkData linkData = block.linkData();
213 
214  // keep track of the elements which are still active.
215  std::vector<bool> active( elements.size(), true );
216 
217  pfeg_->RunPFEG(globalCache(),blockref,active);
218 
219  if( !pfeg_->getCandidates().empty() ) {
220  LOGDRESSED("PFEGammaProducer")
221  << "Block with " << elements.size()
222  << " elements produced "
223  << pfeg_->getCandidates().size()
224  << " e-g candidates!" << std::endl;
225  }
226 
227  const size_t egsize = egCandidates_->size();
228  egCandidates_->resize(egsize + pfeg_->getCandidates().size());
229  reco::PFCandidateCollection::iterator eginsertfrom =
230  egCandidates_->begin() + egsize;
231  std::move(pfeg_->getCandidates().begin(),
232  pfeg_->getCandidates().end(),
233  eginsertfrom);
234 
235  const size_t egxsize = egExtra_->size();
236  egExtra_->resize(egxsize + pfeg_->getEGExtra().size());
237  reco::PFCandidateEGammaExtraCollection::iterator egxinsertfrom =
238  egExtra_->begin() + egxsize;
239  std::move(pfeg_->getEGExtra().begin(),
240  pfeg_->getEGExtra().end(),
241  egxinsertfrom);
242 
243  const size_t rscsize = sClusters_->size();
244  sClusters_->resize(rscsize + pfeg_->getRefinedSCs().size());
245  reco::SuperClusterCollection::iterator rscinsertfrom =
246  sClusters_->begin() + rscsize;
247  std::move(pfeg_->getRefinedSCs().begin(),
248  pfeg_->getRefinedSCs().end(),
249  rscinsertfrom);
250  }
251 
252  LOGDRESSED("PFEGammaProducer")
253  << "Running PFEGammaAlgo on all blocks produced = "
254  << egCandidates_->size() << " e-g candidates!"
255  << std::endl;
256 
259 
262 
263  //set the correct references to refined SC and EG extra using the refprods
264  for (unsigned int i=0; i < egCandidates_->size(); ++i) {
265  reco::PFCandidate &cand = egCandidates_->at(i);
266  reco::PFCandidateEGammaExtra &xtra = egExtra_->at(i);
267 
268  reco::PFCandidateEGammaExtraRef extraref(egXtraProd,i);
269  reco::SuperClusterRef refinedSCRef(sClusterProd,i);
270 
271  xtra.setSuperClusterRef(refinedSCRef);
272  cand.setSuperClusterRef(refinedSCRef);
273  cand.setPFEGammaExtraRef(extraref);
274  }
275 
276  //build collections of output CaloClusters from the used PFClusters
277  auto caloClustersEBEE = std::make_unique<reco::CaloClusterCollection>();
278  auto caloClustersES = std::make_unique<reco::CaloClusterCollection>();
279 
280  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapEBEE; //maps of pfclusters to caloclusters
281  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapES;
282 
283  for( const auto& sc : *sClusters_ ) {
284  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus!=sc.clustersEnd(); ++pfclus) {
285  if (!pfClusterMapEBEE.count(*pfclus)) {
286  reco::CaloCluster caloclus(**pfclus);
287  caloClustersEBEE->push_back(caloclus);
288  pfClusterMapEBEE[*pfclus] = caloClustersEBEE->size() - 1;
289  }
290  else {
291  throw cms::Exception("PFEgammaProducer::produce")
292  << "Found an EB/EE pfcluster matched to more than one supercluster!"
293  << std::dec << std::endl;
294  }
295  }
296  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus!=sc.preshowerClustersEnd(); ++pfclus) {
297  if (!pfClusterMapES.count(*pfclus)) {
298  reco::CaloCluster caloclus(**pfclus);
299  caloClustersES->push_back(caloclus);
300  pfClusterMapES[*pfclus] = caloClustersES->size() - 1;
301  }
302  else {
303  throw cms::Exception("PFEgammaProducer::produce")
304  << "Found an ES pfcluster matched to more than one supercluster!"
305  << std::dec << std::endl;
306  }
307  }
308  }
309 
310  //put calocluster output collections in event and get orphan handles to create ptrs
311  auto const& caloClusHandleEBEE = iEvent.put(std::move(caloClustersEBEE),ebeeClustersCollection_);
312  auto const& caloClusHandleES = iEvent.put(std::move(caloClustersES),esClustersCollection_);
313 
314  //relink superclusters to output caloclusters
315  for( auto& sc : *sClusters_ ) {
316  edm::Ptr<reco::CaloCluster> seedptr(caloClusHandleEBEE,pfClusterMapEBEE[sc.seed()]);
317  sc.setSeed(seedptr);
318 
320  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus!=sc.clustersEnd(); ++pfclus) {
321  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleEBEE,pfClusterMapEBEE[*pfclus]);
322  clusters.push_back(clusptr);
323  }
324  sc.setClusters(clusters);
325 
326  reco::CaloClusterPtrVector psclusters;
327  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus!=sc.preshowerClustersEnd(); ++pfclus) {
328  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleES,pfClusterMapES[*pfclus]);
329  psclusters.push_back(clusptr);
330  }
331  sc.setPreshowerClusters(psclusters);
332  }
333 
334  //create and fill references to single leg conversions
336  auto singleLegConv_ = std::make_unique<reco::ConversionCollection>();
337  createSingleLegConversions(*egExtra_, *singleLegConv_, convProd);
338 
339  // release our demonspawn into the wild to cause havoc
340  iEvent.put(std::move(sClusters_));
341  iEvent.put(std::move(egExtra_));
342  iEvent.put(std::move(singleLegConv_));
343  iEvent.put(std::move(egCandidates_));
344 }
345 
346 //PFEGammaAlgo: a new method added to set the parameters for electron and photon reconstruction.
347 void
349 
350  //for MVA pass PV if there is one in the collection otherwise pass a dummy
351  if(!useVerticesForNeutral_) { // create a dummy PV
353  e(0, 0) = 0.0015 * 0.0015;
354  e(1, 1) = 0.0015 * 0.0015;
355  e(2, 2) = 15. * 15.;
356  reco::Vertex::Point p(0, 0, 0);
357  primaryVertex_ = reco::Vertex(p, e, 0, 0, 0);
358  }
359  cfg.primaryVtx = &primaryVertex_;
360  pfeg_.reset(new PFEGammaAlgo(cfg));
361 }
362 
363 void
365 
366  primaryVertex_ = primaryVertices->front();
367  for (unsigned short i=0 ;i<primaryVertices->size();++i)
368  {
369  if(primaryVertices->at(i).isValid()&&(!primaryVertices->at(i).isFake()))
370  {
371  primaryVertex_ = primaryVertices->at(i);
372  break;
373  }
374  }
375 
376  pfeg_->setPhotonPrimaryVtx(primaryVertex_ );
377 
378 }
379 
381  reco::ConversionCollection &oneLegConversions,
383 {
384 
386  for (auto &extra : extras){
387  for (const auto &tkrefmva : extra.singleLegConvTrackRefMva()) {
388  const reco::Track &trk = *tkrefmva.first;
389 
390  const reco::Vertex convVtx(trk.innerPosition(), error);
391  std::vector<reco::TrackRef> OneLegConvVector;
392  OneLegConvVector.push_back(tkrefmva.first);
393  std::vector< float > OneLegMvaVector;
394  OneLegMvaVector.push_back(tkrefmva.second);
395  std::vector<reco::CaloClusterPtr> dummymatchingBC;
397  scPtrVec.push_back(edm::refToPtr(extra.superClusterRef()));
398 
399  std::vector<math::XYZPointF>trackPositionAtEcalVec;
400  std::vector<math::XYZPointF>innPointVec;
401  std::vector<math::XYZVectorF>trackPinVec;
402  std::vector<math::XYZVectorF>trackPoutVec;
403  math::XYZPointF trackPositionAtEcal(trk.outerPosition().X(), trk.outerPosition().Y(), trk.outerPosition().Z());
404  trackPositionAtEcalVec.push_back(trackPositionAtEcal);
405 
406  math::XYZPointF innPoint(trk.innerPosition().X(), trk.innerPosition().Y(), trk.innerPosition().Z());
407  innPointVec.push_back(innPoint);
408 
409  math::XYZVectorF trackPin(trk.innerMomentum().X(), trk.innerMomentum().Y(), trk.innerMomentum().Z());
410  trackPinVec.push_back(trackPin);
411 
412  math::XYZVectorF trackPout(trk.outerMomentum().X(), trk.outerMomentum().Y(), trk.outerMomentum().Z());
413  trackPoutVec.push_back( trackPout );
414 
415  float DCA = trk.d0() ;
416  float mvaval = tkrefmva.second;
417  reco::Conversion singleLegConvCandidate(scPtrVec,
418  OneLegConvVector,
419  trackPositionAtEcalVec,
420  convVtx,
421  dummymatchingBC,
422  DCA,
423  innPointVec,
424  trackPinVec,
425  trackPoutVec,
426  mvaval,
428  singleLegConvCandidate.setOneLegMVA(OneLegMvaVector);
429  oneLegConversions.push_back(singleLegConvCandidate);
430 
431  reco::ConversionRef convref(convProd,oneLegConversions.size()-1);
432  extra.addSingleLegConversionRef(convref);
433 
434  }
435 
436  }
437 
438 }
439 
442  desc.add<bool> ("useVerticesForNeutral", true);
443  desc.add<bool> ("produceEGCandsWithNoSuperCluster", false)->setComment("Allow building of candidates with no input or output supercluster?");
444  desc.add<double>("pf_electron_mvaCut", -0.1);
445  desc.add<bool> ("pf_electronID_crackCorrection", false);
446  desc.add<double>("pf_conv_mvaCut", 0.0);
447  desc.add<edm::InputTag> ("blocks", edm::InputTag("particleFlowBlock"))->setComment("PF Blocks label");
448  desc.add<edm::InputTag> ("EEtoPS_source", edm::InputTag("particleFlowClusterECAL"))->setComment("EE to PS association");
449  desc.add<edm::InputTag> ("vertexCollection", edm::InputTag("offlinePrimaryVertices"));
450  desc.add<edm::FileInPath>("pf_electronID_mvaWeightFile",
451  edm::FileInPath("RecoParticleFlow/PFProducer/data/PfElectrons23Jan_BDT.weights.xml.gz"));
452  desc.add<edm::FileInPath>("pf_convID_mvaWeightFile",
453  edm::FileInPath("RecoParticleFlow/PFProducer/data/pfConversionAug0411_BDT.weights.xml.gz"));
454  descriptions.add("particleFlowEGamma", desc);
455 }
RunNumber_t run() const
Definition: EventID.h:39
const std::string esClustersCollection_
type
Definition: HCALResponse.h:21
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:41
const std::string ebeeClustersCollection_
void createSingleLegConversions(reco::PFCandidateEGammaExtraCollection &extras, reco::ConversionCollection &oneLegConversions, const edm::RefProd< reco::ConversionCollection > &convProd)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
void setPFVertexParameters(const reco::VertexCollection *primaryVertices)
void setSuperClusterRef(reco::SuperClusterRef sc)
set reference to the corresponding supercluster
Ptr< typename C::value_type > refToPtr(Ref< C, typename C::value_type, refhelper::FindUsingAdvance< C, typename C::value_type > > const &ref)
Definition: RefToPtr.h:18
double d0() const
dxy parameter in perigee convention (d0 = -dxy)
Definition: TrackBase.h:630
const bool useVerticesForNeutral_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:140
std::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration
Definition: PFEGammaAlgo.h:111
unsigned int index() const
Definition: EDGetToken.h:72
size_type size() const
Definition: OwnVector.h:264
math::Error< dimension >::type Error
covariance error matrix (3x3)
Definition: Vertex.h:43
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
ErrorD< N >::type type
Definition: Error.h:33
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
const reco::Vertex * primaryVtx
Definition: PFEGammaAlgo.h:115
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:67
std::vector< Conversion > ConversionCollection
collectin of Conversion objects
Definition: ConversionFwd.h:9
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:57
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int iEvent
Definition: GenABIO.cc:230
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
std::vector< reco::PFCandidateEGammaExtra > PFCandidateEGammaExtraCollection
collection of PFCandidateEGammaExtras
reco::Vertex primaryVertex_
Variables for PFEGamma.
math::XYZPoint Point
point in the space
Definition: Vertex.h:39
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float > > XYZVectorF
spatial vector with cartesian internal representation
Definition: Vector3D.h:17
void setPFEGParameters(PFEGammaAlgo::PFEGConfigInfo &)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
Definition: PFBlockFwd.h:11
RefProd< PROD > getRefBeforePut()
Definition: Event.h:167
const edm::EDGetTokenT< reco::PFCluster::EEtoPSAssociation > eetopsSrc_
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:72
T const * product() const
Definition: Handle.h:81
primaryVertices
Definition: jets_cff.py:130
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::unique_ptr< PFEGammaAlgo > pfeg_
particle flow algorithm
const edm::EDGetTokenT< reco::VertexCollection > vertices_
const edm::EDGetTokenT< reco::PFBlockCollection > inputTagBlocks_
edm::EventID id() const
Definition: EventBase.h:60
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
fixed size matrix
HLT enums.
void setOneLegMVA(const std::vector< float > &mva)
set the MVS output from PF for one leg conversions
Definition: Conversion.h:171
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
Definition: Track.h:62
#define LOGDRESSED(x)
T get() const
Definition: EventSetup.h:68
void setPFEGammaExtraRef(const reco::PFCandidateEGammaExtraRef &ref)
set the PF EGamma Extra Ref
Definition: PFCandidate.cc:650
void setSuperClusterRef(const reco::SuperClusterRef &scRef)
Definition: PFCandidate.cc:629
PFEGammaProducer(const edm::ParameterSet &, const pfEGHelpers::HeavyObjectCache *)
#define str(s)
void produce(edm::Event &, const edm::EventSetup &) override
T const * product() const
Definition: ESHandle.h:84
def move(src, dest)
Definition: eostools.py:511