CMS 3D CMS Logo

PFEGammaProducer.cc
Go to the documentation of this file.
1 
35 
37 public:
38  explicit PFEGammaProducer(const edm::ParameterSet&);
39 
40  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
41 
42  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
43 
44 private:
46  const edm::RefProd<reco::ConversionCollection>& convProd) const;
47 
51 
58 
62 
65 };
66 
69 
70 #ifdef PFLOW_DEBUG
71 #define LOGDRESSED(x) edm::LogInfo(x)
72 #else
73 #define LOGDRESSED(x) LogDebug(x)
74 #endif
75 
77  : inputTagBlocks_(consumes<reco::PFBlockCollection>(iConfig.getParameter<edm::InputTag>("blocks"))),
78  eetopsSrc_(consumes<reco::PFCluster::EEtoPSAssociation>(iConfig.getParameter<edm::InputTag>("EEtoPS_source"))),
79  vertices_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertexCollection"))),
80  pfCandidateCollectionPutToken_{produces<reco::PFCandidateCollection>()},
81  pfCandidateEGammaExtraCollectionPutToken_{produces<reco::PFCandidateEGammaExtraCollection>()},
82  superClusterCollectionPutToken_{produces<reco::SuperClusterCollection>()},
83  caloClusterCollectionEBEEPutToken_{produces<reco::CaloClusterCollection>("EBEEClusters")},
84  caloClusterCollectionESPutToken_{produces<reco::CaloClusterCollection>("ESClusters")},
85  conversionCollectionPutToken_{produces<reco::ConversionCollection>()},
86  pfEGConfigInfo_{
87  .mvaEleCut = iConfig.getParameter<double>("pf_electron_mvaCut"),
88  .applyCrackCorrections = iConfig.getParameter<bool>("pf_electronID_crackCorrection"),
89  .produceEGCandsWithNoSuperCluster = iConfig.getParameter<bool>("produceEGCandsWithNoSuperCluster"),
90  .mvaConvCut = iConfig.getParameter<double>("pf_conv_mvaCut"),
91  },
92  gbrForests_{
93  iConfig,
94  },
95  esEEInterCalibToken_(esConsumes()),
96  esChannelStatusToken_(esConsumes()) {}
97 
99  LOGDRESSED("PFEGammaProducer") << "START event: " << iEvent.id().event() << " in run " << iEvent.id().run()
100  << std::endl;
101 
102  // output collections
103  reco::PFCandidateCollection egCandidates{};
105  reco::SuperClusterCollection sClusters{};
106 
107  // preshower conditions
108  auto esEEInterCalibHandle_ = iSetup.getHandle(esEEInterCalibToken_);
109  auto esChannelStatusHandle_ = iSetup.getHandle(esChannelStatusToken_);
110 
111  //Assign the PFAlgo Parameters
112  auto const& primaryVertices = iEvent.get(vertices_);
113  auto const* primaryVertex = &primaryVertices.front();
114  for (auto const& pv : primaryVertices) {
115  if (pv.isValid() && !pv.isFake()) {
116  primaryVertex = &pv;
117  break;
118  }
119  }
120 
121  PFEGammaAlgo pfEGammaAlgo{pfEGConfigInfo_,
122  gbrForests_,
123  iEvent.get(eetopsSrc_),
124  *esEEInterCalibHandle_,
125  *esChannelStatusHandle_,
126  *primaryVertex};
127 
128  // get the collection of blocks
129 
130  LOGDRESSED("PFEGammaProducer") << "getting blocks" << std::endl;
131  auto blocks = iEvent.getHandle(inputTagBlocks_);
132 
133  LOGDRESSED("PFEGammaProducer") << "EGPFlow is starting..." << std::endl;
134 
135 #ifdef PFLOW_DEBUG
136  assert(blocks.isValid() && "edm::Handle to blocks was null!");
137  std::ostringstream str;
138  //str<<(*pfAlgo_)<<std::endl;
139  // cout << (*pfAlgo_) << std::endl;
140  LOGDRESSED("PFEGammaProducer") << str.str() << std::endl;
141 #endif
142 
143  // sort elements in three lists:
144  std::list<reco::PFBlockRef> hcalBlockRefs;
145  std::list<reco::PFBlockRef> ecalBlockRefs;
146  std::list<reco::PFBlockRef> hoBlockRefs;
147  std::list<reco::PFBlockRef> otherBlockRefs;
148 
149  for (unsigned i = 0; i < blocks->size(); ++i) {
150  reco::PFBlockRef blockref(blocks, i);
151 
152  const edm::OwnVector<reco::PFBlockElement>& elements = blockref->elements();
153 
154  LOGDRESSED("PFEGammaProducer") << "Found " << elements.size() << " PFBlockElements in block: " << i << std::endl;
155 
156  bool singleEcalOrHcal = false;
157  if (elements.size() == 1) {
158  switch (elements[0].type()) {
160  edm::LogError("PFEGammaProducer") << "PFBLOCKALGO BUG!!!! Found a SuperCluster in a block by itself!";
161  break;
165  ecalBlockRefs.push_back(blockref);
166  singleEcalOrHcal = true;
167  break;
171  if (elements[0].clusterRef()->flags() & reco::CaloCluster::badHcalMarker)
172  continue;
173  hcalBlockRefs.push_back(blockref);
174  singleEcalOrHcal = true;
175  break;
177  // Single HO elements are likely to be noise. Not considered for now.
178  hoBlockRefs.push_back(blockref);
179  singleEcalOrHcal = true;
180  break;
181  default:
182  break;
183  }
184  }
185 
186  if (!singleEcalOrHcal) {
187  otherBlockRefs.push_back(blockref);
188  }
189  } //loop blocks
190 
191  // loop on blocks that are not single ecal, single ps1, single ps2 , or
192  // single hcal and produce unbiased collection of EGamma Candidates
193 
194  //printf("loop over blocks\n");
195 
196  // this auto is a const reco::PFBlockRef&
197  for (const auto& blockref : otherBlockRefs) {
198  // this auto is a: const edm::OwnVector< reco::PFBlockElement >&
199  const auto& elements = blockref->elements();
200  // make a copy of the link data, which will be edited.
201  //PFBlock::LinkData linkData = block.linkData();
202 
203  auto output = pfEGammaAlgo(blockref);
204 
205  if (!output.candidates.empty()) {
206  LOGDRESSED("PFEGammaProducer") << "Block with " << elements.size() << " elements produced "
207  << output.candidates.size() << " e-g candidates!" << std::endl;
208  }
209 
210  const size_t egsize = egCandidates.size();
211  egCandidates.resize(egsize + output.candidates.size());
212  std::move(output.candidates.begin(), output.candidates.end(), egCandidates.begin() + egsize);
213 
214  const size_t egxsize = egExtra.size();
215  egExtra.resize(egxsize + output.candidateExtras.size());
216  std::move(output.candidateExtras.begin(), output.candidateExtras.end(), egExtra.begin() + egxsize);
217 
218  const size_t rscsize = sClusters.size();
219  sClusters.resize(rscsize + output.refinedSuperClusters.size());
220  std::move(output.refinedSuperClusters.begin(), output.refinedSuperClusters.end(), sClusters.begin() + rscsize);
221  }
222 
223  LOGDRESSED("PFEGammaProducer") << "Running PFEGammaAlgo on all blocks produced = " << egCandidates.size()
224  << " e-g candidates!" << std::endl;
225 
226  auto sClusterProd = iEvent.getRefBeforePut<reco::SuperClusterCollection>();
227  auto egXtraProd = iEvent.getRefBeforePut<reco::PFCandidateEGammaExtraCollection>();
228 
229  //set the correct references to refined SC and EG extra using the refprods
230  for (unsigned int i = 0; i < egCandidates.size(); ++i) {
231  reco::PFCandidate& cand = egCandidates.at(i);
232  reco::PFCandidateEGammaExtra& xtra = egExtra.at(i);
233 
234  reco::PFCandidateEGammaExtraRef extraref(egXtraProd, i);
235  reco::SuperClusterRef refinedSCRef(sClusterProd, i);
236 
237  xtra.setSuperClusterRef(refinedSCRef);
238  cand.setSuperClusterRef(refinedSCRef);
239  cand.setPFEGammaExtraRef(extraref);
240  }
241 
242  //build collections of output CaloClusters from the used PFClusters
243  reco::CaloClusterCollection caloClustersEBEE{};
244  reco::CaloClusterCollection caloClustersES{};
245 
246  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapEBEE; //maps of pfclusters to caloclusters
247  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapES;
248 
249  for (const auto& sc : sClusters) {
250  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus != sc.clustersEnd(); ++pfclus) {
251  if (!pfClusterMapEBEE.count(*pfclus)) {
252  reco::CaloCluster caloclus(**pfclus);
253  caloClustersEBEE.push_back(caloclus);
254  pfClusterMapEBEE[*pfclus] = caloClustersEBEE.size() - 1;
255  } else {
256  throw cms::Exception("PFEgammaProducer::produce")
257  << "Found an EB/EE pfcluster matched to more than one supercluster!" << std::dec << std::endl;
258  }
259  }
260  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus != sc.preshowerClustersEnd();
261  ++pfclus) {
262  if (!pfClusterMapES.count(*pfclus)) {
263  reco::CaloCluster caloclus(**pfclus);
264  caloClustersES.push_back(caloclus);
265  pfClusterMapES[*pfclus] = caloClustersES.size() - 1;
266  } else {
267  throw cms::Exception("PFEgammaProducer::produce")
268  << "Found an ES pfcluster matched to more than one supercluster!" << std::dec << std::endl;
269  }
270  }
271  }
272 
273  //put calocluster output collections in event and get orphan handles to create ptrs
274  auto const& caloClusHandleEBEE = iEvent.emplace(caloClusterCollectionEBEEPutToken_, std::move(caloClustersEBEE));
275  auto const& caloClusHandleES = iEvent.emplace(caloClusterCollectionESPutToken_, std::move(caloClustersES));
276 
277  //relink superclusters to output caloclusters
278  for (auto& sc : sClusters) {
279  edm::Ptr<reco::CaloCluster> seedptr(caloClusHandleEBEE, pfClusterMapEBEE[sc.seed()]);
280  sc.setSeed(seedptr);
281 
283  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus != sc.clustersEnd(); ++pfclus) {
284  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleEBEE, pfClusterMapEBEE[*pfclus]);
285  clusters.push_back(clusptr);
286  }
287  sc.setClusters(clusters);
288 
289  reco::CaloClusterPtrVector psclusters;
290  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus != sc.preshowerClustersEnd();
291  ++pfclus) {
292  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleES, pfClusterMapES[*pfclus]);
293  psclusters.push_back(clusptr);
294  }
295  sc.setPreshowerClusters(psclusters);
296  }
297 
298  //create and fill references to single leg conversions
299  auto singleLegConv = createSingleLegConversions(egExtra, iEvent.getRefBeforePut<reco::ConversionCollection>());
300 
301  // release our demonspawn into the wild to cause havoc
302  iEvent.emplace(superClusterCollectionPutToken_, std::move(sClusters));
304  iEvent.emplace(conversionCollectionPutToken_, std::move(singleLegConv));
305  iEvent.emplace(pfCandidateCollectionPutToken_, std::move(egCandidates));
306 }
307 
310  reco::ConversionCollection oneLegConversions{};
312  for (auto& extra : extras) {
313  for (const auto& tkrefmva : extra.singleLegConvTrackRefMva()) {
314  const reco::Track& trk = *tkrefmva.first;
315 
316  const reco::Vertex convVtx(trk.innerPosition(), error);
317  std::vector<reco::TrackRef> OneLegConvVector;
318  OneLegConvVector.push_back(tkrefmva.first);
319  std::vector<float> OneLegMvaVector;
320  OneLegMvaVector.push_back(tkrefmva.second);
321  std::vector<reco::CaloClusterPtr> dummymatchingBC;
323  scPtrVec.push_back(edm::refToPtr(extra.superClusterRef()));
324 
325  std::vector<math::XYZPointF> trackPositionAtEcalVec;
326  std::vector<math::XYZPointF> innPointVec;
327  std::vector<math::XYZVectorF> trackPinVec;
328  std::vector<math::XYZVectorF> trackPoutVec;
329  math::XYZPointF trackPositionAtEcal(trk.outerPosition().X(), trk.outerPosition().Y(), trk.outerPosition().Z());
330  trackPositionAtEcalVec.push_back(trackPositionAtEcal);
331 
332  math::XYZPointF innPoint(trk.innerPosition().X(), trk.innerPosition().Y(), trk.innerPosition().Z());
333  innPointVec.push_back(innPoint);
334 
335  math::XYZVectorF trackPin(trk.innerMomentum().X(), trk.innerMomentum().Y(), trk.innerMomentum().Z());
336  trackPinVec.push_back(trackPin);
337 
338  math::XYZVectorF trackPout(trk.outerMomentum().X(), trk.outerMomentum().Y(), trk.outerMomentum().Z());
339  trackPoutVec.push_back(trackPout);
340 
341  float DCA = trk.d0();
342  float mvaval = tkrefmva.second;
343  reco::Conversion singleLegConvCandidate(scPtrVec,
344  OneLegConvVector,
345  trackPositionAtEcalVec,
346  convVtx,
347  dummymatchingBC,
348  DCA,
349  innPointVec,
350  trackPinVec,
351  trackPoutVec,
352  mvaval,
354  singleLegConvCandidate.setOneLegMVA(OneLegMvaVector);
355  oneLegConversions.push_back(singleLegConvCandidate);
356 
357  reco::ConversionRef convref(convProd, oneLegConversions.size() - 1);
358  extra.addSingleLegConversionRef(convref);
359  }
360  }
361  return oneLegConversions;
362 }
363 
366  desc.add<bool>("produceEGCandsWithNoSuperCluster", false)
367  ->setComment("Allow building of candidates with no input or output supercluster?");
368  desc.add<double>("pf_electron_mvaCut", -0.1);
369  desc.add<bool>("pf_electronID_crackCorrection", false);
370  desc.add<double>("pf_conv_mvaCut", 0.0);
371  desc.add<edm::InputTag>("blocks", edm::InputTag("particleFlowBlock"))->setComment("PF Blocks label");
372  desc.add<edm::InputTag>("EEtoPS_source", edm::InputTag("particleFlowClusterECAL"))
373  ->setComment("EE to PS association");
374  desc.add<edm::InputTag>("vertexCollection", edm::InputTag("offlinePrimaryVertices"));
375  desc.add<edm::FileInPath>("pf_electronID_mvaWeightFile",
376  edm::FileInPath("RecoParticleFlow/PFProducer/data/PfElectrons23Jan_BDT.weights.xml.gz"));
377  desc.add<edm::FileInPath>("pf_convID_mvaWeightFile",
378  edm::FileInPath("RecoParticleFlow/PFProducer/data/pfConversionAug0411_BDT.weights.xml.gz"));
379  descriptions.add("particleFlowEGamma", desc);
380 }
const edm::EDPutTokenT< reco::CaloClusterCollection > caloClusterCollectionESPutToken_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
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
const edm::EDPutTokenT< reco::ConversionCollection > conversionCollectionPutToken_
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:152
Trktree trk
Definition: Trktree.cc:2
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
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
Log< level::Error, false > LogError
const edm::EDPutTokenT< reco::PFCandidateEGammaExtraCollection > pfCandidateEGammaExtraCollectionPutToken_
std::vector< Vertex > VertexCollection
Definition: Vertex.h:31
assert(be >=bs)
std::vector< Conversion > ConversionCollection
collectin of Conversion objects
Definition: ConversionFwd.h:9
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const edm::ESGetToken< ESChannelStatus, ESChannelStatusRcd > esChannelStatusToken_
const edm::EDPutTokenT< reco::PFCandidateCollection > pfCandidateCollectionPutToken_
int iEvent
Definition: GenABIO.cc:224
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
std::vector< reco::PFCandidateEGammaExtra > PFCandidateEGammaExtraCollection
collection of PFCandidateEGammaExtras
def pv(vc)
Definition: MetAnalyzer.py:7
std::vector< CaloCluster > CaloClusterCollection
collection of CaloCluster objects
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float > > XYZVectorF
spatial vector with cartesian internal representation
Definition: Vector3D.h:16
const edm::EDPutTokenT< reco::SuperClusterCollection > superClusterCollectionPutToken_
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
Definition: PFBlockFwd.h:10
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
reco::ConversionCollection createSingleLegConversions(reco::PFCandidateEGammaExtraCollection &extras, const edm::RefProd< reco::ConversionCollection > &convProd) const
const edm::EDGetTokenT< reco::PFCluster::EEtoPSAssociation > eetopsSrc_
const edm::ESGetToken< ESEEIntercalibConstants, ESEEIntercalibConstantsRcd > esEEInterCalibToken_
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
const PFEGammaAlgo::GBRForests gbrForests_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const PFEGammaAlgo::PFEGConfigInfo pfEGConfigInfo_
particle flow algorithm configuration
const edm::EDGetTokenT< reco::VertexCollection > vertices_
const edm::EDGetTokenT< reco::PFBlockCollection > inputTagBlocks_
const edm::EDPutTokenT< reco::CaloClusterCollection > caloClusterCollectionEBEEPutToken_
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
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
#define LOGDRESSED(x)
PFEGammaProducer(const edm::ParameterSet &)
Producer for particle flow reconstructed particles (PFCandidates)
Definition: output.py:1
#define str(s)
primaryVertex
hltOfflineBeamSpot for HLTMON
def move(src, dest)
Definition: eostools.py:511