CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFEGammaProducer.cc
Go to the documentation of this file.
1 
46 
47 #include <sstream>
48 #include <string>
49 #include <memory>
50 
51 class PFEGammaProducer : public edm::stream::EDProducer<edm::GlobalCache<PFEGammaAlgo::GBRForests> > {
52 public:
54 
55  static std::unique_ptr<PFEGammaAlgo::GBRForests> initializeGlobalCache(const edm::ParameterSet& conf) {
56  return std::unique_ptr<PFEGammaAlgo::GBRForests>(new PFEGammaAlgo::GBRForests(conf));
57  }
58 
59  static void globalEndJob(PFEGammaAlgo::GBRForests const*) {}
60 
61  void produce(edm::Event&, const edm::EventSetup&) override;
62  void beginRun(const edm::Run&, const edm::EventSetup&) override {}
63 
64  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
65 
66 private:
68 
70  reco::ConversionCollection& oneLegConversions,
72 
76 
77  // Use vertices for Neutral particles ?
79 
81 
83 
85  std::unique_ptr<PFEGammaAlgo> pfeg_;
86 
89 };
90 
93 
94 #ifdef PFLOW_DEBUG
95 #define LOGDRESSED(x) edm::LogInfo(x)
96 #else
97 #define LOGDRESSED(x) LogDebug(x)
98 #endif
99 
101  : inputTagBlocks_(consumes<reco::PFBlockCollection>(iConfig.getParameter<edm::InputTag>("blocks"))),
102  eetopsSrc_(consumes<reco::PFCluster::EEtoPSAssociation>(iConfig.getParameter<edm::InputTag>("EEtoPS_source"))),
103  vertices_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertexCollection"))),
104  useVerticesForNeutral_(iConfig.getParameter<bool>("useVerticesForNeutral")),
106  ebeeClustersCollection_("EBEEClusters"),
107  esClustersCollection_("ESClusters") {
108  PFEGammaAlgo::PFEGConfigInfo algo_config;
109 
110  algo_config.produceEGCandsWithNoSuperCluster = iConfig.getParameter<bool>("produceEGCandsWithNoSuperCluster");
111 
112  // register products
113  produces<reco::PFCandidateCollection>();
114  produces<reco::PFCandidateEGammaExtraCollection>();
115  produces<reco::SuperClusterCollection>();
116  produces<reco::CaloClusterCollection>(ebeeClustersCollection_);
117  produces<reco::CaloClusterCollection>(esClustersCollection_);
118  produces<reco::ConversionCollection>();
119 
120  //PFElectrons Configuration
121  algo_config.mvaEleCut = iConfig.getParameter<double>("pf_electron_mvaCut");
122 
123  algo_config.applyCrackCorrections = iConfig.getParameter<bool>("pf_electronID_crackCorrection");
124 
125  algo_config.mvaConvCut = iConfig.getParameter<double>("pf_conv_mvaCut");
126 
127  //PFEGamma
128  //for MVA pass PV if there is one in the collection otherwise pass a dummy
129  if (!useVerticesForNeutral_) { // create a dummy PV
131  e(0, 0) = 0.0015 * 0.0015;
132  e(1, 1) = 0.0015 * 0.0015;
133  e(2, 2) = 15. * 15.;
134  reco::Vertex::Point p(0, 0, 0);
135  primaryVertex_ = reco::Vertex(p, e, 0, 0, 0);
136  }
137  pfeg_ = std::make_unique<PFEGammaAlgo>(algo_config, *gbrForests);
138  pfeg_->setPrimaryVertex(primaryVertex_);
139 }
140 
142  LOGDRESSED("PFEGammaProducer") << "START event: " << iEvent.id().event() << " in run " << iEvent.id().run()
143  << std::endl;
144 
145  // output collections
146  auto egCandidates_ = std::make_unique<reco::PFCandidateCollection>();
147  auto egExtra_ = std::make_unique<reco::PFCandidateEGammaExtraCollection>();
148  auto sClusters_ = std::make_unique<reco::SuperClusterCollection>();
149 
150  // Get the EE-PS associations
151  pfeg_->setEEtoPSAssociation(iEvent.get(eetopsSrc_));
152 
153  // preshower conditions
154  edm::ESHandle<ESEEIntercalibConstants> esEEInterCalibHandle_;
155  iSetup.get<ESEEIntercalibConstantsRcd>().get(esEEInterCalibHandle_);
156  pfeg_->setAlphaGamma_ESplanes_fromDB(esEEInterCalibHandle_.product());
157 
158  edm::ESHandle<ESChannelStatus> esChannelStatusHandle_;
159  iSetup.get<ESChannelStatusRcd>().get(esChannelStatusHandle_);
160  pfeg_->setESChannelStatus(esChannelStatusHandle_.product());
161 
162  //Assign the PFAlgo Parameters
164 
165  // get the collection of blocks
166 
167  LOGDRESSED("PFEGammaProducer") << "getting blocks" << std::endl;
168  auto blocks = iEvent.getHandle(inputTagBlocks_);
169 
170  LOGDRESSED("PFEGammaProducer") << "EGPFlow is starting..." << std::endl;
171 
172 #ifdef PFLOW_DEBUG
173  assert(blocks.isValid() && "edm::Handle to blocks was null!");
174  std::ostringstream str;
175  //str<<(*pfAlgo_)<<std::endl;
176  // cout << (*pfAlgo_) << std::endl;
177  LOGDRESSED("PFEGammaProducer") << str.str() << std::endl;
178 #endif
179 
180  // sort elements in three lists:
181  std::list<reco::PFBlockRef> hcalBlockRefs;
182  std::list<reco::PFBlockRef> ecalBlockRefs;
183  std::list<reco::PFBlockRef> hoBlockRefs;
184  std::list<reco::PFBlockRef> otherBlockRefs;
185 
186  for (unsigned i = 0; i < blocks->size(); ++i) {
187  reco::PFBlockRef blockref(blocks, i);
188 
189  const edm::OwnVector<reco::PFBlockElement>& elements = blockref->elements();
190 
191  LOGDRESSED("PFEGammaProducer") << "Found " << elements.size() << " PFBlockElements in block: " << i << std::endl;
192 
193  bool singleEcalOrHcal = false;
194  if (elements.size() == 1) {
195  switch (elements[0].type()) {
197  edm::LogError("PFEGammaProducer") << "PFBLOCKALGO BUG!!!! Found a SuperCluster in a block by itself!";
198  break;
202  ecalBlockRefs.push_back(blockref);
203  singleEcalOrHcal = true;
204  break;
208  if (elements[0].clusterRef()->flags() & reco::CaloCluster::badHcalMarker)
209  continue;
210  hcalBlockRefs.push_back(blockref);
211  singleEcalOrHcal = true;
212  break;
214  // Single HO elements are likely to be noise. Not considered for now.
215  hoBlockRefs.push_back(blockref);
216  singleEcalOrHcal = true;
217  break;
218  default:
219  break;
220  }
221  }
222 
223  if (!singleEcalOrHcal) {
224  otherBlockRefs.push_back(blockref);
225  }
226  } //loop blocks
227 
228  // loop on blocks that are not single ecal, single ps1, single ps2 , or
229  // single hcal and produce unbiased collection of EGamma Candidates
230 
231  //printf("loop over blocks\n");
232  unsigned nblcks = 0;
233 
234  // this auto is a const reco::PFBlockRef&
235  for (const auto& blockref : otherBlockRefs) {
236  ++nblcks;
237  // this auto is a: const edm::OwnVector< reco::PFBlockElement >&
238  const auto& elements = blockref->elements();
239  // make a copy of the link data, which will be edited.
240  //PFBlock::LinkData linkData = block.linkData();
241 
242  auto output = (*pfeg_)(blockref);
243 
244  if (!output.candidates.empty()) {
245  LOGDRESSED("PFEGammaProducer") << "Block with " << elements.size() << " elements produced "
246  << output.candidates.size() << " e-g candidates!" << std::endl;
247  }
248 
249  const size_t egsize = egCandidates_->size();
250  egCandidates_->resize(egsize + output.candidates.size());
251  std::move(output.candidates.begin(), output.candidates.end(), egCandidates_->begin() + egsize);
252 
253  const size_t egxsize = egExtra_->size();
254  egExtra_->resize(egxsize + output.candidateExtras.size());
255  std::move(output.candidateExtras.begin(), output.candidateExtras.end(), egExtra_->begin() + egxsize);
256 
257  const size_t rscsize = sClusters_->size();
258  sClusters_->resize(rscsize + output.refinedSuperClusters.size());
259  std::move(output.refinedSuperClusters.begin(), output.refinedSuperClusters.end(), sClusters_->begin() + rscsize);
260  }
261 
262  LOGDRESSED("PFEGammaProducer") << "Running PFEGammaAlgo on all blocks produced = " << egCandidates_->size()
263  << " e-g candidates!" << std::endl;
264 
266 
269 
270  //set the correct references to refined SC and EG extra using the refprods
271  for (unsigned int i = 0; i < egCandidates_->size(); ++i) {
272  reco::PFCandidate& cand = egCandidates_->at(i);
273  reco::PFCandidateEGammaExtra& xtra = egExtra_->at(i);
274 
275  reco::PFCandidateEGammaExtraRef extraref(egXtraProd, i);
276  reco::SuperClusterRef refinedSCRef(sClusterProd, i);
277 
278  xtra.setSuperClusterRef(refinedSCRef);
279  cand.setSuperClusterRef(refinedSCRef);
280  cand.setPFEGammaExtraRef(extraref);
281  }
282 
283  //build collections of output CaloClusters from the used PFClusters
284  auto caloClustersEBEE = std::make_unique<reco::CaloClusterCollection>();
285  auto caloClustersES = std::make_unique<reco::CaloClusterCollection>();
286 
287  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapEBEE; //maps of pfclusters to caloclusters
288  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapES;
289 
290  for (const auto& sc : *sClusters_) {
291  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus != sc.clustersEnd(); ++pfclus) {
292  if (!pfClusterMapEBEE.count(*pfclus)) {
293  reco::CaloCluster caloclus(**pfclus);
294  caloClustersEBEE->push_back(caloclus);
295  pfClusterMapEBEE[*pfclus] = caloClustersEBEE->size() - 1;
296  } else {
297  throw cms::Exception("PFEgammaProducer::produce")
298  << "Found an EB/EE pfcluster matched to more than one supercluster!" << std::dec << std::endl;
299  }
300  }
301  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus != sc.preshowerClustersEnd();
302  ++pfclus) {
303  if (!pfClusterMapES.count(*pfclus)) {
304  reco::CaloCluster caloclus(**pfclus);
305  caloClustersES->push_back(caloclus);
306  pfClusterMapES[*pfclus] = caloClustersES->size() - 1;
307  } else {
308  throw cms::Exception("PFEgammaProducer::produce")
309  << "Found an ES pfcluster matched to more than one supercluster!" << std::dec << std::endl;
310  }
311  }
312  }
313 
314  //put calocluster output collections in event and get orphan handles to create ptrs
315  auto const& caloClusHandleEBEE = iEvent.put(std::move(caloClustersEBEE), ebeeClustersCollection_);
316  auto const& caloClusHandleES = iEvent.put(std::move(caloClustersES), esClustersCollection_);
317 
318  //relink superclusters to output caloclusters
319  for (auto& sc : *sClusters_) {
320  edm::Ptr<reco::CaloCluster> seedptr(caloClusHandleEBEE, pfClusterMapEBEE[sc.seed()]);
321  sc.setSeed(seedptr);
322 
324  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus != sc.clustersEnd(); ++pfclus) {
325  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleEBEE, pfClusterMapEBEE[*pfclus]);
326  clusters.push_back(clusptr);
327  }
328  sc.setClusters(clusters);
329 
330  reco::CaloClusterPtrVector psclusters;
331  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus != sc.preshowerClustersEnd();
332  ++pfclus) {
333  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleES, pfClusterMapES[*pfclus]);
334  psclusters.push_back(clusptr);
335  }
336  sc.setPreshowerClusters(psclusters);
337  }
338 
339  //create and fill references to single leg conversions
341  auto singleLegConv_ = std::make_unique<reco::ConversionCollection>();
342  createSingleLegConversions(*egExtra_, *singleLegConv_, convProd);
343 
344  // release our demonspawn into the wild to cause havoc
345  iEvent.put(std::move(sClusters_));
346  iEvent.put(std::move(egExtra_));
347  iEvent.put(std::move(singleLegConv_));
348  iEvent.put(std::move(egCandidates_));
349 }
350 
352  primaryVertex_ = primaryVertices.front();
353  for (auto const& pv : primaryVertices) {
354  if (pv.isValid() && !pv.isFake()) {
355  primaryVertex_ = pv;
356  break;
357  }
358  }
359 
360  pfeg_->setPrimaryVertex(primaryVertex_);
361 }
362 
364  reco::ConversionCollection& oneLegConversions,
367  for (auto& extra : extras) {
368  for (const auto& tkrefmva : extra.singleLegConvTrackRefMva()) {
369  const reco::Track& trk = *tkrefmva.first;
370 
371  const reco::Vertex convVtx(trk.innerPosition(), error);
372  std::vector<reco::TrackRef> OneLegConvVector;
373  OneLegConvVector.push_back(tkrefmva.first);
374  std::vector<float> OneLegMvaVector;
375  OneLegMvaVector.push_back(tkrefmva.second);
376  std::vector<reco::CaloClusterPtr> dummymatchingBC;
378  scPtrVec.push_back(edm::refToPtr(extra.superClusterRef()));
379 
380  std::vector<math::XYZPointF> trackPositionAtEcalVec;
381  std::vector<math::XYZPointF> innPointVec;
382  std::vector<math::XYZVectorF> trackPinVec;
383  std::vector<math::XYZVectorF> trackPoutVec;
384  math::XYZPointF trackPositionAtEcal(trk.outerPosition().X(), trk.outerPosition().Y(), trk.outerPosition().Z());
385  trackPositionAtEcalVec.push_back(trackPositionAtEcal);
386 
387  math::XYZPointF innPoint(trk.innerPosition().X(), trk.innerPosition().Y(), trk.innerPosition().Z());
388  innPointVec.push_back(innPoint);
389 
390  math::XYZVectorF trackPin(trk.innerMomentum().X(), trk.innerMomentum().Y(), trk.innerMomentum().Z());
391  trackPinVec.push_back(trackPin);
392 
393  math::XYZVectorF trackPout(trk.outerMomentum().X(), trk.outerMomentum().Y(), trk.outerMomentum().Z());
394  trackPoutVec.push_back(trackPout);
395 
396  float DCA = trk.d0();
397  float mvaval = tkrefmva.second;
398  reco::Conversion singleLegConvCandidate(scPtrVec,
399  OneLegConvVector,
400  trackPositionAtEcalVec,
401  convVtx,
402  dummymatchingBC,
403  DCA,
404  innPointVec,
405  trackPinVec,
406  trackPoutVec,
407  mvaval,
409  singleLegConvCandidate.setOneLegMVA(OneLegMvaVector);
410  oneLegConversions.push_back(singleLegConvCandidate);
411 
412  reco::ConversionRef convref(convProd, oneLegConversions.size() - 1);
413  extra.addSingleLegConversionRef(convref);
414  }
415  }
416 }
417 
420  desc.add<bool>("useVerticesForNeutral", true);
421  desc.add<bool>("produceEGCandsWithNoSuperCluster", false)
422  ->setComment("Allow building of candidates with no input or output supercluster?");
423  desc.add<double>("pf_electron_mvaCut", -0.1);
424  desc.add<bool>("pf_electronID_crackCorrection", false);
425  desc.add<double>("pf_conv_mvaCut", 0.0);
426  desc.add<edm::InputTag>("blocks", edm::InputTag("particleFlowBlock"))->setComment("PF Blocks label");
427  desc.add<edm::InputTag>("EEtoPS_source", edm::InputTag("particleFlowClusterECAL"))
428  ->setComment("EE to PS association");
429  desc.add<edm::InputTag>("vertexCollection", edm::InputTag("offlinePrimaryVertices"));
430  desc.add<edm::FileInPath>("pf_electronID_mvaWeightFile",
431  edm::FileInPath("RecoParticleFlow/PFProducer/data/PfElectrons23Jan_BDT.weights.xml.gz"));
432  desc.add<edm::FileInPath>("pf_convID_mvaWeightFile",
433  edm::FileInPath("RecoParticleFlow/PFProducer/data/pfConversionAug0411_BDT.weights.xml.gz"));
434  descriptions.add("particleFlowEGamma", desc);
435 }
RunNumber_t run() const
Definition: EventID.h:38
const std::string esClustersCollection_
type
Definition: HCALResponse.h:21
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:40
static std::unique_ptr< PFEGammaAlgo::GBRForests > initializeGlobalCache(const edm::ParameterSet &conf)
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:131
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
PFEGammaProducer(const edm::ParameterSet &, const PFEGammaAlgo::GBRForests *)
double d0() const
dxy parameter in perigee convention (d0 = -dxy)
Definition: TrackBase.h:590
const bool useVerticesForNeutral_
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:149
size_type size() const
Definition: OwnVector.h:300
void setPFVertexParameters(reco::VertexCollection const &primaryVertices)
math::Error< dimension >::type Error
covariance error matrix (3x3)
Definition: Vertex.h:43
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
ErrorD< N >::type type
Definition: Error.h:32
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:62
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:56
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:547
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
std::vector< reco::PFCandidateEGammaExtra > PFCandidateEGammaExtraCollection
collection of PFCandidateEGammaExtras
def pv(vc)
Definition: MetAnalyzer.py:7
reco::Vertex primaryVertex_
Variables for PFEGamma.
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:334
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:16
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void beginRun(const edm::Run &, const edm::EventSetup &) override
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
Definition: PFBlockFwd.h:10
RefProd< PROD > getRefBeforePut()
Definition: Event.h:156
const edm::EDGetTokenT< reco::PFCluster::EEtoPSAssociation > eetopsSrc_
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:65
static void globalEndJob(PFEGammaAlgo::GBRForests const *)
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:59
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:163
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
Definition: Track.h:59
#define LOGDRESSED(x)
T get() const
Definition: EventSetup.h:73
void setPFEGammaExtraRef(const reco::PFCandidateEGammaExtraRef &ref)
set the PF EGamma Extra Ref
Definition: PFCandidate.cc:596
void setSuperClusterRef(const reco::SuperClusterRef &scRef)
Definition: PFCandidate.cc:576
Producer for particle flow reconstructed particles (PFCandidates)
#define str(s)
void produce(edm::Event &, const edm::EventSetup &) override
T const * product() const
Definition: ESHandle.h:86
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45