CMS 3D CMS Logo

PFSimParticleProducer.cc
Go to the documentation of this file.
1 
59 
60 #include <memory>
61 #include <set>
62 #include <sstream>
63 #include <string>
64 
66 public:
68 
69  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
70 
71  void produce(edm::Event&, const edm::EventSetup&) override;
72 
74  void getSimIDs(const TrackHandle& trackh, std::vector<unsigned>& recTrackSimID);
75 
76 private:
81 
82  //MC Truth Matching
83  //modif-beg
87  //modif-end
88 
95 
97 
98  // parameters for retrieving true particles information --
99 
101  std::unique_ptr<FSimEvent> mySimEvent;
102 
103  // flags for the various tasks ---------------------------
104 
107 
109  bool verbose_;
110 };
111 
114 
116  // particleFlowSimParticle
118  desc.addUntracked<edm::InputTag>("fastSimProducer", edm::InputTag("fastSimProducer", "EcalHitsEB"));
119  desc.addUntracked<bool>("MCTruthMatchingInfo", false);
120  desc.add<edm::InputTag>("RecTracks", edm::InputTag("trackerDrivenElectronSeeds"));
121  desc.add<std::string>("Fitter", "KFFittingSmoother");
122  desc.add<edm::InputTag>("ecalRecHitsEE", edm::InputTag("caloRecHits", "EcalRecHitsEE"));
123  desc.add<edm::InputTag>("ecalRecHitsEB", edm::InputTag("caloRecHits", "EcalRecHitsEB"));
124  desc.addUntracked<bool>("process_RecTracks", false);
125  {
127  psd0.setUnknown();
128  desc.add<edm::ParameterSetDescription>("ParticleFilter", psd0);
129  }
130  desc.add<std::string>("TTRHBuilder", "WithTrackAngle");
131  desc.addUntracked<bool>("process_Particles", true);
132  desc.add<std::string>("Propagator", "PropagatorWithMaterial");
133  desc.add<edm::InputTag>("sim", edm::InputTag("g4SimHits"));
134  desc.addUntracked<bool>("verbose", false);
135  descriptions.add("particleFlowSimParticle", desc);
136 }
137 
138 using namespace std;
139 using namespace edm;
140 
142  processParticles_ = iConfig.getUntrackedParameter<bool>("process_Particles", true);
143 
144  inputTagSim_ = iConfig.getParameter<InputTag>("sim");
145  tokenSim_ = consumes<std::vector<SimTrack> >(inputTagSim_);
146  tokenSimVertices_ = consumes<std::vector<SimVertex> >(inputTagSim_);
147 
148  //retrieving collections for MC Truth Matching
149 
150  //modif-beg
151  inputTagFastSimProducer_ = iConfig.getUntrackedParameter<InputTag>("fastSimProducer");
152  tokenFastSimProducer_ = consumes<edm::PCaloHitContainer>(inputTagFastSimProducer_);
153  mctruthMatchingInfo_ = iConfig.getUntrackedParameter<bool>("MCTruthMatchingInfo", false);
154  //modif-end
155 
156  inputTagRecTracks_ = iConfig.getParameter<InputTag>("RecTracks");
157  tokenRecTracks_ = consumes<reco::PFRecTrackCollection>(inputTagRecTracks_);
158 
159  inputTagEcalRecHitsEB_ = iConfig.getParameter<InputTag>("ecalRecHitsEB");
160  tokenEcalRecHitsEB_ = consumes<EcalRecHitCollection>(inputTagEcalRecHitsEB_);
161  inputTagEcalRecHitsEE_ = iConfig.getParameter<InputTag>("ecalRecHitsEE");
162  tokenEcalRecHitsEE_ = consumes<EcalRecHitCollection>(inputTagEcalRecHitsEE_);
163 
164  pdtToken_ = esConsumes();
165 
166  verbose_ = iConfig.getUntrackedParameter<bool>("verbose", false);
167 
168  // register products
169  produces<reco::PFSimParticleCollection>();
170 
171  particleFilter_ = iConfig.getParameter<ParameterSet>("ParticleFilter");
172 
173  mySimEvent = std::make_unique<FSimEvent>(particleFilter_);
174 }
175 
177  // init Particle data table (from Pythia)
178  mySimEvent->initializePdt(&iSetup.getData(pdtToken_));
179 
180  LogDebug("PFSimParticleProducer") << "START event: " << iEvent.id().event() << " in run " << iEvent.id().run()
181  << endl;
182 
183  //MC Truth Matching only with Famos and UnFoldedMode option to true!!
184 
185  //vector to store the trackIDs of rectracks corresponding
186  //to the simulated particle.
187  std::vector<unsigned> recTrackSimID;
188 
189  //In order to know which simparticule contribute to
190  //a given Ecal RecHit energy, we need to access
191  //the PCAloHit from FastSim.
192 
193  typedef std::pair<double, unsigned> hitSimID;
194  std::vector<std::list<hitSimID> > caloHitsEBID(62000);
195  std::vector<double> caloHitsEBTotE(62000, 0.0);
196 
197  if (mctruthMatchingInfo_) {
198  //getting the PCAloHit
199  auto pcalohits = iEvent.getHandle(tokenFastSimProducer_);
200 
201  if (!pcalohits) {
202  ostringstream err;
203  err << "could not find pcaloHit "
204  << "fastSimProducer:EcalHitsEB";
205  LogError("PFSimParticleProducer") << err.str() << endl;
206 
207  throw cms::Exception("MissingProduct", err.str());
208  } else {
209  assert(pcalohits.isValid());
210 
211  edm::PCaloHitContainer::const_iterator it = pcalohits.product()->begin();
212  edm::PCaloHitContainer::const_iterator itend = pcalohits.product()->end();
213 
214  //loop on the PCaloHit from FastSim Calorimetry
215  for (; it != itend; ++it) {
216  EBDetId detid(it->id());
217 
218  if (it->energy() > 0.0) {
219  std::pair<double, unsigned> phitsimid = make_pair(it->energy(), it->geantTrackId());
220  caloHitsEBID[detid.hashedIndex()].push_back(phitsimid);
221  caloHitsEBTotE[detid.hashedIndex()] += it->energy(); //summing pcalhit energy
222  } //energy > 0
223 
224  } //loop PcaloHits
225  } //pcalohit handle access
226 
227  //Retrieving the PFRecTrack collection for
228  //Monte Carlo Truth Matching tool
230  try {
231  LogDebug("PFSimParticleProducer") << "getting PFRecTracks" << endl;
232  iEvent.getByToken(tokenRecTracks_, recTracks);
233 
234  } catch (cms::Exception& err) {
235  LogError("PFSimParticleProducer") << err << " cannot get collection "
236  << "particleFlowBlock"
237  << ":"
238  << "" << endl;
239  } //pfrectrack handle access
240 
241  //getting the simID corresponding to
242  //each of the PFRecTracks
243  getSimIDs(recTracks, recTrackSimID);
244 
245  } //mctruthMatchingInfo_ //modif
246 
247  // deal with true particles
248  if (processParticles_) {
249  auto pOutputPFSimParticleCollection = std::make_unique<reco::PFSimParticleCollection>();
250 
252  bool found = iEvent.getByToken(tokenSim_, simTracks);
253  if (!found) {
254  ostringstream err;
255  err << "cannot find sim tracks: " << inputTagSim_;
256  LogError("PFSimParticleProducer") << err.str() << endl;
257 
258  throw cms::Exception("MissingProduct", err.str());
259  }
260 
262  found = iEvent.getByToken(tokenSimVertices_, simVertices);
263  if (!found) {
264  LogError("PFSimParticleProducer") << "cannot find sim vertices: " << inputTagSim_ << endl;
265  return;
266  }
267 
268  mySimEvent->fill(*simTracks, *simVertices);
269 
270  if (verbose_)
271  mySimEvent->print();
272 
273  for (unsigned i = 0; i < mySimEvent->nTracks(); i++) {
274  const FSimTrack& fst = mySimEvent->track(i);
275 
276  int motherId = -1;
277  if (!fst.noMother()) // a mother exist
278  motherId = fst.mother().id();
279 
280  //This is finding out the simID corresponding
281  //to the recTrack
282 
283  //GETTING THE TRACK ID
284  unsigned recTrackID = 99999;
285  vector<unsigned> recHitContrib; //modif
286  vector<double> recHitContribFrac; //modif
287 
288  if (mctruthMatchingInfo_) { //modif
289 
290  for (unsigned lo = 0; lo < recTrackSimID.size(); lo++) {
291  if (i == recTrackSimID[lo]) {
292  recTrackID = lo;
293  } //match track
294  } //loop rectrack
295 
296  // get the ecalBarrel rechits for MC truth matching tool
298  bool found = iEvent.getByToken(tokenEcalRecHitsEB_, rhcHandle);
299  if (!found) {
300  ostringstream err;
301  err << "could not find rechits " << inputTagEcalRecHitsEB_;
302  LogError("PFSimParticleProducer") << err.str() << endl;
303 
304  throw cms::Exception("MissingProduct", err.str());
305  } else {
306  assert(rhcHandle.isValid());
307 
308  EBRecHitCollection::const_iterator it_rh = rhcHandle.product()->begin();
309  EBRecHitCollection::const_iterator itend_rh = rhcHandle.product()->end();
310 
311  for (; it_rh != itend_rh; ++it_rh) {
312  unsigned rhit_hi = EBDetId(it_rh->id()).hashedIndex();
313  EBDetId detid(it_rh->id());
314 
315  auto it_phit = caloHitsEBID[rhit_hi].begin();
316  auto itend_phit = caloHitsEBID[rhit_hi].end();
317  for (; it_phit != itend_phit; ++it_phit) {
318  if (i == it_phit->second) {
319  //Alex (08/10/08) TO BE REMOVED, eliminating
320  //duplicated rechits
321  bool alreadyin = false;
322  for (unsigned ihit = 0; ihit < recHitContrib.size(); ++ihit)
323  if (detid.rawId() == recHitContrib[ihit])
324  alreadyin = true;
325 
326  if (!alreadyin) {
327  double pcalofraction = 0.0;
328  if (caloHitsEBTotE[rhit_hi] != 0.0)
329  pcalofraction = (it_phit->first / caloHitsEBTotE[rhit_hi]) * 100.0;
330 
331  //store info
332  recHitContrib.push_back(it_rh->id());
333  recHitContribFrac.push_back(pcalofraction);
334  } //selected rechits
335  } //matching
336  } //loop pcalohit
337 
338  } //loop rechits
339 
340  } //getting the rechits
341 
342  } //mctruthMatchingInfo_ //modif
343 
344  reco::PFSimParticle particle(
345  fst.charge(), fst.type(), fst.id(), motherId, fst.daughters(), recTrackID, recHitContrib, recHitContribFrac);
346 
347  const FSimVertex& originVtx = fst.vertex();
348 
349  math::XYZPoint posOrig(originVtx.position().x(), originVtx.position().y(), originVtx.position().z());
350 
351  math::XYZTLorentzVector momOrig(
352  fst.momentum().px(), fst.momentum().py(), fst.momentum().pz(), fst.momentum().e());
353  reco::PFTrajectoryPoint pointOrig(-1, reco::PFTrajectoryPoint::ClosestApproach, posOrig, momOrig);
354 
355  // point 0 is origin vertex
356  particle.addPoint(pointOrig);
357 
358  if (!fst.noEndVertex()) {
359  const FSimVertex& endVtx = fst.endVertex();
360 
361  math::XYZPoint posEnd(endVtx.position().x(), endVtx.position().y(), endVtx.position().z());
362 
364 
366 
367  particle.addPoint(pointEnd);
368  } else { // add a dummy point
370  particle.addPoint(dummy);
371  }
372 
373  if (fst.onLayer1()) { // PS layer1
374  const RawParticle& rp = fst.layer1Entrance();
375 
376  math::XYZPoint posLayer1(rp.x(), rp.y(), rp.z());
377  math::XYZTLorentzVector momLayer1(rp.px(), rp.py(), rp.pz(), rp.e());
378  reco::PFTrajectoryPoint layer1Pt(-1, reco::PFTrajectoryPoint::PS1, posLayer1, momLayer1);
379 
380  particle.addPoint(layer1Pt);
381 
382  // extrapolate to cluster depth
383  } else { // add a dummy point
385  particle.addPoint(dummy);
386  }
387 
388  if (fst.onLayer2()) { // PS layer2
389  const RawParticle& rp = fst.layer2Entrance();
390 
391  math::XYZPoint posLayer2(rp.x(), rp.y(), rp.z());
392  math::XYZTLorentzVector momLayer2(rp.px(), rp.py(), rp.pz(), rp.e());
393  reco::PFTrajectoryPoint layer2Pt(-1, reco::PFTrajectoryPoint::PS2, posLayer2, momLayer2);
394 
395  particle.addPoint(layer2Pt);
396 
397  // extrapolate to cluster depth
398  } else { // add a dummy point
400  particle.addPoint(dummy);
401  }
402 
403  if (fst.onEcal()) {
404  const RawParticle& rp = fst.ecalEntrance();
405 
406  math::XYZPoint posECAL(rp.x(), rp.y(), rp.z());
407  math::XYZTLorentzVector momECAL(rp.px(), rp.py(), rp.pz(), rp.e());
409 
410  particle.addPoint(ecalPt);
411 
412  // extrapolate to cluster depth
413  } else { // add a dummy point
415  particle.addPoint(dummy);
416  }
417 
418  // add a dummy point for ECAL Shower max
420  particle.addPoint(dummy);
421 
422  if (fst.onHcal()) {
423  const RawParticle& rpin = fst.hcalEntrance();
424 
425  math::XYZPoint posHCALin(rpin.x(), rpin.y(), rpin.z());
426  math::XYZTLorentzVector momHCALin(rpin.px(), rpin.py(), rpin.pz(), rpin.e());
427  reco::PFTrajectoryPoint hcalPtin(-1, reco::PFTrajectoryPoint::HCALEntrance, posHCALin, momHCALin);
428 
429  particle.addPoint(hcalPtin);
430 
431  const RawParticle& rpout = fst.hcalExit();
432 
433  math::XYZPoint posHCALout(rpout.x(), rpout.y(), rpout.z());
434  math::XYZTLorentzVector momHCALout(rpout.px(), rpout.py(), rpout.pz(), rpout.e());
435  reco::PFTrajectoryPoint hcalPtout(-1, reco::PFTrajectoryPoint::HCALExit, posHCALout, momHCALout);
436 
437  particle.addPoint(hcalPtout);
438 
439  const RawParticle& rpho = fst.hoEntrance();
440 
441  math::XYZPoint posHOEntrance(rpho.x(), rpho.y(), rpho.z());
442  math::XYZTLorentzVector momHOEntrance(rpho.px(), rpho.py(), rpho.pz(), rpho.e());
443  reco::PFTrajectoryPoint hoPtin(-1, reco::PFTrajectoryPoint::HOLayer, posHOEntrance, momHOEntrance);
444 
445  particle.addPoint(hoPtin);
446 
447  } else { // add a dummy point
449  particle.addPoint(dummy);
450  }
451 
452  pOutputPFSimParticleCollection->push_back(particle);
453  }
454 
455  iEvent.put(std::move(pOutputPFSimParticleCollection));
456  }
457 
458  LogDebug("PFSimParticleProducer") << "STOP event: " << iEvent.id().event() << " in run " << iEvent.id().run() << endl;
459 }
460 
461 void PFSimParticleProducer::getSimIDs(const TrackHandle& trackh, std::vector<unsigned>& recTrackSimID) {
462  if (trackh.isValid()) {
463  for (unsigned i = 0; i < trackh->size(); i++) {
464  const reco::PFRecTrackRef ref(trackh, i);
465 
466  for (auto const& hit : ref->trackRef()->recHits()) {
467  if (hit->isValid()) {
468  auto rechit = dynamic_cast<const FastTrackerRecHit*>(hit);
469 
470  for (unsigned int st_index = 0; st_index < rechit->nSimTrackIds(); ++st_index) {
471  recTrackSimID.push_back(rechit->simTrackId(st_index));
472  }
473  break;
474  }
475  } //loop track rechit
476  } //loop recTracks
477  } //track handle valid
478 }
PFSimParticleProducer(const edm::ParameterSet &)
bool noMother() const
no mother particle
std::unique_ptr< FSimEvent > mySimEvent
bool processParticles_
process particles on/off
edm::InputTag inputTagEcalRecHitsEE_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
double x() const
x of vertex
Definition: RawParticle.h:282
edm::EDGetTokenT< EcalRecHitCollection > tokenEcalRecHitsEE_
const RawParticle & hcalEntrance() const
The particle at HCAL entrance.
Definition: FSimTrack.h:146
const RawParticle & layer2Entrance() const
The particle at Preshower Layer 2.
Definition: FSimTrack.h:140
edm::Handle< reco::PFRecTrackCollection > TrackHandle
const RawParticle & ecalEntrance() const
The particle at ECAL entrance.
Definition: FSimTrack.h:143
edm::ParameterSet particleFilter_
T const * product() const
Definition: Handle.h:70
std::vector< EcalRecHit >::const_iterator const_iterator
edm::InputTag inputTagEcalRecHitsEB_
int onHcal() const
Definition: FSimTrack.h:116
const RawParticle & hoEntrance() const
The particle at HCAL exir.
Definition: FSimTrack.h:155
Log< level::Error, false > LogError
bool noEndVertex() const
no end vertex
assert(be >=bs)
Producer for PFRecTracks and PFSimParticles.
const FSimVertex vertex() const
Origin vertex.
edm::EDGetTokenT< reco::PFRecTrackCollection > tokenRecTracks_
double px() const
x of the momentum
Definition: RawParticle.h:296
const FSimVertex & endVertex() const
end vertex
T getUntrackedParameter(std::string const &, T const &) const
void produce(edm::Event &, const edm::EventSetup &) override
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:22
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
int hashedIndex(int ieta, int iphi)
Definition: EcalPyUtils.cc:36
int iEvent
Definition: GenABIO.cc:224
const XYZTLorentzVector & momentum() const
Temporary (until move of SimTrack to Mathcore) - No! Actually very useful.
Definition: FSimTrack.h:209
edm::InputTag inputTagSim_
module label for retrieving input simtrack and simvertex
const RawParticle & hcalExit() const
The particle at HCAL exir.
Definition: FSimTrack.h:152
Point of closest approach from beam axis (initial point in the case of PFSimParticle) ...
edm::EDGetTokenT< std::vector< SimTrack > > tokenSim_
float charge() const
charge
Definition: FSimTrack.h:56
edm::ESGetToken< HepPDT::ParticleDataTable, edm::DefaultRecord > pdtToken_
double z() const
z of vertex
Definition: RawParticle.h:284
const std::vector< int > & daughters() const
Vector of daughter indices.
int onLayer2() const
Definition: FSimTrack.h:106
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
double py() const
y of the momentum
Definition: RawParticle.h:299
int onLayer1() const
Definition: FSimTrack.h:101
bool getData(T &iHolder) const
Definition: EventSetup.h:122
const_iterator begin() const
double y() const
y of vertex
Definition: RawParticle.h:283
true particle for particle flow
Definition: PFSimParticle.h:19
int onEcal() const
Definition: FSimTrack.h:111
double pz() const
z of the momentum
Definition: RawParticle.h:302
edm::EDGetTokenT< edm::PCaloHitContainer > tokenFastSimProducer_
const_iterator end() const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
edm::EDGetTokenT< EcalRecHitCollection > tokenEcalRecHitsEB_
const math::XYZTLorentzVector & position() const
Temporary (until CMSSW moves to Mathcore) - No ! Actually very useful.
Definition: FSimVertex.h:48
void add(std::string const &label, ParameterSetDescription const &psetDescription)
bool isValid() const
Definition: HandleBase.h:70
HLT enums.
A PFTrack holds several trajectory points, which basically contain the position and momentum of a tra...
const RawParticle & layer1Entrance() const
The particle at Preshower Layer 1.
Definition: FSimTrack.h:137
double e() const
energy of the momentum
Definition: RawParticle.h:305
void getSimIDs(const TrackHandle &trackh, std::vector< unsigned > &recTrackSimID)
def move(src, dest)
Definition: eostools.py:511
int id() const
the index in FBaseSimEvent and other vectors
Definition: FSimTrack.h:96
edm::EDGetTokenT< std::vector< SimVertex > > tokenSimVertices_
const FSimTrack & mother() const
mother
edm::InputTag inputTagFastSimProducer_
#define LogDebug(id)