19#include "HepMC3/ReaderFactory.h"
20#include "HepMC3/GenEvent.h"
21#include "HepMC3/GenParticle.h"
22#include "HepMC3/GenVertex.h"
23#include "HepMC3/FourVector.h"
24#include "HepMC3/Version.h"
27#include <fairlogger/Logger.h>
28#include "FairPrimaryGenerator.h"
51 mEvent =
new HepMC3::GenEvent();
61 LOG(info) <<
"Destructing GeneratorHepMC";
68 if (not
mCmd.empty()) {
82 if (not
param.fileName.empty()) {
83 LOG(warn) <<
"The use of the key \"HepMC.fileName\" is "
84 <<
"deprecated, use \"GeneratorFileOrCmd.fileNames\" instead";
88 if (not
param.fileName.empty()) {
101 if (
param.version != 0 and
mCmd.empty()) {
102 LOG(warn) <<
"The key \"HepMC.version\" is no longer needed when "
103 <<
"reading from files. The format version of the input files "
104 <<
"are automatically deduced. However, it is mandatory when reading "
105 <<
"from a pipe containing HepMC2 data.";
114 if (not
param.fileName.empty()) {
115 LOG(warn) <<
"The use of the key \"HepMC.fileName\" is "
116 <<
"deprecated, use \"GeneratorFileOrCmd.fileNames\" instead";
120 if (not
param.fileName.empty()) {
133 if (
param.version != 0 and
mCmd.empty()) {
134 LOG(warn) <<
"The key \"HepMC.version\" is no longer needed when "
135 <<
"reading from files. The format version of the input files "
136 <<
"are automatically deduced. However, it is mandatory when reading "
137 <<
"from a pipe containing HepMC2 data.";
144 LOG(
debug) <<
"Generating an event";
147 constexpr int max_tries = 3;
159 mEvent->set_units(HepMC3::Units::GEV, HepMC3::Units::MM);
163 LOG(error) <<
"Event reading from HepMC failed ...";
166 }
while (tries < max_tries);
168 LOG(error) <<
"HepMC event gen failed (Does the file/stream have enough events)?";
177 HepMC3::GenEvent&
event = *
mEvent;
179 auto particles =
event.particles();
180 auto vertices =
event.vertices();
181 std::list<HepMC3::GenParticlePtr> toRemove;
183 LOG(
debug) <<
"HepMC events has " << particles.size()
184 <<
" particles and " << vertices.size()
185 <<
" vertices" << std::endl;
188 for (
size_t i = 0;
i < particles.size(); ++
i) {
189 auto particle = particles[
i];
196 toRemove.push_back(particle);
197 LOG(
debug) <<
" Remove " << std::setw(3) << particle->id();
199 auto endVtx = particle->end_vertex();
200 auto prdVtx = particle->production_vertex();
203 endVtx->remove_particle_in(particle);
204 LOG(
debug) <<
" end " << std::setw(3) << endVtx->id();
206 if (prdVtx and prdVtx->id() != endVtx->id()) {
207 auto outbound = endVtx->particles_out();
208 auto inbound = endVtx->particles_in();
209 LOG(
debug) <<
" prd " << std::setw(3) << prdVtx->id() <<
" "
210 << std::setw(3) << outbound.size() <<
" out "
212 << std::setw(3) << inbound.size() <<
" in ";
216 for (
auto outgoing : outbound) {
220 auto ee = outgoing->end_vertex();
221 if (not ee or ee->id() != prdVtx->id()) {
222 prdVtx->add_particle_out(outgoing);
224 LOG(
debug) <<
" " << std::setw(3) << outgoing->id();
231 for (
auto incoming : inbound) {
233 auto pp = incoming->production_vertex();
234 if (not pp or pp->id() != prdVtx->id()) {
235 prdVtx->add_particle_in(incoming);
238 LOG(
debug) <<
" " << std::setw(3) << incoming->id();
244 prdVtx->remove_particle_out(particle);
248 LOG(
debug) <<
"Selected " << nSelect <<
" particles\n"
249 <<
"Removing " << toRemove.size() <<
" particles";
250 size_t oldSize = particles.size();
251 for (
auto particle : toRemove) {
252 event.remove_particle(particle);
255 std::list<HepMC3::GenVertexPtr> remVtx;
256 for (
auto vtx :
event.vertices()) {
258 (vtx->particles_out().empty() and
259 vtx->particles_in().empty())) {
260 remVtx.push_back(vtx);
263 LOG(
debug) <<
"Removing " << remVtx.size() <<
" vertexes";
264 for (
auto vtx : remVtx) {
265 event.remove_vertex(vtx);
268 LOG(
debug) <<
"HepMC events was pruned from " << oldSize
269 <<
" particles to " <<
event.particles().size()
270 <<
" particles and " <<
event.vertices().size()
280 auto select = [](HepMC3::ConstGenParticlePtr particle) {
281 switch (particle->status()) {
296 auto particles =
mEvent->particles();
297 for (
int i = 0;
i < particles.size(); ++
i) {
300 auto particle = particles.at(
i);
301 auto momentum = particle->momentum();
302 auto vertex = particle->production_vertex()->position();
303 auto parents = particle->parents();
304 auto children = particle->children();
307 auto m1 = parents.empty() ? -1 : parents.front()->id() - 1;
308 auto m2 = parents.empty() ? -1 : parents.back()->id() - 1;
311 auto d1 = children.empty() ? -1 : children.front()->id() - 1;
312 auto d2 = children.empty() ? -1 : children.back()->id() - 1;
315 mParticles.push_back(TParticle(particle->pid(),
331 particle->status() == 1);
341template <
typename AttributeType,
typename TargetType>
343 const std::string&
name,
344 const std::shared_ptr<HepMC3::Attribute>&
a)
346 if (
auto* p =
dynamic_cast<AttributeType*
>(
a.get())) {
347 eventHeader->
putInfo<TargetType>(
name, p->value());
354 const std::string&
name,
355 const std::shared_ptr<HepMC3::Attribute>&
a)
357 using IntAttribute = HepMC3::IntAttribute;
358 using LongAttribute = HepMC3::LongAttribute;
359 using FloatAttribute = HepMC3::FloatAttribute;
360 using DoubleAttribute = HepMC3::DoubleAttribute;
361 using StringAttribute = HepMC3::StringAttribute;
362 using CharAttribute = HepMC3::CharAttribute;
363 using LongLongAttribute = HepMC3::LongLongAttribute;
364 using LongDoubleAttribute = HepMC3::LongDoubleAttribute;
365 using UIntAttribute = HepMC3::UIntAttribute;
366 using ULongAttribute = HepMC3::ULongAttribute;
367 using ULongLongAttribute = HepMC3::ULongLongAttribute;
368 using BoolAttribute = HepMC3::BoolAttribute;
370 if (putAttributeInfoImpl<IntAttribute, int>(eventHeader,
name,
a)) {
373 if (putAttributeInfoImpl<LongAttribute, int>(eventHeader,
name,
a)) {
376 if (putAttributeInfoImpl<FloatAttribute, float>(eventHeader,
name,
a)) {
379 if (putAttributeInfoImpl<DoubleAttribute, float>(eventHeader,
name,
a)) {
382 if (putAttributeInfoImpl<StringAttribute, std::string>(eventHeader,
name,
a)) {
385 if (putAttributeInfoImpl<CharAttribute, char>(eventHeader,
name,
a)) {
388 if (putAttributeInfoImpl<LongLongAttribute, int>(eventHeader,
name,
a)) {
391 if (putAttributeInfoImpl<LongDoubleAttribute, float>(eventHeader,
name,
a)) {
394 if (putAttributeInfoImpl<UIntAttribute, int>(eventHeader,
name,
a)) {
397 if (putAttributeInfoImpl<ULongAttribute, int>(eventHeader,
name,
a)) {
400 if (putAttributeInfoImpl<ULongLongAttribute, int>(eventHeader,
name,
a)) {
403 if (putAttributeInfoImpl<BoolAttribute, bool>(eventHeader,
name,
a)) {
416 eventHeader->
putInfo<std::string>(Key::generator,
"hepmc");
417 eventHeader->
putInfo<
int>(Key::generatorVersion, HEPMC3_VERSION_CODE);
419 auto xSection =
mEvent->cross_section();
420 auto pdfInfo =
mEvent->pdf_info();
421 auto hiInfo =
mEvent->heavy_ion();
425 eventHeader->
putInfo<
float>(Key::xSection, xSection->xsec());
426 eventHeader->
putInfo<
float>(Key::xSectionError, xSection->xsec_err());
427 eventHeader->
putInfo<
int>(Key::acceptedEvents,
428 xSection->get_accepted_events());
429 eventHeader->
putInfo<
int>(Key::attemptedEvents,
430 xSection->get_attempted_events());
435 for (
auto w :
mEvent->weights()) {
437 eventHeader->
putInfo<
float>(Key::weight + post,
w);
439 eventHeader->
putInfo<
float>(Key::xSection, xSection->xsec(iw));
440 eventHeader->
putInfo<
float>(Key::xSectionError, xSection->xsec_err(iw));
447 eventHeader->
putInfo<
int>(Key::pdfParton1Id, pdfInfo->parton_id[0]);
448 eventHeader->
putInfo<
int>(Key::pdfParton2Id, pdfInfo->parton_id[1]);
449 eventHeader->
putInfo<
float>(Key::pdfX1, pdfInfo->x[0]);
450 eventHeader->
putInfo<
float>(Key::pdfX2, pdfInfo->x[1]);
451 eventHeader->
putInfo<
float>(Key::pdfScale, pdfInfo->scale);
452 eventHeader->
putInfo<
float>(Key::pdfXF1, pdfInfo->xf[0]);
453 eventHeader->
putInfo<
float>(Key::pdfXF2, pdfInfo->xf[1]);
454 eventHeader->
putInfo<
int>(Key::pdfCode1, pdfInfo->pdf_id[0]);
455 eventHeader->
putInfo<
int>(Key::pdfCode2, pdfInfo->pdf_id[1]);
460 eventHeader->
putInfo<
int>(Key::impactParameter,
461 hiInfo->impact_parameter);
462 eventHeader->
putInfo<
int>(Key::nPart,
463 hiInfo->Npart_proj + hiInfo->Npart_targ);
464 eventHeader->
putInfo<
int>(Key::nPartProjectile, hiInfo->Npart_proj);
465 eventHeader->
putInfo<
int>(Key::nPartTarget, hiInfo->Npart_targ);
466 eventHeader->
putInfo<
int>(Key::nColl, hiInfo->Ncoll);
467 eventHeader->
putInfo<
int>(Key::nCollHard, hiInfo->Ncoll_hard);
468 eventHeader->
putInfo<
int>(Key::nCollNNWounded,
469 hiInfo->N_Nwounded_collisions);
470 eventHeader->
putInfo<
int>(Key::nCollNWoundedN,
471 hiInfo->Nwounded_N_collisions);
472 eventHeader->
putInfo<
int>(Key::nCollNWoundedNwounded,
473 hiInfo->Nwounded_Nwounded_collisions);
474 eventHeader->
putInfo<
int>(Key::planeAngle,
475 hiInfo->event_plane_angle);
476 eventHeader->
putInfo<
int>(Key::sigmaInelNN,
477 hiInfo->sigma_inel_NN);
478 eventHeader->
putInfo<
int>(Key::centrality, hiInfo->centrality);
479 eventHeader->
putInfo<
int>(Key::nSpecProjectileProton, hiInfo->Nspec_proj_p);
480 eventHeader->
putInfo<
int>(Key::nSpecProjectileNeutron, hiInfo->Nspec_proj_n);
481 eventHeader->
putInfo<
int>(Key::nSpecTargetProton, hiInfo->Nspec_targ_p);
482 eventHeader->
putInfo<
int>(Key::nSpecTargetNeutron, hiInfo->Nspec_targ_n);
485 for (
auto na :
mEvent->attributes()) {
486 std::string
name = na.first;
487 if (
name ==
"GenPdfInfo" ||
488 name ==
"GenCrossSection" ||
489 name ==
"GenHeavyIon") {
493 for (
auto ia : na.second) {
498 putAttributeInfo(eventHeader,
name + post, at);
508 LOG(
debug) <<
"Reseting the reader";
513 LOG(
debug) <<
"No more files to read, return false";
524 if (not
mCmd.empty()) {
530 LOG(info) <<
"Creating ASCII reader of " <<
filename;
542 LOG(info) <<
"Reader is " <<
mReader.get() <<
" " << ret;
583 if (not
mCmd.empty()) {
603 LOG(
debug) <<
"EG command line is \"" << cmd <<
"\"";
607 LOG(fatal) <<
"Failed to spawn \"" << cmd <<
"\"";
o2::monitoring::tags::Key Key
Utility functions for MC particles.
void updateHeader(o2::dataformats::MCEventHeader *eventHeader) override
void setEventsToSkip(uint64_t val)
Bool_t importParticles() override
~GeneratorHepMC() override
void pruneEvent(Select select)
Bool_t generateEvent() override
HepMC3::GenEvent * mEvent
std::shared_ptr< HepMC3::Reader > mReader
void setup(const GeneratorFileOrCmdParam ¶m0, const GeneratorHepMCParam ¶m, const conf::SimConfig &config)
std::string mInterfaceName
std::vector< TParticle > mParticles
static void encodeParticleStatusAndTracking(TParticle &particle, bool wanttracking=true)
GLuint const GLchar * name
GLboolean GLboolean GLboolean GLboolean a
GLubyte GLubyte GLubyte GLubyte w
std::vector< InputSpec > select(char const *matcher="")
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
virtual bool ensureFiles()
virtual bool terminateCmd()
void setFileNames(const std::string &filenames)
void setup(const GeneratorFileOrCmdParam ¶m, const conf::SimConfig &config)
std::list< std::string > mFileNames
virtual std::string makeCmdLine() const
virtual bool removeTemp() const
virtual bool executeCmdLine(const std::string &cmd)
virtual bool makeTemp(const bool &)
virtual bool makeFifo() const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"