diff --git a/MC/config/PWGUD/external/generator/GeneratorUpcgen.C b/MC/config/PWGUD/external/generator/GeneratorUpcgen.C new file mode 100644 index 000000000..f746cf6a5 --- /dev/null +++ b/MC/config/PWGUD/external/generator/GeneratorUpcgen.C @@ -0,0 +1,175 @@ +R__LOAD_LIBRARY(libUpcgenlib.so) +R__ADD_INCLUDE_PATH($upcgen_ROOT/include) + +#include "UpcGenerator.h" + +// usage: o2-sim -n 100 -g external --configKeyValues 'GeneratorExternal.fileName=GeneratorUpcgen.C;GeneratorExternal.funcName=GeneratorUpcgen("kDiTau")' + +namespace o2 { +namespace eventgen { +class GeneratorUPCgen_class : public Generator { +public: + GeneratorUPCgen_class() { mUPCgen = new UpcGenerator(); }; + ~GeneratorUPCgen_class() = default; + void selectConfiguration(std::string val) { mSelectedConfiguration = val; }; + void setLumiFileDirectory(std::string lumiFileDirectory) { + mUPCgen->setLumiFileDirectory(lumiFileDirectory); + }; + void setCollisionSystem(float energyCM, int beamZ, int beamA) { + eCM = energyCM; + projZ = beamZ; + projA = beamA; + }; + void setSeed(int seed) { mUPCgen->setSeed(seed); } + + // predefined generator configurations + const static int nProcess = 5; + const static int nElements = 9; + const struct UpcgenConfig { + std::string pnames[nElements]{"PROC_ID", "LEP_A", "ALP_MASS", + "ALP_WIDTH", "PT_MIN", "ETA_MIN", + "ETA_MAX", "FLUX_POINT", "BREAKUP_MODE"}; + const struct definitions { + const char *name; + std::string elements[nElements]; + } sets[nProcess] = { + {"kDiElectron", + {"11", "0.0", "0.0", "0.0", "0.0", "-1.0", "1.0", "1", "1"}}, + {"kDiMuon", + {"13", "0.0", "0.0", "0.0", "0.0", "-1.0", "1.0", "1", "1"}}, + {"kDiTau", {"15", "0.0", "0.0", "0.0", "0.0", "-1.0", "1.0", "1", "1"}}, + {"kLightByLight", + {"22", "0.0", "0.0", "0.0", "0.0", "-1.0", "1.0", "1", "1"}}, + {"kAxionLike", + {"51", "0.0", "0.0", "0.0", "0.0", "-1.0", "1.0", "1", "1"}}}; + } upcgenConfig; + + bool Config() { + // select a specific set of parameters + int idx = -1; + for (int i = 0; i < nProcess; ++i) { + if (mSelectedConfiguration.compare(upcgenConfig.sets[i].name) == 0) { + idx = i; + break; + } + } + + if (idx == -1) { + std::cout << "UPCGEN process " << mSelectedConfiguration + << " is not supported" << std::endl; + return false; + } + + // new generator + mUPCgen->setDebugLevel(0); + mUPCgen->setNumThreads(1); + + // update generator parameters - configure + mUPCgen->setParameterValue("DO_PT_CUT", "1"); + mUPCgen->setParameterValue("DO_ETA_CUT", "1"); + mUPCgen->setParameterValue("USE_ROOT_OUTPUT", "0"); + mUPCgen->setParameterValue("USE_HEPMC_OUTPUT", "0"); + + for (int i = 0; i < nElements; ++i) { + mUPCgen->setParameterValue(upcgenConfig.pnames[i], + upcgenConfig.sets[idx].elements[i]); + } + + return true; + } + + bool Init() override { + Generator::Init(); + + // initialize the generator + mUPCgen->init(); + + return true; + }; + + bool generateEvent() override { + if (!mUPCgen) { + std::cout << "GenerateEvent: upcgen class/object not properly constructed" + << std::endl; + return false; + } + + // generate a new event + vector pdgs; + vector statuses; + vector mothers; + vector particles; + // events can be rejected due to applied cuts + bool goon = true; + while (goon) { + auto stat = mUPCgen->generateEvent(pdgs, statuses, mothers, particles); + if (stat == 0) { + nRejected++; + } else { + nAccepted++; + goon = false; + } + } + + return true; + }; + + bool importParticles() override { + std::cout << "\n"; + auto upcgenParticles = mUPCgen->getParticles(); + for (auto part : upcgenParticles) { + part.Print(); + TParticle particle(part.GetPdgCode(), 1, part.GetFirstMother(), -1, + part.GetFirstDaughter(), part.GetLastDaughter(), + part.Px(), part.Py(), part.Pz(), part.Energy(), 0., 0., + 0., 0.); + mParticles.push_back(particle); + o2::mcutils::MCGenHelper::encodeParticleStatusAndTracking( + mParticles.back(), true); + } + return true; + }; + + long int acceptedEvents() { return nAccepted; } + long int rejectedEvents() { return nRejected; } + double fiducialXSection() { + return mUPCgen->totNuclX() * nAccepted / (nAccepted + nRejected); + } + +private: + UpcGenerator *mUPCgen = 0x0; + std::string mSelectedConfiguration = ""; + + // keep track of the rejected and accepted events + long int nAccepted{0}; + long int nRejected{0}; + + float eCM = 5020; + int projZ = 82; + int projA = 208; +}; + +} // namespace eventgen +} // namespace o2 + +FairGenerator *GeneratorUpcgen(std::string configuration = "kDiTau", + std::string lumiFileDirectory = ".", + float energyCM = 5020., int beamZ = 82, + int beamA = 208) { + // create generator + auto gen = new o2::eventgen::GeneratorUPCgen_class(); + + // set generator parameters + gen->selectConfiguration(configuration); + gen->setLumiFileDirectory(lumiFileDirectory); + gen->setCollisionSystem(energyCM, beamZ, beamA); + + // configure the generator + cout << "Upcgen is initialized ..."; + gen->Config(); + cout << " config done ..."; + gen->Init(); + cout << " init done!\n"; + + return gen; +} diff --git a/MC/config/PWGUD/ini/makeUpcgenConfig.py b/MC/config/PWGUD/ini/makeUpcgenConfig.py new file mode 100755 index 000000000..cea1854d0 --- /dev/null +++ b/MC/config/PWGUD/ini/makeUpcgenConfig.py @@ -0,0 +1,59 @@ +#! /usr/bin/env python3 + +### @author: Paul Buehler +### @email: paul.buhler@cern.ch + +import argparse + +parser = argparse.ArgumentParser(description='Make Upcgen configuration', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + +parser.add_argument('--collType',default='PbPb', choices=['PbPb', 'OO'], + help='Colission system') + +parser.add_argument('--eCM', type=float, default='5360', + help='Centre-of-mass energy') + +parser.add_argument('--rapidity', default='cent', choices=['cent_eta', 'muon_eta'], + help='Rapidity to select') + +parser.add_argument('--process',default=None, choices=['kDiElectron', 'kDiMuon', 'kDiTau', 'kLightByLight', 'kAxionLike'], + help='Process to switch on') + + +parser.add_argument('--output', default='GenUpcgen.ini', + help='Where to write the configuration') + + +args = parser.parse_args() + +if 'PbPb' in args.collType: + pZ = 82 + pA = 208 + +if 'OO' in args.collType: + pZ = 8 + pA = 16 + +### open output file +fout = open(args.output, 'w') + +### Generator +fout.write('[GeneratorExternal] \n') +fout.write('fileName = ${O2DPG_ROOT}/MC/config/PWGUD/external/generator/GeneratorUpcgen.C \n') +fout.write('funcName = GeneratorUpcgen("%s", "%s", %f, %d, %d) \n' % (args.process,"../.",args.eCM,pZ,pA)) + +###Trigger +fout.write('[TriggerExternal] \n') +fout.write('fileName = ${O2DPG_ROOT}/MC/config/PWGUD/trigger/selectParticlesInAcceptance.C \n') +if args.rapidity == 'cent_rap': + fout.write('funcName = selectMotherPartInAcc(-0.9,0.9) \n') +if args.rapidity == 'muon_rap': + fout.write('funcName = selectMotherPartInAcc(-4.0,-2.5) \n') +if args.rapidity == 'cent_eta': + fout.write('funcName = selectDaughterPartInAcc(-0.95,0.95) \n') +if args.rapidity == 'muon_eta': + fout.write('funcName = selectDaughterPartInAcc(-4.05,-2.45) \n') + +### close outout file +fout.close() diff --git a/MC/run/PWGUD/runUpcgenANCHOR.sh b/MC/run/PWGUD/runUpcgenANCHOR.sh new file mode 100755 index 000000000..6ea86f55e --- /dev/null +++ b/MC/run/PWGUD/runUpcgenANCHOR.sh @@ -0,0 +1,30 @@ +# Run as: ${O2DPG_ROOT}/GRID/utils/grid_submit.sh --script ./runUpcgenANCHOR.sh --jobname SLtest --outputspec "*.log@disk=1","*.root@disk=2" --packagespec "VO_ALICE@O2sim::v20240626-1" --wait --fetch-output --asuser pbuhler --local + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_COLLISIONSYSTEM=PbPb +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMPASSNAME=apass2 +export ALIEN_JDL_LPMRUNNUMBER=544389 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=PbPb +export ALIEN_JDL_LPMPRODUCTIONTAG=MyPass2Test +export ALIEN_JDL_LPMANCHORRUN=544389 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC23zzi +export ALIEN_JDL_LPMANCHORYEAR=2023 + +export NTIMEFRAMES=2 +export NSIGEVENTS=5 +export NBKGEVENTS=1 +export SPLITID=2 +export PRODSPLIT=100 +export CYCLE=0 +export ALIEN_PROC_ID=2963436952 + + +#export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini ${PWD}/GenUpcgen.ini --embedding -nb ${NBKGEVENTS} -colBkg PbPb -genBkg pythia8 -procBkg heavy_ion" + +${O2DPG_ROOT}/MC/config/PWGUD/ini/makeUpcgenConfig.py --process kDiTau --collType PbPb --eCM 5360 --rapidity cent_eta +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini ${PWD}/GenUpcgen.ini" + +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh