Project
Loading...
Searching...
No Matches
GeneratorHepMC.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
18#include "SimConfig/SimConfig.h"
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"
25#include "TParticle.h"
26
27#include <fairlogger/Logger.h>
28#include "FairPrimaryGenerator.h"
29#include <cmath>
30#include <sstream>
31
32namespace o2
33{
34namespace eventgen
35{
36
37/*****************************************************************/
38/*****************************************************************/
39
41 : GeneratorHepMC("ALICEo2", "ALICEo2 HepMC Generator")
42{
43}
44
45/*****************************************************************/
46
47GeneratorHepMC::GeneratorHepMC(const Char_t* name, const Char_t* title)
48 : Generator(name, title)
49{
52 mEvent = new HepMC3::GenEvent();
53 mInterface = reinterpret_cast<void*>(mEvent);
54 mInterfaceName = "hepmc";
55}
56
57/*****************************************************************/
58
60{
62 LOG(info) << "Destructing GeneratorHepMC";
63 if (mReader) {
64 mReader->close();
65 }
66 if (mEvent) {
67 delete mEvent;
68 }
69 stop();
70 removeTemp();
71}
72
73/*****************************************************************/
74
76{
77 if (mCmd.empty()) {
78 return;
79 }
80 // Close our end of the pipe first: a generator still blocked writing to it
81 // then sees EPIPE and exits promptly, instead of sitting out the whole grace
82 // period and being killed - which would lose its CPU time (see terminateCmd).
83 if (mReader) {
84 mReader->close();
85 }
86 // Must be executed before removing the temporary file
87 // otherwise the current child process might still be writing on it
88 // causing unwanted stdout messages which could slow down the system
90}
91
92/*****************************************************************/
95 const conf::SimConfig& config)
96{
97 if (not param.fileName.empty()) {
98 LOG(warn) << "The use of the key \"HepMC.fileName\" is "
99 << "deprecated, use \"GeneratorFileOrCmd.fileNames\" instead";
100 }
101
102 GeneratorFileOrCmd::setup(param0, config);
103 if (not param.fileName.empty()) {
104 setFileNames(param.fileName);
105 }
106
107 mVersion = param.version;
108 mPrune = param.prune;
109 setEventsToSkip(param.eventsToSkip);
110
111 // we are skipping ahead in the HepMC stream now
112 for (int i = 0; i < mEventsToSkip; ++i) {
114 }
115
116 if (param.version != 0 and mCmd.empty()) {
117 LOG(warn) << "The key \"HepMC.version\" is no longer needed when "
118 << "reading from files. The format version of the input files "
119 << "are automatically deduced. However, it is mandatory when reading "
120 << "from a pipe containing HepMC2 data.";
121 }
122}
123
124/*****************************************************************/
126 const HepMCGenConfig& param,
127 const conf::SimConfig& config)
128{
129 if (not param.fileName.empty()) {
130 LOG(warn) << "The use of the key \"HepMC.fileName\" is "
131 << "deprecated, use \"GeneratorFileOrCmd.fileNames\" instead";
132 }
133
134 GeneratorFileOrCmd::setup(param0, config);
135 if (not param.fileName.empty()) {
136 setFileNames(param.fileName);
137 }
138
139 mVersion = param.version;
140 mPrune = param.prune;
141 setEventsToSkip(param.eventsToSkip);
142
143 // we are skipping ahead in the HepMC stream now
144 for (int i = 0; i < mEventsToSkip; ++i) {
146 }
147
148 if (param.version != 0 and mCmd.empty()) {
149 LOG(warn) << "The key \"HepMC.version\" is no longer needed when "
150 << "reading from files. The format version of the input files "
151 << "are automatically deduced. However, it is mandatory when reading "
152 << "from a pipe containing HepMC2 data.";
153 }
154}
155
156/*****************************************************************/
158{
159 LOG(debug) << "Generating an event";
161 int tries = 0;
162 constexpr int max_tries = 3;
163 do {
164 LOG(debug) << " try # " << tries;
165 if (not mReader and not makeReader()) {
166 return false;
167 }
168
170 mEvent->clear();
171 mReader->read_event(*mEvent);
172 if (not mReader->failed()) {
174 mEvent->set_units(HepMC3::Units::GEV, HepMC3::Units::MM);
175 LOG(debug) << "Read one event " << mEvent->event_number();
176 return true;
177 } else {
178 LOG(error) << "Event reading from HepMC failed ...";
179 }
180 tries++;
181 } while (tries < max_tries);
182
183 LOG(error) << "HepMC event gen failed (Does the file/stream have enough events)?";
184
186 return false;
187}
188
189/*****************************************************************/
191{
192 HepMC3::GenEvent& event = *mEvent;
193
194 auto particles = event.particles();
195 auto vertices = event.vertices();
196 std::list<HepMC3::GenParticlePtr> toRemove;
197
198 LOG(debug) << "HepMC events has " << particles.size()
199 << " particles and " << vertices.size()
200 << " vertices" << std::endl;
201
202 size_t nSelect = 0;
203 for (size_t i = 0; i < particles.size(); ++i) {
204 auto particle = particles[i];
205 if (select(particle)) {
206 nSelect++;
207 continue;
208 }
209
210 // Remove particle from the event
211 toRemove.push_back(particle);
212 LOG(debug) << " Remove " << std::setw(3) << particle->id();
213
214 auto endVtx = particle->end_vertex();
215 auto prdVtx = particle->production_vertex();
216 if (endVtx) {
217 // Disconnect this particle from its out going vertex
218 endVtx->remove_particle_in(particle);
219 LOG(debug) << " end " << std::setw(3) << endVtx->id();
220
221 if (prdVtx and prdVtx->id() != endVtx->id()) {
222 auto outbound = endVtx->particles_out();
223 auto inbound = endVtx->particles_in();
224 LOG(debug) << " prd " << std::setw(3) << prdVtx->id() << " "
225 << std::setw(3) << outbound.size() << " out "
226 << " "
227 << std::setw(3) << inbound.size() << " in ";
228
229 // Other out-bound particles of the end vertex are attached as
230 // out-going to the production vertex of this particle.
231 for (auto outgoing : outbound) {
232 // This should also detach the particle from its old
233 // end-vertex.
234 if (outgoing) {
235 auto ee = outgoing->end_vertex();
236 if (not ee or ee->id() != prdVtx->id()) {
237 prdVtx->add_particle_out(outgoing);
238 }
239 LOG(debug) << " " << std::setw(3) << outgoing->id();
240 }
241 }
242
243 // Other incoming particles to the end vertex of this
244 // particles are attached incoming particles to the production
245 // vertex of this particle.
246 for (auto incoming : inbound) {
247 if (incoming) {
248 auto pp = incoming->production_vertex();
249 if (not pp or pp->id() != prdVtx->id()) {
250 prdVtx->add_particle_in(incoming);
251 }
252
253 LOG(debug) << " " << std::setw(3) << incoming->id();
254 }
255 }
256 }
257 }
258 if (prdVtx) {
259 prdVtx->remove_particle_out(particle);
260 }
261 }
262
263 LOG(debug) << "Selected " << nSelect << " particles\n"
264 << "Removing " << toRemove.size() << " particles";
265 size_t oldSize = particles.size();
266 for (auto particle : toRemove) {
267 event.remove_particle(particle);
268 }
269
270 std::list<HepMC3::GenVertexPtr> remVtx;
271 for (auto vtx : event.vertices()) {
272 if (not vtx or
273 (vtx->particles_out().empty() and
274 vtx->particles_in().empty())) {
275 remVtx.push_back(vtx);
276 }
277 }
278 LOG(debug) << "Removing " << remVtx.size() << " vertexes";
279 for (auto vtx : remVtx) {
280 event.remove_vertex(vtx);
281 }
282
283 LOG(debug) << "HepMC events was pruned from " << oldSize
284 << " particles to " << event.particles().size()
285 << " particles and " << event.vertices().size()
286 << " vertices";
287}
288
289/*****************************************************************/
290
292{
294 if (mPrune) {
295 auto select = [](HepMC3::ConstGenParticlePtr particle) {
296 switch (particle->status()) {
297 case 1: // Final st
298 case 2: // Decayed
299 case 4: // Beam
300 return true;
301 }
302 // To also keep diffractive particles
303 // if (particle->pid() == 9902210) return true;
304 return false;
305 };
307 }
308
310 mParticles.clear();
311 auto particles = mEvent->particles();
312 for (int i = 0; i < particles.size(); ++i) {
313
315 auto particle = particles.at(i);
316 auto momentum = particle->momentum();
317 auto vertex = particle->production_vertex()->position();
318 auto parents = particle->parents();
319 auto children = particle->children();
320
322 auto m1 = parents.empty() ? -1 : parents.front()->id() - 1;
323 auto m2 = parents.empty() ? -1 : parents.back()->id() - 1;
324
326 auto d1 = children.empty() ? -1 : children.front()->id() - 1;
327 auto d2 = children.empty() ? -1 : children.back()->id() - 1;
328
330 mParticles.push_back(TParticle(particle->pid(), // Particle type
331 particle->status(), // Status code
332 m1, // First mother
333 m2, // Second mother
334 d1, // First daughter
335 d2, // Last daughter
336 momentum.x(), // X-momentum
337 momentum.y(), // Y-momentum
338 momentum.z(), // Z-momentum
339 momentum.t(), // Energy
340 vertex.x(), // Production X
341 vertex.y(), // Production Y
342 vertex.z(), // Production Z
343 vertex.t())); // Production time
345 mParticles.back(), // Add to back
346 particle->status() == 1); // only final state are to be propagated
347
348 }
351 return kTRUE;
352}
353
354namespace
355{
356template <typename AttributeType, typename TargetType>
357bool putAttributeInfoImpl(o2::dataformats::MCEventHeader* eventHeader,
358 const std::string& name,
359 const std::shared_ptr<HepMC3::Attribute>& a)
360{
361 if (auto* p = dynamic_cast<AttributeType*>(a.get())) {
362 eventHeader->putInfo<TargetType>(name, p->value());
363 return true;
364 }
365 return false;
366}
367
368void putAttributeInfo(o2::dataformats::MCEventHeader* eventHeader,
369 const std::string& name,
370 const std::shared_ptr<HepMC3::Attribute>& a)
371{
372 using IntAttribute = HepMC3::IntAttribute;
373 using LongAttribute = HepMC3::LongAttribute;
374 using FloatAttribute = HepMC3::FloatAttribute;
375 using DoubleAttribute = HepMC3::DoubleAttribute;
376 using StringAttribute = HepMC3::StringAttribute;
377 using CharAttribute = HepMC3::CharAttribute;
378 using LongLongAttribute = HepMC3::LongLongAttribute;
379 using LongDoubleAttribute = HepMC3::LongDoubleAttribute;
380 using UIntAttribute = HepMC3::UIntAttribute;
381 using ULongAttribute = HepMC3::ULongAttribute;
382 using ULongLongAttribute = HepMC3::ULongLongAttribute;
383 using BoolAttribute = HepMC3::BoolAttribute;
384
385 if (putAttributeInfoImpl<IntAttribute, int>(eventHeader, name, a)) {
386 return;
387 }
388 if (putAttributeInfoImpl<LongAttribute, int>(eventHeader, name, a)) {
389 return;
390 }
391 if (putAttributeInfoImpl<FloatAttribute, float>(eventHeader, name, a)) {
392 return;
393 }
394 if (putAttributeInfoImpl<DoubleAttribute, float>(eventHeader, name, a)) {
395 return;
396 }
397 if (putAttributeInfoImpl<StringAttribute, std::string>(eventHeader, name, a)) {
398 return;
399 }
400 if (putAttributeInfoImpl<CharAttribute, char>(eventHeader, name, a)) {
401 return;
402 }
403 if (putAttributeInfoImpl<LongLongAttribute, int>(eventHeader, name, a)) {
404 return;
405 }
406 if (putAttributeInfoImpl<LongDoubleAttribute, float>(eventHeader, name, a)) {
407 return;
408 }
409 if (putAttributeInfoImpl<UIntAttribute, int>(eventHeader, name, a)) {
410 return;
411 }
412 if (putAttributeInfoImpl<ULongAttribute, int>(eventHeader, name, a)) {
413 return;
414 }
415 if (putAttributeInfoImpl<ULongLongAttribute, int>(eventHeader, name, a)) {
416 return;
417 }
418 if (putAttributeInfoImpl<BoolAttribute, bool>(eventHeader, name, a)) {
419 return;
420 }
421}
422} // namespace
423
424/*****************************************************************/
425
427{
430
431 eventHeader->putInfo<std::string>(Key::generator, "hepmc");
432 eventHeader->putInfo<int>(Key::generatorVersion, HEPMC3_VERSION_CODE);
433
434 auto xSection = mEvent->cross_section();
435 auto pdfInfo = mEvent->pdf_info();
436 auto hiInfo = mEvent->heavy_ion();
437
438 // Workaround for a bug in HepMC3 (3.3.1 on 23/02/2026): GenHeavyIon::from_string() for the "v0"
439 // format skips reading user_cent_estimate, but to_string() always writes it.
440 // This shifts all subsequent fields by one, causing a istringstream failure and and heavy_ion()
441 // to return null even when the attribute is present and well-formed.
442 // For now we use this manual parser in case the infos are available
443 if (!hiInfo) {
444 auto attStr = mEvent->attribute_as_string("GenHeavyIon");
445 if (!attStr.empty() && attStr[0] == 'v') {
446 std::istringstream is(attStr);
447 std::string version;
448 is >> version;
449 if (version == "v0") {
450 auto hi = std::make_shared<HepMC3::GenHeavyIon>();
451 double spectNeutrons, spectProtons, eccentricity, userCentEst;
452 is >> hi->Ncoll_hard >> hi->Npart_proj >> hi->Npart_targ >> hi->Ncoll >> spectNeutrons >> spectProtons // deprecated v0 fields
453 >> hi->N_Nwounded_collisions >> hi->Nwounded_N_collisions >> hi->Nwounded_Nwounded_collisions >> hi->impact_parameter >> hi->event_plane_angle >> eccentricity // deprecated v0 field
454 >> hi->sigma_inel_NN >> hi->centrality >> userCentEst // GenHeavyIon::to_string always writes this, but GenHeavyIon::from_string skips it for v0 (HepMC3 bug to fix)
455 >> hi->Nspec_proj_n >> hi->Nspec_targ_n >> hi->Nspec_proj_p >> hi->Nspec_targ_p;
456 if (!is.fail()) {
457 LOG(debug) << "GenHeavyIon: using manual v0 parser (workaround for HepMC3 from_string bug)";
458 hiInfo = hi;
459 } else {
460 LOG(warn) << "GenHeavyIon: manual v0 parser also failed on: [" << attStr << "]";
461 }
462 }
463 }
464 }
465
466 // Set default cross-section
467 if (xSection) {
468 eventHeader->putInfo<float>(Key::xSection, xSection->xsec());
469 eventHeader->putInfo<float>(Key::xSectionError, xSection->xsec_err());
470 eventHeader->putInfo<int>(Key::acceptedEvents,
471 xSection->get_accepted_events());
472 eventHeader->putInfo<int>(Key::attemptedEvents,
473 xSection->get_attempted_events());
474 }
475
476 // Set weights and cross sections
477 size_t iw = 0;
478 for (auto w : mEvent->weights()) {
479 std::string post = (iw > 0 ? "_" + std::to_string(iw) : "");
480 eventHeader->putInfo<float>(Key::weight + post, w);
481 if (xSection) {
482 eventHeader->putInfo<float>(Key::xSection, xSection->xsec(iw));
483 eventHeader->putInfo<float>(Key::xSectionError, xSection->xsec_err(iw));
484 }
485 iw++;
486 }
487
488 // Set the PDF information
489 if (pdfInfo) {
490 eventHeader->putInfo<int>(Key::pdfParton1Id, pdfInfo->parton_id[0]);
491 eventHeader->putInfo<int>(Key::pdfParton2Id, pdfInfo->parton_id[1]);
492 eventHeader->putInfo<float>(Key::pdfX1, pdfInfo->x[0]);
493 eventHeader->putInfo<float>(Key::pdfX2, pdfInfo->x[1]);
494 eventHeader->putInfo<float>(Key::pdfScale, pdfInfo->scale);
495 eventHeader->putInfo<float>(Key::pdfXF1, pdfInfo->xf[0]);
496 eventHeader->putInfo<float>(Key::pdfXF2, pdfInfo->xf[1]);
497 eventHeader->putInfo<int>(Key::pdfCode1, pdfInfo->pdf_id[0]);
498 eventHeader->putInfo<int>(Key::pdfCode2, pdfInfo->pdf_id[1]);
499 }
500
501 // Set heavy-ion information
502 if (hiInfo) {
503 eventHeader->SetB(hiInfo->impact_parameter); // sets the impact parameter to the FairMCEventHeader field for quick access in the AO2D
504 eventHeader->putInfo<float>(Key::impactParameter,
505 hiInfo->impact_parameter);
506 eventHeader->putInfo<int>(Key::nPart,
507 hiInfo->Npart_proj + hiInfo->Npart_targ);
508 eventHeader->putInfo<int>(Key::nPartProjectile, hiInfo->Npart_proj);
509 eventHeader->putInfo<int>(Key::nPartTarget, hiInfo->Npart_targ);
510 eventHeader->putInfo<int>(Key::nColl, hiInfo->Ncoll);
511 eventHeader->putInfo<int>(Key::nCollHard, hiInfo->Ncoll_hard);
512 eventHeader->putInfo<int>(Key::nCollNNWounded,
513 hiInfo->N_Nwounded_collisions);
514 eventHeader->putInfo<int>(Key::nCollNWoundedN,
515 hiInfo->Nwounded_N_collisions);
516 eventHeader->putInfo<int>(Key::nCollNWoundedNwounded,
517 hiInfo->Nwounded_Nwounded_collisions);
518 eventHeader->putInfo<double>(Key::planeAngle, hiInfo->event_plane_angle);
519 eventHeader->putInfo<float>(Key::sigmaInelNN, hiInfo->sigma_inel_NN);
520 eventHeader->putInfo<float>(Key::centrality, hiInfo->centrality);
521 eventHeader->putInfo<int>(Key::nSpecProjectileProton, hiInfo->Nspec_proj_p);
522 eventHeader->putInfo<int>(Key::nSpecProjectileNeutron, hiInfo->Nspec_proj_n);
523 eventHeader->putInfo<int>(Key::nSpecTargetProton, hiInfo->Nspec_targ_p);
524 eventHeader->putInfo<int>(Key::nSpecTargetNeutron, hiInfo->Nspec_targ_n);
525 }
526
527 for (auto na : mEvent->attributes()) {
528 std::string name = na.first;
529 if (name == "GenPdfInfo" ||
530 name == "GenCrossSection" ||
531 name == "GenHeavyIon") {
532 continue;
533 }
534
535 for (auto ia : na.second) {
536 int no = ia.first;
537 auto at = ia.second;
538 std::string post = (no == 0 ? "" : std::to_string(no));
539
540 putAttributeInfo(eventHeader, name + post, at);
541 }
542 }
543}
544
545/*****************************************************************/
546
548{
549 // Reset the reader smart pointer
550 LOG(debug) << "Reseting the reader";
551 mReader.reset();
552
553 // Check that we have any file names left
554 if (mFileNames.size() < 1) {
555 LOG(debug) << "No more files to read, return false";
556 return false;
557 }
558
559 // If we have file names left, pop the top of the list (LIFO)
560 auto filename = mFileNames.front();
561 mFileNames.pop_front();
562
563 LOG(debug) << "Next file to read: \"" << filename << "\" "
564 << mFileNames.size() << " left";
565
566 if (not mCmd.empty()) {
567 // For FIFO reading, we assume straight ASCII output always.
568 // Unfortunately, the HepMC3::deduce_reader `stat`s the filename
569 // which isn't supported on a FIFO, so we have to use the reader
570 // directly. Here, we allow for version 2 formats if the user
571 // specifies that
572 LOG(info) << "Creating ASCII reader of " << filename;
573 if (mVersion == 2) {
574 mReader = std::make_shared<HepMC3::ReaderAsciiHepMC2>(filename);
575 } else {
576 mReader = std::make_shared<HepMC3::ReaderAscii>(filename);
577 }
578 } else {
579 LOG(info) << "Deduce a reader of " << filename;
580 mReader = HepMC3::deduce_reader(filename);
581 }
582
583 bool ret = bool(mReader) and not mReader->failed();
584 LOG(info) << "Reader is " << mReader.get() << " " << ret;
585 return ret;
586}
587
588/*****************************************************************/
589
591{
596
597 // If a EG command line is given, then we make a fifo on a temporary
598 // file, and directs the EG to write to that fifo. We will then set
599 // up the HepMC3 reader to read from that fifo.
600 //
601 // o2-sim -g hepmc --configKeyValues "HepMC.progCmd=<cmd>" ...
602 //
603 // where <cmd> is the command line to run an event generator. The
604 // event generator should output HepMC event records to standard
605 // output. Nothing else, but the HepMC event record may be output
606 // to standard output. If the EG has other output to standard
607 // output, then a filter can be set-up. For example
608 //
609 // crmc -n 3 -o hepmc3 -c /optsw/inst/etc/crmc.param -f /dev/stdout \
610 // | sed -n 's/^\‍(HepMC::\|[EAUWVP] \‍)/\1/p'
611 //
612 // What's more, the event generator program _must_ accept the
613 // following command line argument
614 //
615 // `-n NEVENTS` to set the number of events to produce.
616 //
617 // Optionally, the command line should also accept
618 //
619 // `-s SEED` to set the random number seed
620 // `-b FM` to set the maximum impact parameter to sample
621 // `-o OUTPUT` to set the output file name
622 //
623 // All of this can conviniently be achieved via a wrapper script
624 // around the actual EG program.
625 if (not mCmd.empty()) {
626 if (mFileNames.empty()) {
627 // Set filename to be a temporary name
628 if (not makeTemp(false)) {
629 return false;
630 }
631 } else {
632 // Use the first filename as output for cmd line
633 if (not makeTemp(true)) {
634 return false;
635 }
636 }
637
638 // Make a fifo
639 if (not makeFifo()) {
640 return false;
641 }
642
643 // Build command line, rediret stdout to our fifo and put
644 std::string cmd = makeCmdLine();
645 LOG(debug) << "EG command line is \"" << cmd << "\"";
646
647 // Execute the command line
648 if (not executeCmdLine(cmd)) {
649 LOG(fatal) << "Failed to spawn \"" << cmd << "\"";
650 return false;
651 }
652 } else {
653 // If no command line was given, ensure that all files are present
654 // on the system. Note, in principle, HepMC3 can read from remote
655 // files
656 //
657 // root:// XRootD served
658 // http[s]:// Web served
659 // gsidcap:// DCap served
660 //
661 // These will all be handled in HepMC3 via ROOT's TFile protocol
662 // and the files are assumed to contain a TTree named
663 // `hepmc3_tree` and that tree has the branches
664 //
665 // `hepmc3_event` with object of type `HepMC3::GenEventData`
666 // `GenRunInfo` with object of type `HepMC3::GenRunInfoData`
667 //
668 // where the last branch is optional.
669 //
670 // However, here we will assume system local files. If _any_ of
671 // the listed files do not exist, then we fail.
672 if (not ensureFiles()) {
673 return false;
674 }
675 }
676
677 // Create reader for current (first) file
678 return true;
679}
680
681/*****************************************************************/
682/*****************************************************************/
683
684} /* namespace eventgen */
685} /* namespace o2 */
o2::monitoring::tags::Key Key
std::ostringstream debug
uint64_t vertex
Definition RawEventData.h:9
int32_t i
Utility functions for MC particles.
uint32_t version
Definition RawData.h:8
void putInfo(std::string const &key, T const &value)
void updateHeader(o2::dataformats::MCEventHeader *eventHeader) override
void setEventsToSkip(uint64_t val)
std::shared_ptr< HepMC3::Reader > mReader
void setup(const GeneratorFileOrCmdParam &param0, const GeneratorHepMCParam &param, const conf::SimConfig &config)
std::string mInterfaceName
Definition Generator.h:131
std::vector< TParticle > mParticles
Definition Generator.h:151
Bool_t Init() override
static void encodeParticleStatusAndTracking(TParticle &particle, bool wanttracking=true)
Definition MCUtils.cxx:211
GLuint const GLchar * name
Definition glcorearb.h:781
GLenum GLfloat param
Definition glcorearb.h:271
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
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)
Definition common.h:52
std::string filename()
void setFileNames(const std::string &filenames)
void setup(const GeneratorFileOrCmdParam &param, const conf::SimConfig &config)
std::list< std::string > mFileNames
static constexpr unsigned int sStopGraceMillis
virtual bool terminateCmd(unsigned int graceMillis=0)
virtual std::string makeCmdLine() const
virtual bool executeCmdLine(const std::string &cmd)
virtual bool makeTemp(const bool &)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"