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
94  pfeg_->setEEtoPSAssociation(iEvent.get(eetopsSrc_));
95 
96  // preshower conditions
97  edm::ESHandle<ESEEIntercalibConstants> esEEInterCalibHandle_;
98  iSetup.get<ESEEIntercalibConstantsRcd>().get(esEEInterCalibHandle_);
99  pfeg_->setAlphaGamma_ESplanes_fromDB(esEEInterCalibHandle_.product());
100 
101  edm::ESHandle<ESChannelStatus> esChannelStatusHandle_;
102  iSetup.get<ESChannelStatusRcd>().get(esChannelStatusHandle_);
103  pfeg_->setESChannelStatus(esChannelStatusHandle_.product());
104 
105  //Assign the PFAlgo Parameters
107 
108  // get the collection of blocks
109 
110  LOGDRESSED("PFEGammaProducer")<<"getting blocks"<<std::endl;
111  auto blocks = iEvent.getHandle( inputTagBlocks_);
112 
113  LOGDRESSED("PFEGammaProducer")
114  <<"EGPFlow is starting..."<<std::endl;
115 
116 #ifdef PFLOW_DEBUG
117  assert( blocks.isValid() && "edm::Handle to blocks was null!");
118  std::ostringstream str;
119  //str<<(*pfAlgo_)<<std::endl;
120  // cout << (*pfAlgo_) << std::endl;
121  LOGDRESSED("PFEGammaProducer") <<str.str()<<std::endl;
122 #endif
123 
124  // sort elements in three lists:
125  std::list< reco::PFBlockRef > hcalBlockRefs;
126  std::list< reco::PFBlockRef > ecalBlockRefs;
127  std::list< reco::PFBlockRef > hoBlockRefs;
128  std::list< reco::PFBlockRef > otherBlockRefs;
129 
130  for( unsigned i=0; i<blocks->size(); ++i ) {
131  // reco::PFBlockRef blockref( blockh,i );
132  //reco::PFBlockRef blockref = createBlockRef( *blocks, i);
133  reco::PFBlockRef blockref(blocks, i);
134 
136  elements = blockref->elements();
137 
138  LOGDRESSED("PFEGammaProducer")
139  << "Found " << elements.size()
140  << " PFBlockElements in block: " << i << std::endl;
141 
142  bool singleEcalOrHcal = false;
143  if( elements.size() == 1 ){
144  switch( elements[0].type() ) {
146  edm::LogError("PFEGammaProducer")
147  << "PFBLOCKALGO BUG!!!! Found a SuperCluster in a block by itself!";
151  ecalBlockRefs.push_back( blockref );
152  singleEcalOrHcal = true;
153  break;
157  if (elements[0].clusterRef()->flags() & reco::CaloCluster::badHcalMarker) continue;
158  hcalBlockRefs.push_back( blockref );
159  singleEcalOrHcal = true;
160  break;
162  // Single HO elements are likely to be noise. Not considered for now.
163  hoBlockRefs.push_back( blockref );
164  singleEcalOrHcal = true;
165  break;
166  default:
167  break;
168  }
169  }
170 
171  if(!singleEcalOrHcal) {
172  otherBlockRefs.push_back( blockref );
173  }
174  }//loop blocks
175 
176  // loop on blocks that are not single ecal, single ps1, single ps2 , or
177  // single hcal and produce unbiased collection of EGamma Candidates
178 
179  //printf("loop over blocks\n");
180  unsigned nblcks = 0;
181 
182  // this auto is a const reco::PFBlockRef&
183  for( const auto& blockref : otherBlockRefs ) {
184  ++nblcks;
185  // this auto is a: const edm::OwnVector< reco::PFBlockElement >&
186  const auto& elements = blockref->elements();
187  // make a copy of the link data, which will be edited.
188  //PFBlock::LinkData linkData = block.linkData();
189 
190  pfeg_->buildAndRefineEGObjects(globalCache(),blockref);
191 
192  if( !pfeg_->getCandidates().empty() ) {
193  LOGDRESSED("PFEGammaProducer")
194  << "Block with " << elements.size()
195  << " elements produced "
196  << pfeg_->getCandidates().size()
197  << " e-g candidates!" << std::endl;
198  }
199 
200  const size_t egsize = egCandidates_->size();
201  egCandidates_->resize(egsize + pfeg_->getCandidates().size());
202  reco::PFCandidateCollection::iterator eginsertfrom =
203  egCandidates_->begin() + egsize;
204  std::move(pfeg_->getCandidates().begin(),
205  pfeg_->getCandidates().end(),
206  eginsertfrom);
207 
208  const size_t egxsize = egExtra_->size();
209  egExtra_->resize(egxsize + pfeg_->getEGExtra().size());
210  reco::PFCandidateEGammaExtraCollection::iterator egxinsertfrom =
211  egExtra_->begin() + egxsize;
212  std::move(pfeg_->getEGExtra().begin(),
213  pfeg_->getEGExtra().end(),
214  egxinsertfrom);
215 
216  const size_t rscsize = sClusters_->size();
217  sClusters_->resize(rscsize + pfeg_->getRefinedSCs().size());
218  reco::SuperClusterCollection::iterator rscinsertfrom =
219  sClusters_->begin() + rscsize;
220  std::move(pfeg_->getRefinedSCs().begin(),
221  pfeg_->getRefinedSCs().end(),
222  rscinsertfrom);
223  }
224 
225  LOGDRESSED("PFEGammaProducer")
226  << "Running PFEGammaAlgo on all blocks produced = "
227  << egCandidates_->size() << " e-g candidates!"
228  << std::endl;
229 
232 
235 
236  //set the correct references to refined SC and EG extra using the refprods
237  for (unsigned int i=0; i < egCandidates_->size(); ++i) {
238  reco::PFCandidate &cand = egCandidates_->at(i);
239  reco::PFCandidateEGammaExtra &xtra = egExtra_->at(i);
240 
241  reco::PFCandidateEGammaExtraRef extraref(egXtraProd,i);
242  reco::SuperClusterRef refinedSCRef(sClusterProd,i);
243 
244  xtra.setSuperClusterRef(refinedSCRef);
245  cand.setSuperClusterRef(refinedSCRef);
246  cand.setPFEGammaExtraRef(extraref);
247  }
248 
249  //build collections of output CaloClusters from the used PFClusters
250  auto caloClustersEBEE = std::make_unique<reco::CaloClusterCollection>();
251  auto caloClustersES = std::make_unique<reco::CaloClusterCollection>();
252 
253  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapEBEE; //maps of pfclusters to caloclusters
254  std::map<edm::Ptr<reco::CaloCluster>, unsigned int> pfClusterMapES;
255 
256  for( const auto& sc : *sClusters_ ) {
257  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus!=sc.clustersEnd(); ++pfclus) {
258  if (!pfClusterMapEBEE.count(*pfclus)) {
259  reco::CaloCluster caloclus(**pfclus);
260  caloClustersEBEE->push_back(caloclus);
261  pfClusterMapEBEE[*pfclus] = caloClustersEBEE->size() - 1;
262  }
263  else {
264  throw cms::Exception("PFEgammaProducer::produce")
265  << "Found an EB/EE pfcluster matched to more than one supercluster!"
266  << std::dec << std::endl;
267  }
268  }
269  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus!=sc.preshowerClustersEnd(); ++pfclus) {
270  if (!pfClusterMapES.count(*pfclus)) {
271  reco::CaloCluster caloclus(**pfclus);
272  caloClustersES->push_back(caloclus);
273  pfClusterMapES[*pfclus] = caloClustersES->size() - 1;
274  }
275  else {
276  throw cms::Exception("PFEgammaProducer::produce")
277  << "Found an ES pfcluster matched to more than one supercluster!"
278  << std::dec << std::endl;
279  }
280  }
281  }
282 
283  //put calocluster output collections in event and get orphan handles to create ptrs
284  auto const& caloClusHandleEBEE = iEvent.put(std::move(caloClustersEBEE),ebeeClustersCollection_);
285  auto const& caloClusHandleES = iEvent.put(std::move(caloClustersES),esClustersCollection_);
286 
287  //relink superclusters to output caloclusters
288  for( auto& sc : *sClusters_ ) {
289  edm::Ptr<reco::CaloCluster> seedptr(caloClusHandleEBEE,pfClusterMapEBEE[sc.seed()]);
290  sc.setSeed(seedptr);
291 
293  for (reco::CaloCluster_iterator pfclus = sc.clustersBegin(); pfclus!=sc.clustersEnd(); ++pfclus) {
294  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleEBEE,pfClusterMapEBEE[*pfclus]);
295  clusters.push_back(clusptr);
296  }
297  sc.setClusters(clusters);
298 
299  reco::CaloClusterPtrVector psclusters;
300  for (reco::CaloCluster_iterator pfclus = sc.preshowerClustersBegin(); pfclus!=sc.preshowerClustersEnd(); ++pfclus) {
301  edm::Ptr<reco::CaloCluster> clusptr(caloClusHandleES,pfClusterMapES[*pfclus]);
302  psclusters.push_back(clusptr);
303  }
304  sc.setPreshowerClusters(psclusters);
305  }
306 
307  //create and fill references to single leg conversions
309  auto singleLegConv_ = std::make_unique<reco::ConversionCollection>();
310  createSingleLegConversions(*egExtra_, *singleLegConv_, convProd);
311 
312  // release our demonspawn into the wild to cause havoc
313  iEvent.put(std::move(sClusters_));
314  iEvent.put(std::move(egExtra_));
315  iEvent.put(std::move(singleLegConv_));
316  iEvent.put(std::move(egCandidates_));
317 }
318 
319 //PFEGammaAlgo: a new method added to set the parameters for electron and photon reconstruction.
320 void
322 
323  //for MVA pass PV if there is one in the collection otherwise pass a dummy
324  if(!useVerticesForNeutral_) { // create a dummy PV
326  e(0, 0) = 0.0015 * 0.0015;
327  e(1, 1) = 0.0015 * 0.0015;
328  e(2, 2) = 15. * 15.;
329  reco::Vertex::Point p(0, 0, 0);
330  primaryVertex_ = reco::Vertex(p, e, 0, 0, 0);
331  }
332  cfg.primaryVtx = &primaryVertex_;
333  pfeg_.reset(new PFEGammaAlgo(cfg));
334 }
335 
336 void
338 {
339  primaryVertex_ = primaryVertices.front();
340  for(auto const& pv : primaryVertices) {
341  if(pv.isValid() && !pv.isFake()) {
342  primaryVertex_ = pv;
343  break;
344  }
345  }
346 
347  pfeg_->setPhotonPrimaryVtx(primaryVertex_ );
348 }
349 
351  reco::ConversionCollection &oneLegConversions,
353 {
354 
356  for (auto &extra : extras){
357  for (const auto &tkrefmva : extra.singleLegConvTrackRefMva()) {
358  const reco::Track &trk = *tkrefmva.first;
359 
360  const reco::Vertex convVtx(trk.innerPosition(), error);
361  std::vector<reco::TrackRef> OneLegConvVector;
362  OneLegConvVector.push_back(tkrefmva.first);
363  std::vector< float > OneLegMvaVector;
364  OneLegMvaVector.push_back(tkrefmva.second);
365  std::vector<reco::CaloClusterPtr> dummymatchingBC;
367  scPtrVec.push_back(edm::refToPtr(extra.superClusterRef()));
368 
369  std::vector<math::XYZPointF>trackPositionAtEcalVec;
370  std::vector<math::XYZPointF>innPointVec;
371  std::vector<math::XYZVectorF>trackPinVec;
372  std::vector<math::XYZVectorF>trackPoutVec;
373  math::XYZPointF trackPositionAtEcal(trk.outerPosition().X(), trk.outerPosition().Y(), trk.outerPosition().Z());
374  trackPositionAtEcalVec.push_back(trackPositionAtEcal);
375 
376  math::XYZPointF innPoint(trk.innerPosition().X(), trk.innerPosition().Y(), trk.innerPosition().Z());
377  innPointVec.push_back(innPoint);
378 
379  math::XYZVectorF trackPin(trk.innerMomentum().X(), trk.innerMomentum().Y(), trk.innerMomentum().Z());
380  trackPinVec.push_back(trackPin);
381 
382  math::XYZVectorF trackPout(trk.outerMomentum().X(), trk.outerMomentum().Y(), trk.outerMomentum().Z());
383  trackPoutVec.push_back( trackPout );
384 
385  float DCA = trk.d0() ;
386  float mvaval = tkrefmva.second;
387  reco::Conversion singleLegConvCandidate(scPtrVec,
388  OneLegConvVector,
389  trackPositionAtEcalVec,
390  convVtx,
391  dummymatchingBC,
392  DCA,
393  innPointVec,
394  trackPinVec,
395  trackPoutVec,
396  mvaval,
398  singleLegConvCandidate.setOneLegMVA(OneLegMvaVector);
399  oneLegConversions.push_back(singleLegConvCandidate);
400 
401  reco::ConversionRef convref(convProd,oneLegConversions.size()-1);
402  extra.addSingleLegConversionRef(convref);
403 
404  }
405 
406  }
407 
408 }
409 
412  desc.add<bool> ("useVerticesForNeutral", true);
413  desc.add<bool> ("produceEGCandsWithNoSuperCluster", false)->setComment("Allow building of candidates with no input or output supercluster?");
414  desc.add<double>("pf_electron_mvaCut", -0.1);
415  desc.add<bool> ("pf_electronID_crackCorrection", false);
416  desc.add<double>("pf_conv_mvaCut", 0.0);
417  desc.add<edm::InputTag> ("blocks", edm::InputTag("particleFlowBlock"))->setComment("PF Blocks label");
418  desc.add<edm::InputTag> ("EEtoPS_source", edm::InputTag("particleFlowClusterECAL"))->setComment("EE to PS association");
419  desc.add<edm::InputTag> ("vertexCollection", edm::InputTag("offlinePrimaryVertices"));
420  desc.add<edm::FileInPath>("pf_electronID_mvaWeightFile",
421  edm::FileInPath("RecoParticleFlow/PFProducer/data/PfElectrons23Jan_BDT.weights.xml.gz"));
422  desc.add<edm::FileInPath>("pf_convID_mvaWeightFile",
423  edm::FileInPath("RecoParticleFlow/PFProducer/data/pfConversionAug0411_BDT.weights.xml.gz"));
424  descriptions.add("particleFlowEGamma", desc);
425 }
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:125
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_
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:140
std::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration
Definition: PFEGammaAlgo.h:110
size_type size() const
Definition: OwnVector.h:264
void setPFVertexParameters(reco::VertexCollection const &primaryVertices)
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:114
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)
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:539
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
reco::Vertex primaryVertex_
Variables for PFEGamma.
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:326
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:150
const edm::EDGetTokenT< reco::PFCluster::EEtoPSAssociation > eetopsSrc_
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:72
primaryVertices
Definition: jets_cff.py:26
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:172
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:71
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:86
def move(src, dest)
Definition: eostools.py:511