|
| 1 | +/// |
| 2 | +/// \file generator_pythia8_longlived_multiple.C |
| 3 | +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch |
| 4 | +/// \brief Implementation of a gun generator for multiple particles, built on generator_pythia8_longlived.C |
| 5 | +/// usage: |
| 6 | +/// o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_longlived_multiple.C;GeneratorExternal.funcName=generateLongLivedMultiple({1010010030}, {10}, {0.5}, {10})' |
| 7 | +/// or: |
| 8 | +/// o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_longlived_multiple.C;GeneratorExternal.funcName=generateLongLivedMultiple({{1010010030, 10, 0.5, 10}})' |
| 9 | +/// |
| 10 | + |
| 11 | +#include "generator_pythia8_longlived.C" |
| 12 | +#include "TSystem.h" |
| 13 | +#include <fstream> |
| 14 | + |
| 15 | +using namespace Pythia8; |
| 16 | + |
| 17 | +class GeneratorPythia8LongLivedGunMultiple : public GeneratorPythia8LongLivedGun |
| 18 | +{ |
| 19 | + public: |
| 20 | + /// constructor |
| 21 | + GeneratorPythia8LongLivedGunMultiple() : GeneratorPythia8LongLivedGun{0} |
| 22 | + { |
| 23 | + } |
| 24 | + |
| 25 | + /// Destructor |
| 26 | + ~GeneratorPythia8LongLivedGunMultiple() = default; |
| 27 | + |
| 28 | + //__________________________________________________________________ |
| 29 | + Bool_t importParticles() override |
| 30 | + { |
| 31 | + GeneratorPythia8::importParticles(); |
| 32 | + for (const ConfigContainer& cfg : gunConfigs) { |
| 33 | + for (int i{0}; i < cfg.nInject; ++i) { |
| 34 | + const double pt = gRandom->Uniform(cfg.ptMin, cfg.ptMax); |
| 35 | + const double eta = gRandom->Uniform(cfg.etaMin, cfg.etaMax); |
| 36 | + const double phi = gRandom->Uniform(0, TMath::TwoPi()); |
| 37 | + const double px{pt * std::cos(phi)}; |
| 38 | + const double py{pt * std::sin(phi)}; |
| 39 | + const double pz{pt * std::sinh(eta)}; |
| 40 | + const double et{std::hypot(std::hypot(pt, pz), cfg.mass)}; |
| 41 | + mParticles.push_back(TParticle(cfg.pdg, 1, -1, -1, -1, -1, px, py, pz, et, 0., 0., 0., 0.)); |
| 42 | + } |
| 43 | + } |
| 44 | + return true; |
| 45 | + } |
| 46 | + |
| 47 | + struct ConfigContainer { |
| 48 | + ConfigContainer(int input_pdg = 0, int n = 1, float p = 1, float P = 10) : pdg{input_pdg}, |
| 49 | + nInject{n}, |
| 50 | + ptMin{p}, |
| 51 | + ptMax{P} |
| 52 | + { |
| 53 | + mass = GeneratorPythia8LongLivedGun::getMass(pdg); |
| 54 | + }; |
| 55 | + ConfigContainer(TObjArray* arr) : ConfigContainer(atoi(arr->At(0)->GetName()), |
| 56 | + atoi(arr->At(1)->GetName()), |
| 57 | + atof(arr->At(2)->GetName()), |
| 58 | + atof(arr->At(3)->GetName())){}; |
| 59 | + |
| 60 | + int pdg = 0; |
| 61 | + int nInject = 1; |
| 62 | + float ptMin = 1; |
| 63 | + float ptMax = 10; |
| 64 | + float etaMin = -1.f; |
| 65 | + float etaMax = 1.f; |
| 66 | + double mass = 0.f; |
| 67 | + void print() const |
| 68 | + { |
| 69 | + Printf("int pdg = %i", pdg); |
| 70 | + Printf("int nInject = %i", nInject); |
| 71 | + Printf("float ptMin = %f", ptMin); |
| 72 | + Printf("float ptMax = %f", ptMax); |
| 73 | + Printf("float etaMin = %f", etaMin); |
| 74 | + Printf("float etaMax = %f", etaMax); |
| 75 | + Printf("double mass = %f", mass); |
| 76 | + } |
| 77 | + }; |
| 78 | + |
| 79 | + //__________________________________________________________________ |
| 80 | + ConfigContainer addGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10) |
| 81 | + { |
| 82 | + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax}; |
| 83 | + gunConfigs.push_back(cfg); |
| 84 | + return cfg; |
| 85 | + } |
| 86 | + |
| 87 | + //__________________________________________________________________ |
| 88 | + ConfigContainer addGun(ConfigContainer cfg) { return addGun(cfg.pdg, cfg.nInject, cfg.ptMin, cfg.ptMax); } |
| 89 | + |
| 90 | + private: |
| 91 | + std::vector<ConfigContainer> gunConfigs; // List of gun configurations to use |
| 92 | +}; |
| 93 | + |
| 94 | +///___________________________________________________________ |
| 95 | +/// Create generator via arrays of entries |
| 96 | +FairGenerator* generateLongLivedMultiple(std::vector<int> PDGs, std::vector<int> nInject, std::vector<float> ptMin, std::vector<float> ptMax) |
| 97 | +{ |
| 98 | + const std::vector<unsigned long> entries = {PDGs.size(), nInject.size(), ptMin.size(), ptMax.size()}; |
| 99 | + if (!std::equal(entries.begin() + 1, entries.end(), entries.begin())) { |
| 100 | + Printf("Not equal number of entries, check configuration"); |
| 101 | + return nullptr; |
| 102 | + } |
| 103 | + GeneratorPythia8LongLivedGunMultiple* multiGun = new GeneratorPythia8LongLivedGunMultiple(); |
| 104 | + for (unsigned long i = 0; i < entries[0]; i++) { |
| 105 | + multiGun->addGun(PDGs[i], nInject[i], ptMin[i], ptMax[i]); |
| 106 | + } |
| 107 | + return multiGun; |
| 108 | +} |
| 109 | + |
| 110 | +///___________________________________________________________ |
| 111 | +/// Create generator via an array of configurations |
| 112 | +FairGenerator* generateLongLivedMultiple(std::vector<GeneratorPythia8LongLivedGunMultiple::ConfigContainer> cfg) |
| 113 | +{ |
| 114 | + if (cfg.size() == 1) { |
| 115 | + return new GeneratorPythia8LongLivedGun(cfg[0].pdg, cfg[0].nInject, cfg[0].ptMin, cfg[0].ptMax); |
| 116 | + } |
| 117 | + GeneratorPythia8LongLivedGunMultiple* multiGun = new GeneratorPythia8LongLivedGunMultiple(); |
| 118 | + for (const auto& c : cfg) { |
| 119 | + Printf("Adding gun"); |
| 120 | + c.print(); |
| 121 | + multiGun->addGun(c); |
| 122 | + } |
| 123 | + return multiGun; |
| 124 | +} |
| 125 | + |
| 126 | +///___________________________________________________________ |
| 127 | +/// Create generator via input file |
| 128 | +FairGenerator* generateLongLivedMultiple(std::string configuration = "${O2DPG_ROOT}/MC/config/PWGLF/pythia8/generator/particlelist.gun") |
| 129 | +{ |
| 130 | + configuration = gSystem->ExpandPathName(configuration.c_str()); |
| 131 | + Printf("Using configuration file '%s'", configuration.c_str()); |
| 132 | + std::ifstream inputFile(configuration.c_str(), ios::in); |
| 133 | + std::vector<GeneratorPythia8LongLivedGunMultiple::ConfigContainer> cfgVec; |
| 134 | + if (inputFile.is_open()) { |
| 135 | + std::string l; |
| 136 | + int n = 0; |
| 137 | + while (getline(inputFile, l)) { |
| 138 | + TString line = l; |
| 139 | + line.Strip(TString::kBoth, ' '); |
| 140 | + |
| 141 | + std::cout << n++ << " " << line << endl; |
| 142 | + if (line.BeginsWith("#")) { |
| 143 | + std::cout << "Skipping\n"; |
| 144 | + continue; |
| 145 | + } |
| 146 | + |
| 147 | + GeneratorPythia8LongLivedGunMultiple::ConfigContainer cfg(line.Tokenize(" ")); |
| 148 | + cfgVec.push_back(cfg); |
| 149 | + } |
| 150 | + } else { |
| 151 | + Printf("ERROR: can't open '%s'", configuration.c_str()); |
| 152 | + return nullptr; |
| 153 | + } |
| 154 | + return generateLongLivedMultiple(cfgVec); |
| 155 | +} |
| 156 | + |
| 157 | +///___________________________________________________________ |
| 158 | +void generator_pythia8_longlived_multiple() |
| 159 | +{ |
| 160 | + Printf("Compiled correctly!"); |
| 161 | +} |
0 commit comments