CMS 3D CMS Logo

GenParticleProducer.cc
Go to the documentation of this file.
1 /* \class GenParticleProducer
2  *
3  * \author Luca Lista, INFN
4  *
5  * Convert HepMC GenEvent format into a collection of type
6  * CandidateCollection containing objects of type GenParticle
7  *
8  *
9  */
18 
19 #include <vector>
20 #include <string>
21 #include <unordered_map>
22 
23 namespace edm {
24  class ParameterSet;
25 }
26 namespace HepMC {
27  class GenParticle;
28  class GenEvent;
29 } // namespace HepMC
30 
31 static constexpr int PDGCacheMax = 32768;
32 
33 namespace {
34  struct IDto3Charge {
35  IDto3Charge(HepPDT::ParticleDataTable const&, bool abortOnUnknownPDGCode);
36 
37  int chargeTimesThree(int) const;
38 
39  private:
40  std::vector<int> chargeP_, chargeM_;
41  std::unordered_map<int, int> chargeMap_;
42  bool abortOnUnknownPDGCode_;
43  };
44 
45  IDto3Charge::IDto3Charge(HepPDT::ParticleDataTable const& iTable, bool iAbortOnUnknownPDGCode)
46  : chargeP_(PDGCacheMax, 0), chargeM_(PDGCacheMax, 0), abortOnUnknownPDGCode_(iAbortOnUnknownPDGCode) {
47  for (auto const& p : iTable) {
48  const HepPDT::ParticleID& id = p.first;
49  int pdgId = id.pid(), apdgId = std::abs(pdgId);
50  int q3 = id.threeCharge();
51  if (apdgId < PDGCacheMax && pdgId > 0) {
52  chargeP_[apdgId] = q3;
53  chargeM_[apdgId] = -q3;
54  } else if (apdgId < PDGCacheMax) {
55  chargeP_[apdgId] = -q3;
56  chargeM_[apdgId] = q3;
57  } else {
58  chargeMap_.emplace(pdgId, q3);
59  chargeMap_.emplace(-pdgId, -q3);
60  }
61  }
62  }
63 
64  int IDto3Charge::chargeTimesThree(int id) const {
65  if (std::abs(id) < PDGCacheMax)
66  return id > 0 ? chargeP_[id] : chargeM_[-id];
67  auto f = chargeMap_.find(id);
68  if (f == chargeMap_.end()) {
69  if (abortOnUnknownPDGCode_)
70  throw edm::Exception(edm::errors::LogicError) << "invalid PDG id: " << id;
71  else
72  return HepPDT::ParticleID(id).threeCharge();
73  }
74  return f->second;
75  }
76 
77 } // namespace
78 
79 class GenParticleProducer : public edm::global::EDProducer<edm::RunCache<IDto3Charge>> {
80 public:
84  ~GenParticleProducer() override;
85 
87  void produce(edm::StreamID, edm::Event& e, const edm::EventSetup&) const override;
88  std::shared_ptr<IDto3Charge> globalBeginRun(const edm::Run&, const edm::EventSetup&) const override;
89  void globalEndRun(edm::Run const&, edm::EventSetup const&) const override{};
90 
91  bool convertParticle(reco::GenParticle& cand, const HepMC::GenParticle* part, const IDto3Charge& id2Charge) const;
93  const HepMC::GenParticle* part,
94  reco::GenParticleRefProd const& ref,
95  size_t index,
96  std::unordered_map<int, size_t>& barcodes) const;
97  bool fillIndices(const HepMC::GenEvent* mc,
98  std::vector<const HepMC::GenParticle*>& particles,
99  std::vector<int>& barCodeVector,
100  int offset,
101  std::unordered_map<int, size_t>& barcodes) const;
102 
103 private:
106  std::vector<edm::EDGetTokenT<edm::HepMCProduct>> vectorSrcTokens_;
108 
113 
116  bool useCF_;
117 
120 };
121 
123 
124 //#include "SimDataFormats/HiGenData/interface/SubEventMap.h"
126 
135 #include <fstream>
136 #include <algorithm>
137 using namespace edm;
138 using namespace reco;
139 using namespace std;
140 using namespace HepMC;
141 
142 static const double mmToCm = 0.1;
143 static const double mmToNs = 1.0 / 299792458e-6;
144 
146  : abortOnUnknownPDGCode_(cfg.getUntrackedParameter<bool>("abortOnUnknownPDGCode", true)),
147  saveBarCodes_(cfg.getUntrackedParameter<bool>("saveBarCodes", false)),
148  doSubEvent_(cfg.getUntrackedParameter<bool>("doSubEvent", false)),
149  useCF_(cfg.getUntrackedParameter<bool>("useCrossingFrame", false)) {
150  produces<GenParticleCollection>();
151  produces<math::XYZPointF>("xyz0");
152  produces<float>("t0");
153  if (saveBarCodes_) {
154  std::string alias(cfg.getParameter<std::string>("@module_label"));
155  produces<vector<int>>().setBranchAlias(alias + "BarCodes");
156  }
157 
158  if (useCF_)
159  mixToken_ =
160  mayConsume<CrossingFrame<HepMCProduct>>(InputTag(cfg.getParameter<std::string>("mix"), "generatorSmeared"));
161  else
162  srcToken_ = mayConsume<HepMCProduct>(cfg.getParameter<InputTag>("src"));
163 }
164 
166 
167 std::shared_ptr<IDto3Charge> GenParticleProducer::globalBeginRun(const Run&, const EventSetup& es) const {
169  es.getData(pdt);
170  return std::make_shared<IDto3Charge>(*pdt, abortOnUnknownPDGCode_);
171 }
172 
174  std::unordered_map<int, size_t> barcodes;
175 
176  size_t totalSize = 0;
177  const GenEvent* mc = nullptr;
178  MixCollection<HepMCProduct>* cfhepmcprod = nullptr;
179  size_t npiles = 1;
180 
181  if (useCF_) {
183  evt.getByToken(mixToken_, cf);
184  cfhepmcprod = new MixCollection<HepMCProduct>(cf.product());
185  npiles = cfhepmcprod->size();
186  LogDebug("GenParticleProducer") << "npiles : " << npiles << endl;
187  for (unsigned int icf = 0; icf < npiles; ++icf) {
188  LogDebug("GenParticleProducer") << "subSize : " << cfhepmcprod->getObject(icf).GetEvent()->particles_size()
189  << endl;
190  totalSize += cfhepmcprod->getObject(icf).GetEvent()->particles_size();
191  }
192  LogDebug("GenParticleProducer") << "totalSize : " << totalSize << endl;
193  } else {
195  evt.getByToken(srcToken_, mcp);
196  mc = mcp->GetEvent();
197  if (mc == nullptr)
198  throw edm::Exception(edm::errors::InvalidReference) << "HepMC has null pointer to GenEvent" << endl;
199  totalSize = mc->particles_size();
200  }
201 
202  // initialise containers
203  const size_t size = totalSize;
204  vector<const HepMC::GenParticle*> particles(size);
205  auto candsPtr = std::make_unique<GenParticleCollection>(size);
206  auto barCodeVector = std::make_unique<vector<int>>(size);
207  std::unique_ptr<math::XYZPointF> xyz0Ptr(new math::XYZPointF(0., 0., 0.));
208  std::unique_ptr<float> t0Ptr(new float(0.f));
210  GenParticleCollection& cands = *candsPtr;
211  size_t offset = 0;
212  size_t suboffset = 0;
213 
214  IDto3Charge const& id2Charge = *runCache(evt.getRun().index());
216  if (doSubEvent_ || useCF_) {
217  for (size_t ipile = 0; ipile < npiles; ++ipile) {
218  LogDebug("GenParticleProducer") << "mixed object ipile : " << ipile << endl;
219  barcodes.clear();
220  if (useCF_)
221  mc = cfhepmcprod->getObject(ipile).GetEvent();
222 
223  //Look whether heavy ion/signal event
224  bool isHI = false;
225  const HepMC::HeavyIon* hi = mc->heavy_ion();
226  if (hi && hi->Ncoll_hard() > 1)
227  isHI = true;
228  size_t num_particles = mc->particles_size();
229  LogDebug("GenParticleProducer") << "num_particles : " << num_particles << endl;
230  if (ipile == 0) {
231  auto origin = (*mc->vertices_begin())->position();
232  xyz0Ptr->SetXYZ(origin.x() * mmToCm, origin.y() * mmToCm, origin.z() * mmToCm);
233  *t0Ptr = origin.t() * mmToNs;
234  }
235  fillIndices(mc, particles, *barCodeVector, offset, barcodes);
236  // fill output collection and save association
237  for (size_t ipar = offset; ipar < offset + num_particles; ++ipar) {
238  const HepMC::GenParticle* part = particles[ipar];
239  reco::GenParticle& cand = cands[ipar];
240  // convert HepMC::GenParticle to new reco::GenParticle
241  convertParticle(cand, part, id2Charge);
242  cand.resetDaughters(ref.id());
243  }
244 
245  for (size_t d = offset; d < offset + num_particles; ++d) {
247  const GenVertex* productionVertex = part->production_vertex();
248  int sub_id = 0;
249  if (productionVertex != nullptr) {
250  sub_id = productionVertex->id();
251  if (!isHI)
252  sub_id = 0;
253  // search barcode map and attach daughters
254  fillDaughters(cands, part, ref, d, barcodes);
255  } else {
256  const GenVertex* endVertex = part->end_vertex();
257  if (endVertex != nullptr)
258  sub_id = endVertex->id();
259  else
260  throw cms::Exception("SubEventID")
261  << "SubEvent not determined. Particle has no production and no end vertex!" << endl;
262  }
263  if (sub_id < 0)
264  sub_id = 0;
265  int new_id = sub_id + suboffset;
266  GenParticleRef dref(ref, d);
267  cands[d].setCollisionId(new_id); // For new GenParticle
268  LogDebug("VertexId") << "SubEvent offset 3 : " << suboffset;
269  }
270  int nsub = -2;
271  if (isHI) {
272  nsub = hi->Ncoll_hard() + 1;
273  suboffset += nsub;
274  } else {
275  suboffset += 1;
276  }
277  offset += num_particles;
278  }
279  } else {
280  auto origin = (*mc->vertices_begin())->position();
281  xyz0Ptr->SetXYZ(origin.x() * mmToCm, origin.y() * mmToCm, origin.z() * mmToCm);
282  *t0Ptr = origin.t() * mmToNs;
283  fillIndices(mc, particles, *barCodeVector, 0, barcodes);
284 
285  // fill output collection and save association
286  for (size_t i = 0; i < particles.size(); ++i) {
289  // convert HepMC::GenParticle to new reco::GenParticle
290  convertParticle(cand, part, id2Charge);
291  cand.resetDaughters(ref.id());
292  }
293 
294  // fill references to daughters
295  for (size_t d = 0; d < cands.size(); ++d) {
297  const GenVertex* productionVertex = part->production_vertex();
298  // search barcode map and attach daughters
299  if (productionVertex != nullptr)
300  fillDaughters(cands, part, ref, d, barcodes);
301  cands[d].setCollisionId(0);
302  }
303  }
304 
305  evt.put(std::move(candsPtr));
306  if (saveBarCodes_)
307  evt.put(std::move(barCodeVector));
308  if (cfhepmcprod)
309  delete cfhepmcprod;
310  evt.put(std::move(xyz0Ptr), "xyz0");
311  evt.put(std::move(t0Ptr), "t0");
312 }
313 
315  const HepMC::GenParticle* part,
316  IDto3Charge const& id2Charge) const {
317  Candidate::LorentzVector p4(part->momentum());
318  int pdgId = part->pdg_id();
319  cand.setThreeCharge(id2Charge.chargeTimesThree(pdgId));
320  cand.setPdgId(pdgId);
321  cand.setStatus(part->status());
322  cand.setP4(p4);
323  cand.setCollisionId(0);
324  const GenVertex* v = part->production_vertex();
325  if (v != nullptr) {
326  ThreeVector vtx = v->point3d();
327  Candidate::Point vertex(vtx.x() * mmToCm, vtx.y() * mmToCm, vtx.z() * mmToCm);
328  cand.setVertex(vertex);
329  } else {
330  cand.setVertex(Candidate::Point(0, 0, 0));
331  }
332  mcTruthHelper_.fillGenStatusFlags(*part, cand.statusFlags());
333  return true;
334 }
335 
337  const HepMC::GenParticle* part,
338  reco::GenParticleRefProd const& ref,
339  size_t index,
340  std::unordered_map<int, size_t>& barcodes) const {
341  const GenVertex* productionVertex = part->production_vertex();
342  size_t numberOfMothers = productionVertex->particles_in_size();
343  if (numberOfMothers > 0) {
344  GenVertex::particles_in_const_iterator motherIt = productionVertex->particles_in_const_begin();
345  for (; motherIt != productionVertex->particles_in_const_end(); motherIt++) {
346  const HepMC::GenParticle* mother = *motherIt;
347  size_t m = barcodes.find(mother->barcode())->second;
348  cands[m].addDaughter(GenParticleRef(ref, index));
349  cands[index].addMother(GenParticleRef(ref, m));
350  }
351  }
352 
353  return true;
354 }
355 
357  vector<const HepMC::GenParticle*>& particles,
358  vector<int>& barCodeVector,
359  int offset,
360  std::unordered_map<int, size_t>& barcodes) const {
361  size_t idx = offset;
362  HepMC::GenEvent::particle_const_iterator begin = mc->particles_begin(), end = mc->particles_end();
363  for (HepMC::GenEvent::particle_const_iterator p = begin; p != end; ++p) {
364  const HepMC::GenParticle* particle = *p;
365  size_t barCode_this_event = particle->barcode();
366  size_t barCode = barCode_this_event + offset;
367  if (barcodes.find(barCode) != barcodes.end())
368  throw cms::Exception("WrongReference") << "barcodes are duplicated! " << endl;
369  particles[idx] = particle;
370  barCodeVector[idx] = barCode;
371  barcodes.insert(make_pair(barCode_this_event, idx++));
372  }
373  return true;
374 }
375 
377 
edm::RefProd< GenParticleCollection >
edm::StreamID
Definition: StreamID.h:30
GenParticleProducer::~GenParticleProducer
~GenParticleProducer() override
destructor
Definition: GenParticleProducer.cc:165
edm::Event::getRefBeforePut
RefProd< PROD > getRefBeforePut()
Definition: Event.h:157
Handle.h
dataCertificationJetMET_cfi.isHI
isHI
Definition: dataCertificationJetMET_cfi.py:65
electrons_cff.bool
bool
Definition: electrons_cff.py:372
mps_fire.i
i
Definition: mps_fire.py:355
funct::false
false
Definition: Factorize.h:34
edm::RefProd::id
ProductID id() const
Accessor for product ID.
Definition: RefProd.h:124
edm::Handle::product
T const * product() const
Definition: Handle.h:70
GenParticleProducer::doSubEvent_
bool doSubEvent_
input & output modes
Definition: GenParticleProducer.cc:115
edm::errors::InvalidReference
Definition: EDMException.h:39
ESHandle.h
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
CaloTowersParam_cfi.mc
mc
Definition: CaloTowersParam_cfi.py:8
edm::errors::LogicError
Definition: EDMException.h:37
reco::GenParticle
Definition: GenParticle.h:21
edm::Run
Definition: Run.h:45
edm::EDGetTokenT< edm::HepMCProduct >
edm::Run::index
RunIndex index() const
Definition: Run.cc:21
edm
HLT enums.
Definition: AlignableModifier.h:19
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
CrossingFrame.h
GenParticleProducer::saveBarCodes_
bool saveBarCodes_
save bar-codes
Definition: GenParticleProducer.cc:112
reco::GenParticleCollection
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
Definition: GenParticleFwd.h:13
GenParticleRef
edm::Ref< edm::HepMCProduct, HepMC::GenParticle > GenParticleRef
Definition: MultiTrackValidator.cc:43
GenParticleProducer::fillIndices
bool fillIndices(const HepMC::GenEvent *mc, std::vector< const HepMC::GenParticle * > &particles, std::vector< int > &barCodeVector, int offset, std::unordered_map< int, size_t > &barcodes) const
Definition: GenParticleProducer.cc:356
charmTagsComputerCvsB_cfi.idx
idx
Definition: charmTagsComputerCvsB_cfi.py:108
edm::second
U second(std::pair< T, U > const &p)
Definition: ParameterSet.cc:215
GenParticleProducer
Definition: GenParticleProducer.cc:79
reco
fixed size matrix
Definition: AlignmentAlgorithmBase.h:45
findQualityFiles.v
v
Definition: findQualityFiles.py:179
GenParticleProducer::convertParticle
bool convertParticle(reco::GenParticle &cand, const HepMC::GenParticle *part, const IDto3Charge &id2Charge) const
Definition: GenParticleProducer.cc:314
MCTruthHelper< HepMC::GenParticle >
edm::Handle
Definition: AssociativeIterator.h:50
GenParticle
Definition: GenParticle.py:1
ecalTrigSettings_cff.particles
particles
Definition: ecalTrigSettings_cff.py:11
end
#define end
Definition: vmac.h:39
HepMC::GenEvent
Definition: hepmc_rootio.cc:9
edm::Ref< GenParticleCollection >
GenParticleProducer::globalBeginRun
std::shared_ptr< IDto3Charge > globalBeginRun(const edm::Run &, const edm::EventSetup &) const override
Definition: GenParticleProducer.cc:167
GenParticle.h
CandidateFwd.h
EDMException.h
GenParticleProducer::globalEndRun
void globalEndRun(edm::Run const &, edm::EventSetup const &) const override
Definition: GenParticleProducer.cc:89
GenParticleProducer::mcTruthHelper_
MCTruthHelper< HepMC::GenParticle > mcTruthHelper_
Definition: GenParticleProducer.cc:118
MakerMacros.h
MixCollection::size
int size() const
Definition: MixCollection.h:20
part
part
Definition: HCALResponse.h:20
GeneratorMix_cff.abortOnUnknownPDGCode
abortOnUnknownPDGCode
Definition: GeneratorMix_cff.py:10
DEFINE_FWK_MODULE
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
MCTruthHelper::fillGenStatusFlags
void fillGenStatusFlags(const P &p, reco::GenStatusFlags &statusFlags) const
Definition: MCTruthHelper.h:643
MixCollection.h
MixCollection
Definition: MixCollection.h:11
nsub
const int nsub
Definition: CMTRawAnalyzer.h:421
visualization-live-secondInstance_cfg.m
m
Definition: visualization-live-secondInstance_cfg.py:72
GenParticleFwd.h
Run.h
edm::ESHandle< HepPDT::ParticleDataTable >
edm::Event::getByToken
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:528
MixCollection::getObject
const T & getObject(unsigned int ip) const
Definition: MixCollection.h:27
edm::global::EDProducer
Definition: EDProducer.h:32
badGlobalMuonTaggersAOD_cff.vtx
vtx
Definition: badGlobalMuonTaggersAOD_cff.py:5
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
funct::true
true
Definition: Factorize.h:173
bphysicsOniaDQM_cfi.vertex
vertex
Definition: bphysicsOniaDQM_cfi.py:7
HLT_2018_cff.InputTag
InputTag
Definition: HLT_2018_cff.py:79016
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:670
edm::ParameterSet
Definition: ParameterSet.h:36
Event.h
ParticleDataTable.h
GenParticleProducer::mixToken_
edm::EDGetTokenT< CrossingFrame< edm::HepMCProduct > > mixToken_
Definition: GenParticleProducer.cc:107
position
static int position[264][3]
Definition: ReadPGInfo.cc:289
cand
Definition: decayParser.h:34
p4
double p4[4]
Definition: TauolaWrapper.h:92
edm::Event::put
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:132
MCTruthHelper.h
EgammaValidation_cff.pdgId
pdgId
Definition: EgammaValidation_cff.py:118
edm::EventSetup
Definition: EventSetup.h:57
GenParticleProducer::produce
void produce(edm::StreamID, edm::Event &e, const edm::EventSetup &) const override
process one event
Definition: GenParticleProducer.cc:173
edm::HepMCProduct::GetEvent
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:34
GenParticleProducer::fillDaughters
bool fillDaughters(reco::GenParticleCollection &cand, const HepMC::GenParticle *part, reco::GenParticleRefProd const &ref, size_t index, std::unordered_map< int, size_t > &barcodes) const
Definition: GenParticleProducer.cc:336
InputTag.h
GenParticleProducer::GenParticleProducer
GenParticleProducer(const edm::ParameterSet &)
constructor
Definition: GenParticleProducer.cc:145
PDGCacheMax
static constexpr int PDGCacheMax
Definition: GenParticleProducer.cc:31
edm::EventSetup::getData
bool getData(T &iHolder) const
Definition: EventSetup.h:113
looper.cfg
cfg
Definition: looper.py:297
GenParticleProducer::abortOnUnknownPDGCode_
bool abortOnUnknownPDGCode_
unknown code treatment flag
Definition: GenParticleProducer.cc:110
hi
Definition: HiEvtPlaneList.h:38
GenParticle.GenParticle
GenParticle
Definition: GenParticle.py:18
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
mmToCm
static const double mmToCm
Definition: GenParticleProducer.cc:142
GenParticleProducer::useCF_
bool useCF_
Definition: GenParticleProducer.cc:116
triggerObjects_cff.id
id
Definition: triggerObjects_cff.py:31
transform.h
mmToNs
static const double mmToNs
Definition: GenParticleProducer.cc:143
HepMC
Definition: GenParticle.h:15
SiStripOfflineCRack_cfg.alias
alias
Definition: SiStripOfflineCRack_cfg.py:129
Exception
Definition: hltDiff.cc:246
GenParticleProducer::mcTruthHelperGenParts_
MCTruthHelper< reco::GenParticle > mcTruthHelperGenParts_
Definition: GenParticleProducer.cc:119
HLT_2018_cff.cands
cands
Definition: HLT_2018_cff.py:13762
EventSetup.h
AlignmentPI::index
index
Definition: AlignmentPayloadInspectorHelper.h:46
ztail.d
d
Definition: ztail.py:151
cms::Exception
Definition: Exception.h:70
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ParameterSet.h
GenParticleProducer::vectorSrcTokens_
std::vector< edm::EDGetTokenT< edm::HepMCProduct > > vectorSrcTokens_
Definition: GenParticleProducer.cc:106
HepMCProduct.h
EDProducer.h
reco::Candidate::LorentzVector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
reco::Candidate::Point
math::XYZPoint Point
point in the space
Definition: Candidate.h:40
hltrates_dqm_sourceclient-live_cfg.offset
offset
Definition: hltrates_dqm_sourceclient-live_cfg.py:82
math::XYZPointF
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
edm::Event
Definition: Event.h:73
LHEGenericFilter_cfi.ParticleID
ParticleID
Definition: LHEGenericFilter_cfi.py:6
ParticleDataTable
HepPDT::ParticleDataTable ParticleDataTable
Definition: ParticleDataTable.h:8
edm::InputTag
Definition: InputTag.h:15
begin
#define begin
Definition: vmac.h:32
edm::Event::getRun
Run const & getRun() const
Definition: Event.cc:107
findQualityFiles.size
size
Write out results.
Definition: findQualityFiles.py:443
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
GenParticleProducer::srcToken_
edm::EDGetTokenT< edm::HepMCProduct > srcToken_
source collection name
Definition: GenParticleProducer.cc:105