diff --git a/MC/config/PWGLF/ini/GeneratorLFDeTrHe_pp.ini b/MC/config/PWGLF/ini/GeneratorLFDeTrHe_pp.ini new file mode 100644 index 000000000..15451bd96 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFDeTrHe_pp.ini @@ -0,0 +1,12 @@ +[GeneratorExternal] +fileName=/tmp/inj/generator_pythia8_longlived_multiple.C +; funcName=generateLongLivedMultiple({{1000010020, 10, 0.2, 10}, {-1000010020, 10, 0.2, 10}, {1000010030, 10, 0.2, 10}, {-1000010030, 10, 0.2, 10}, {1000020030, 10, 0.2, 10}, {-1000020030, 10, 0.2, 10}}) +# Deuteron Anti-Deuteron Triton Anti-Triton Helium3 Anti-Helium3 +funcName=generateLongLivedMultiple("${O2DPG_ROOT}/MC/config/PWGLF/pythia8/generator/particlelist.gun") + +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg + +[DecayerPythia8] +config[0]=${O2DPG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_ROOT}/MC/config/PWGLF/pythia8/generator/nuclei.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/nuclei.cfg b/MC/config/PWGLF/pythia8/generator/nuclei.cfg new file mode 100644 index 000000000..dc83b355e --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/nuclei.cfg @@ -0,0 +1,14 @@ +### particle definition +### id:all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 + +### deuteron +1000010020:all = deuteron deuteron_bar 0 3 0 1.8756134 0. 0. 0. 0. +1000010020:mayDecay = off + +### triton +1000010030:all = triton triton_bar 0 3 0 2.8089218 0. 0. 0. 0. +1000010030:mayDecay = off + +### helium-3 +1000020030:all = helium3 helium3_bar 0 6 0 2.80923 0. 0. 0. 0. +1000020030:mayDecay = off diff --git a/MC/config/PWGLF/pythia8/generator/particlelist.gun b/MC/config/PWGLF/pythia8/generator/particlelist.gun new file mode 100644 index 000000000..ab4564eb6 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/particlelist.gun @@ -0,0 +1,7 @@ +# PDG N ptMin ptMax +1000010020 10 0.2 10 +-1000010020 10 0.2 10 +1000010030 10 0.2 10 +-1000010030 10 0.2 10 +1000020030 10 0.2 10 +-1000020030 10 0.2 10 \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C b/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C index eeb41dc04..6220c00fc 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C @@ -25,19 +25,16 @@ public: void setRandomizePDGsign(bool val) { randomizePDGsign = val; } /// get mass from TParticlePDG - double getMass(int input_pdg) + static double getMass(int input_pdg) { double mass = 0; if (TDatabasePDG::Instance()) { TParticlePDG *particle = TDatabasePDG::Instance()->GetParticle(input_pdg); - if (particle) - { + if (particle) { mass = particle->Mass(); - } - else - { - std::cout << "===> Unknown particle requested, mass set to 0" << std::endl; + } else { + std::cout << "===> Unknown particle requested with PDG " << input_pdg << ", mass set to 0" << std::endl; } } return mass; diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_longlived_multiple.C b/MC/config/PWGLF/pythia8/generator_pythia8_longlived_multiple.C new file mode 100644 index 000000000..1aa587c10 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_longlived_multiple.C @@ -0,0 +1,161 @@ +/// +/// \file generator_pythia8_longlived_multiple.C +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \brief Implementation of a gun generator for multiple particles, built on generator_pythia8_longlived.C +/// usage: +/// o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_longlived_multiple.C;GeneratorExternal.funcName=generateLongLivedMultiple({1010010030}, {10}, {0.5}, {10})' +/// or: +/// o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_longlived_multiple.C;GeneratorExternal.funcName=generateLongLivedMultiple({{1010010030, 10, 0.5, 10}})' +/// + +#include "generator_pythia8_longlived.C" +#include "TSystem.h" +#include + +using namespace Pythia8; + +class GeneratorPythia8LongLivedGunMultiple : public GeneratorPythia8LongLivedGun +{ + public: + /// constructor + GeneratorPythia8LongLivedGunMultiple() : GeneratorPythia8LongLivedGun{0} + { + } + + /// Destructor + ~GeneratorPythia8LongLivedGunMultiple() = default; + + //__________________________________________________________________ + Bool_t importParticles() override + { + GeneratorPythia8::importParticles(); + for (const ConfigContainer& cfg : gunConfigs) { + for (int i{0}; i < cfg.nInject; ++i) { + const double pt = gRandom->Uniform(cfg.ptMin, cfg.ptMax); + const double eta = gRandom->Uniform(cfg.etaMin, cfg.etaMax); + const double phi = gRandom->Uniform(0, TMath::TwoPi()); + const double px{pt * std::cos(phi)}; + const double py{pt * std::sin(phi)}; + const double pz{pt * std::sinh(eta)}; + const double et{std::hypot(std::hypot(pt, pz), cfg.mass)}; + mParticles.push_back(TParticle(cfg.pdg, 1, -1, -1, -1, -1, px, py, pz, et, 0., 0., 0., 0.)); + } + } + return true; + } + + struct ConfigContainer { + ConfigContainer(int input_pdg = 0, int n = 1, float p = 1, float P = 10) : pdg{input_pdg}, + nInject{n}, + ptMin{p}, + ptMax{P} + { + mass = GeneratorPythia8LongLivedGun::getMass(pdg); + }; + ConfigContainer(TObjArray* arr) : ConfigContainer(atoi(arr->At(0)->GetName()), + atoi(arr->At(1)->GetName()), + atof(arr->At(2)->GetName()), + atof(arr->At(3)->GetName())){}; + + int pdg = 0; + int nInject = 1; + float ptMin = 1; + float ptMax = 10; + float etaMin = -1.f; + float etaMax = 1.f; + double mass = 0.f; + void print() const + { + Printf("int pdg = %i", pdg); + Printf("int nInject = %i", nInject); + Printf("float ptMin = %f", ptMin); + Printf("float ptMax = %f", ptMax); + Printf("float etaMin = %f", etaMin); + Printf("float etaMax = %f", etaMax); + Printf("double mass = %f", mass); + } + }; + + //__________________________________________________________________ + ConfigContainer addGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10) + { + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax}; + gunConfigs.push_back(cfg); + return cfg; + } + + //__________________________________________________________________ + ConfigContainer addGun(ConfigContainer cfg) { return addGun(cfg.pdg, cfg.nInject, cfg.ptMin, cfg.ptMax); } + + private: + std::vector gunConfigs; // List of gun configurations to use +}; + +///___________________________________________________________ +/// Create generator via arrays of entries +FairGenerator* generateLongLivedMultiple(std::vector PDGs, std::vector nInject, std::vector ptMin, std::vector ptMax) +{ + const std::vector entries = {PDGs.size(), nInject.size(), ptMin.size(), ptMax.size()}; + if (!std::equal(entries.begin() + 1, entries.end(), entries.begin())) { + Printf("Not equal number of entries, check configuration"); + return nullptr; + } + GeneratorPythia8LongLivedGunMultiple* multiGun = new GeneratorPythia8LongLivedGunMultiple(); + for (unsigned long i = 0; i < entries[0]; i++) { + multiGun->addGun(PDGs[i], nInject[i], ptMin[i], ptMax[i]); + } + return multiGun; +} + +///___________________________________________________________ +/// Create generator via an array of configurations +FairGenerator* generateLongLivedMultiple(std::vector cfg) +{ + if (cfg.size() == 1) { + return new GeneratorPythia8LongLivedGun(cfg[0].pdg, cfg[0].nInject, cfg[0].ptMin, cfg[0].ptMax); + } + GeneratorPythia8LongLivedGunMultiple* multiGun = new GeneratorPythia8LongLivedGunMultiple(); + for (const auto& c : cfg) { + Printf("Adding gun"); + c.print(); + multiGun->addGun(c); + } + return multiGun; +} + +///___________________________________________________________ +/// Create generator via input file +FairGenerator* generateLongLivedMultiple(std::string configuration = "${O2DPG_ROOT}/MC/config/PWGLF/pythia8/generator/particlelist.gun") +{ + configuration = gSystem->ExpandPathName(configuration.c_str()); + Printf("Using configuration file '%s'", configuration.c_str()); + std::ifstream inputFile(configuration.c_str(), ios::in); + std::vector cfgVec; + if (inputFile.is_open()) { + std::string l; + int n = 0; + while (getline(inputFile, l)) { + TString line = l; + line.Strip(TString::kBoth, ' '); + + std::cout << n++ << " " << line << endl; + if (line.BeginsWith("#")) { + std::cout << "Skipping\n"; + continue; + } + + GeneratorPythia8LongLivedGunMultiple::ConfigContainer cfg(line.Tokenize(" ")); + cfgVec.push_back(cfg); + } + } else { + Printf("ERROR: can't open '%s'", configuration.c_str()); + return nullptr; + } + return generateLongLivedMultiple(cfgVec); +} + +///___________________________________________________________ +void generator_pythia8_longlived_multiple() +{ + Printf("Compiled correctly!"); +} diff --git a/MC/run/PWGLF/run_DeTrHeInjected.sh b/MC/run/PWGLF/run_DeTrHeInjected.sh new file mode 100755 index 000000000..79faa7c40 --- /dev/null +++ b/MC/run/PWGLF/run_DeTrHeInjected.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# +# A example workflow MC->RECO->AOD for a simple pp min bias +# production, targetting test beam conditions. + +# make sure O2DPG + O2 is loaded +[ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 + +# ----------- LOAD UTILITY FUNCTIONS -------------------------- +. ${O2_ROOT}/share/scripts/jobutils.sh + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +MODULES="--skipModules ZDC" +SIMENGINE=${SIMENGINE:-TGeant3} +NSIGEVENTS=${NSIGEVENTS:-1} +NBKGEVENTS=${NBKGEVENTS:-1} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-50000} +SYSTEM=${SYSTEM:-pp} +ENERGY=${ENERGY:-900} +[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" + +echo $MODULES + +# create workflow +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "${MODULES}" \ + -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFDeTrHe_${SYSTEM}.ini + +# run workflow +# allow increased timeframe parallelism with --cpu-limit 32 +${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt aod --cpu-limit 32