CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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>()},
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  },
93  iConfig,
94  },
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  unsigned nblcks = 0;
196 
197  // this auto is a const reco::PFBlockRef&
198  for (const auto& blockref : otherBlockRefs) {
199  ++nblcks;
200  // this auto is a: const edm::OwnVector< reco::PFBlockElement >&
201  const auto& elements = blockref->elements();
202  // make a copy of the link data, which will be edited.
203  //PFBlock::LinkData linkData = block.linkData();
204 
205  auto output = pfEGammaAlgo(blockref);
206 
207  if (!output.candidates.empty()) {
208  LOGDRESSED("PFEGammaProducer") << "Block with " << elements.size() << " elements produced "
209  << output.candidates.size() << " e-g candidates!" << std::endl;
210  }
211 
212  const size_t egsize = egCandidates.size();
213  egCandidates.resize(egsize + output.candidates.size());
214  std::move(output.candidates.begin(), output.candidates.end(), egCandidates.begin() + egsize);
215 
216  const size_t egxsize = egExtra.size();
217  egExtra.resize(egxsize + output.candidateExtras.size());
218  std::move(output.candidateExtras.begin(), output.candidateExtras.end(), egExtra.begin() + egxsize);
219 
220  const size_t rscsize = sClusters.size();
221  sClusters.resize(rscsize + output.refinedSuperClusters.size());
222  std::move(output.refinedSuperClusters.begin(), output.refinedSuperClusters.end(), sClusters.begin() + rscsize);
223  }
224 
225  LOGDRESSED("PFEGammaProducer") << "Running PFEGammaAlgo on all blocks produced = " << egCandidates.size()
226  << " e-g candidates!" << std::endl;
227 
228  auto sClusterProd = iEvent.getRefBeforePut<reco::SuperClusterCollection>();
229  auto egXtraProd = iEvent.getRefBeforePut<reco::PFCandidateEGammaExtraCollection>();
230 
231  //set the correct references to refined SC and EG extra using the refprods
232  for (unsigned int i = 0; i < egCandidates.size(); ++i) {
233  reco::PFCandidate& cand = egCandidates.at(i);
234  reco::PFCandidateEGammaExtra& xtra = egExtra.at(i);
235 
236  reco::PFCandidateEGammaExtraRef extraref(egXtraProd, i);
237  reco::SuperClusterRef refinedSCRef(sClusterProd, i);
238 
239  xtra.setSuperClusterRef(refinedSCRef);
240  cand.setSuperClusterRef(refinedSCRef);
241  cand.setPFEGammaExtraRef(extraref);
242  }
243 
244  //build collections of output CaloClusters from the used PFClusters
245  reco::CaloClusterCollection caloClustersEBEE{};
246  reco::CaloClusterCollection caloClustersES{};
247 
248  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapEBEE; //maps of pfclusters to caloclusters
249  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapES;
250 
251  for (const auto& sc : sClusters) {
252  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus != sc.clustersEnd(); ++pfclus) {
253  if (!pfClusterMapEBEE.count(*pfclus)) {
254  reco::CaloCluster caloclus(**pfclus);
255  caloClustersEBEE.push_back(caloclus);
256  pfClusterMapEBEE[*pfclus] = caloClustersEBEE.size() - 1;
257  } else {
258  throw cms::Exception("PFEgammaProducer::produce")
259  << "Found an EB/EE pfcluster matched to more than one supercluster!" << std::dec << std::endl;
260  }
261  }
262  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus != sc.preshowerClustersEnd();
263  ++pfclus) {
264  if (!pfClusterMapES.count(*pfclus)) {
265  reco::CaloCluster caloclus(**pfclus);
266  caloClustersES.push_back(caloclus);
267  pfClusterMapES[*pfclus] = caloClustersES.size() - 1;
268  } else {
269  throw cms::Exception("PFEgammaProducer::produce")
270  << "Found an ES pfcluster matched to more than one supercluster!" << std::dec << std::endl;
271  }
272  }
273  }
274 
275  //put calocluster output collections in event and get orphan handles to create ptrs
276  auto const& caloClusHandleEBEE = iEvent.emplace(caloClusterCollectionEBEEPutToken_, std::move(caloClustersEBEE));
277  auto const& caloClusHandleES = iEvent.emplace(caloClusterCollectionESPutToken_, std::move(caloClustersES));
278 
279  //relink superclusters to output caloclusters
280  for (auto& sc : sClusters) {
281  edm::Ptr<reco::CaloCluster> seedptr(caloClusHandleEBEE, pfClusterMapEBEE[sc.seed()]);
282  sc.setSeed(seedptr);
283 
285  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus != sc.clustersEnd(); ++pfclus) {
286  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleEBEE, pfClusterMapEBEE[*pfclus]);
287  clusters.push_back(clusptr);
288  }
289  sc.setClusters(clusters);
290 
291  reco::CaloClusterPtrVector psclusters;
292  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus != sc.preshowerClustersEnd();
293  ++pfclus) {
294  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleES, pfClusterMapES[*pfclus]);
295  psclusters.push_back(clusptr);
296  }
297  sc.setPreshowerClusters(psclusters);
298  }
299 
300  //create and fill references to single leg conversions
301  auto singleLegConv = createSingleLegConversions(egExtra, iEvent.getRefBeforePut<reco::ConversionCollection>());
302 
303  // release our demonspawn into the wild to cause havoc
306  iEvent.emplace(conversionCollectionPutToken_, std::move(singleLegConv));
307  iEvent.emplace(pfCandidateCollectionPutToken_, std::move(egCandidates));
308 }
309 
312  reco::ConversionCollection oneLegConversions{};
314  for (auto& extra : extras) {
315  for (const auto& tkrefmva : extra.singleLegConvTrackRefMva()) {
316  const reco::Track& trk = *tkrefmva.first;
317 
318  const reco::Vertex convVtx(trk.innerPosition(), error);
319  std::vector<reco::TrackRef> OneLegConvVector;
320  OneLegConvVector.push_back(tkrefmva.first);
321  std::vector<float> OneLegMvaVector;
322  OneLegMvaVector.push_back(tkrefmva.second);
323  std::vector<reco::CaloClusterPtr> dummymatchingBC;
325  scPtrVec.push_back(edm::refToPtr(extra.superClusterRef()));
326 
327  std::vector<math::XYZPointF> trackPositionAtEcalVec;
328  std::vector<math::XYZPointF> innPointVec;
329  std::vector<math::XYZVectorF> trackPinVec;
330  std::vector<math::XYZVectorF> trackPoutVec;
331  math::XYZPointF trackPositionAtEcal(trk.outerPosition().X(), trk.outerPosition().Y(), trk.outerPosition().Z());
332  trackPositionAtEcalVec.push_back(trackPositionAtEcal);
333 
334  math::XYZPointF innPoint(trk.innerPosition().X(), trk.innerPosition().Y(), trk.innerPosition().Z());
335  innPointVec.push_back(innPoint);
336 
337  math::XYZVectorF trackPin(trk.innerMomentum().X(), trk.innerMomentum().Y(), trk.innerMomentum().Z());
338  trackPinVec.push_back(trackPin);
339 
340  math::XYZVectorF trackPout(trk.outerMomentum().X(), trk.outerMomentum().Y(), trk.outerMomentum().Z());
341  trackPoutVec.push_back(trackPout);
342 
343  float DCA = trk.d0();
344  float mvaval = tkrefmva.second;
345  reco::Conversion singleLegConvCandidate(scPtrVec,
346  OneLegConvVector,
347  trackPositionAtEcalVec,
348  convVtx,
349  dummymatchingBC,
350  DCA,
351  innPointVec,
352  trackPinVec,
353  trackPoutVec,
354  mvaval,
356  singleLegConvCandidate.setOneLegMVA(OneLegMvaVector);
357  oneLegConversions.push_back(singleLegConvCandidate);
358 
359  reco::ConversionRef convref(convProd, oneLegConversions.size() - 1);
360  extra.addSingleLegConversionRef(convref);
361  }
362  }
363  return oneLegConversions;
364 }
365 
368  desc.add<bool>("produceEGCandsWithNoSuperCluster", false)
369  ->setComment("Allow building of candidates with no input or output supercluster?");
370  desc.add<double>("pf_electron_mvaCut", -0.1);
371  desc.add<bool>("pf_electronID_crackCorrection", false);
372  desc.add<double>("pf_conv_mvaCut", 0.0);
373  desc.add<edm::InputTag>("blocks", edm::InputTag("particleFlowBlock"))->setComment("PF Blocks label");
374  desc.add<edm::InputTag>("EEtoPS_source", edm::InputTag("particleFlowClusterECAL"))
375  ->setComment("EE to PS association");
376  desc.add<edm::InputTag>("vertexCollection", edm::InputTag("offlinePrimaryVertices"));
377  desc.add<edm::FileInPath>("pf_electronID_mvaWeightFile",
378  edm::FileInPath("RecoParticleFlow/PFProducer/data/PfElectrons23Jan_BDT.weights.xml.gz"));
379  desc.add<edm::FileInPath>("pf_convID_mvaWeightFile",
380  edm::FileInPath("RecoParticleFlow/PFProducer/data/pfConversionAug0411_BDT.weights.xml.gz"));
381  descriptions.add("particleFlowEGamma", desc);
382 }
RunNumber_t run() const
Definition: EventID.h:38
EventNumber_t event() const
Definition: EventID.h:40
const edm::EDPutTokenT< reco::CaloClusterCollection > caloClusterCollectionESPutToken_
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_
double d0() const
dxy parameter in perigee convention (d0 = -dxy)
Definition: TrackBase.h:611
tuple primaryVertices
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:149
reco::ConversionCollection createSingleLegConversions(reco::PFCandidateEGammaExtraCollection &extras, const edm::RefProd< reco::ConversionCollection > &convProd) const
size_type size() const
Definition: OwnVector.h:300
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
tuple blocks
Definition: gather_cfg.py:90
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_
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:62
std::vector< Vertex > VertexCollection
Definition: Vertex.h:12
assert(be >=bs)
std::vector< Conversion > ConversionCollection
collectin of Conversion objects
Definition: ConversionFwd.h:9
dictionary elements
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:56
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const edm::ESGetToken< ESChannelStatus, ESChannelStatusRcd > esChannelStatusToken_
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:563
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 move
Definition: eostools.py:511
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:346
std::vector< CaloCluster > CaloClusterCollection
collection of CaloCluster objects
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)
const edm::EDPutTokenT< reco::SuperClusterCollection > superClusterCollectionPutToken_
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
Definition: PFBlockFwd.h:10
RefProd< PROD > getRefBeforePut()
Definition: Event.h:158
const edm::EDGetTokenT< reco::PFCluster::EEtoPSAssociation > eetopsSrc_
const edm::ESGetToken< ESEEIntercalibConstants, ESEEIntercalibConstantsRcd > esEEInterCalibToken_
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:65
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&...args)
puts a new product
Definition: Event.h:433
const PFEGammaAlgo::GBRForests gbrForests_
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
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_
edm::EventID id() const
Definition: EventBase.h:59
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
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)
void setPFEGammaExtraRef(const reco::PFCandidateEGammaExtraRef &ref)
set the PF EGamma Extra Ref
Definition: PFCandidate.cc:618
PFEGammaProducer(const edm::ParameterSet &)
void setSuperClusterRef(const reco::SuperClusterRef &scRef)
Definition: PFCandidate.cc:598
Producer for particle flow reconstructed particles (PFCandidates)
tuple applyCrackCorrections
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:157
#define str(s)