From 97aa30f8942e3ec2bbede4d8216c33638cf31349 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Fri, 18 Jul 2025 17:34:55 +0200 Subject: [PATCH 001/362] Add decayer for h3l kink decay (#2057) Co-authored-by: Francesco Mazzaschi --- .../pythia8/decayer/force_h3l_kink_decay.cfg | 20 ++++++ .../pythia8/decayer/g4_ext_decayer_h3l.in | 68 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 MC/config/PWGLF/pythia8/decayer/force_h3l_kink_decay.cfg create mode 100644 MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_h3l.in diff --git a/MC/config/PWGLF/pythia8/decayer/force_h3l_kink_decay.cfg b/MC/config/PWGLF/pythia8/decayer/force_h3l_kink_decay.cfg new file mode 100644 index 000000000..abc615984 --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/force_h3l_kink_decay.cfg @@ -0,0 +1,20 @@ +Init:showChangedParticleData = on +1010010030:new = hypertriton anti_hypertriton 1 0 0 0 0 2.991 0.0 0.0 0.0 +1010010030:m0 = 2.991 +1010010030:mWidth = 0.0 +1010010030:tau0 = 78.0 # lifetime in mm (~2.6e-10 s) +1010010030:spinType = 1 +1010010030:chargeType = 3 # +1 e = 3 * (1/3 e) +1010010030:colType = 0 + +1000010030:new = triton anti_triton 1 0 0 0 0 2.80892 0.0 0.0 0.0 +1000010030:m0 = 2.80892 +1000010030:mWidth = 0.0 +1000010030:tau0 = 0.0 # effectively stable +1000010030:spinType = 1 +1000010030:chargeType = 3 # +1 e +1000010030:colType = 0 +1000010030:mayDecay = off + +1010010030:mayDecay = on +1010010030:oneChannel = 1 1.0 0 1000010030 111 diff --git a/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_h3l.in b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_h3l.in new file mode 100644 index 000000000..8bbdf6ca3 --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_h3l.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection hypertriton anti_hypertriton \ No newline at end of file From a2d0f4e9b67f615f96c819b01472116beb0d95ab Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Fri, 18 Jul 2025 23:26:21 +0200 Subject: [PATCH 002/362] Add Lambda1405 (#2064) Co-authored-by: Francesco Mazzaschi --- MC/config/PWGLF/pythia8/generator/resonances.cfg | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MC/config/PWGLF/pythia8/generator/resonances.cfg b/MC/config/PWGLF/pythia8/generator/resonances.cfg index 628ba85e2..1058a9488 100644 --- a/MC/config/PWGLF/pythia8/generator/resonances.cfg +++ b/MC/config/PWGLF/pythia8/generator/resonances.cfg @@ -1,6 +1,12 @@ ### Define resonance ProcessLevel:all = off # will not look for the 'process' +102132:all = Lambda1405 Lambda1405bar 4 0 0 1.40500 0.05000 1.30 1.50 0 +102132:oneChannel = 1 0.33333 5 3112 211 +102132:addChannel = 1 0.33333 5 3222 -211 +102132:addChannel = 1 0.33333 5 3212 111 + + # id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 102134:all = Lambda1520 Lambda1520bar 4 0 0 1.51950 0.01560 1.47 1.60 0 From 3448606cfb0b37180117c144f85eed31a6b2a44f Mon Sep 17 00:00:00 2001 From: chengtt0406 <39661669+chengtt0406@users.noreply.github.com> Date: Mon, 21 Jul 2025 00:43:25 +0800 Subject: [PATCH 003/362] New files for producing eventpool of undecayed XiC (#2056) * New files for producing eventpool of undecayed XiC * add scripts for testing the new .ini files --- ..._D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini | 8 ++ ...eneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini | 8 ++ ...rHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini | 8 ++ ...D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini | 8 ++ ..._D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini | 8 ++ ...eneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini | 8 ++ ...rHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini | 8 ++ ...D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini | 8 ++ ...HF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C | 83 ++++++++++++++++++ .../GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C | 83 ++++++++++++++++++ ...torHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C | 83 ++++++++++++++++++ ...F_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C | 83 ++++++++++++++++++ ...HF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C | 84 +++++++++++++++++++ .../GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C | 84 +++++++++++++++++++ ...torHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C | 84 +++++++++++++++++++ ...F_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C | 84 +++++++++++++++++++ ...ia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg | 49 +++++++++++ .../pythia8_charmhadronic_XiC_NoDecay.cfg | 42 ++++++++++ 18 files changed, 823 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..5ae8c3f42 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini new file mode 100644 index 000000000..374f24889 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..942e2be65 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini new file mode 100644 index 000000000..ca98bb303 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..09db15af0 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini new file mode 100644 index 000000000..98fb54c62 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..a25594bc9 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini new file mode 100644 index 000000000..0231b40bf --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C new file mode 100644 index 000000000..73788a608 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 5; + + int checkPdgHadron{4332}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed OmegaC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C new file mode 100644 index 000000000..c840907c4 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 5; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C new file mode 100644 index 000000000..c840907c4 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 5; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C new file mode 100644 index 000000000..be57c96e1 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 5; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiCplus, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C new file mode 100644 index 000000000..dc5ba9604 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 4; + + int checkPdgHadron{4332}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed OmegaC, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C new file mode 100644 index 000000000..caf5fd98f --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 4; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C new file mode 100644 index 000000000..caf5fd98f --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 4; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C new file mode 100644 index 000000000..e386c8a8b --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne = 4; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiCplus, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg new file mode 100644 index 000000000..024c6fa8e --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg @@ -0,0 +1,49 @@ +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: July 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### switch off Xic0 decays +4132:onMode = off + +### switch off Xic+ decays +4232:onMode = off + +### switch off OmegaC decays +4332:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg new file mode 100644 index 000000000..7719e8b32 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg @@ -0,0 +1,42 @@ +### configuration for XiC + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +#Correct decay lengths(wrong in PYTHIA8 decay table) +#Lb +5122:tau0 = 0.4390 +#Xic0 +4132:tau0 = 0.0455 +#OmegaC +4332:tau0 = 0.0803 + +### switch off XiC decays +4132:onMode = off From 1d682cc1f7dce7a251733389bbcf3baeb053be70 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:12:05 +0200 Subject: [PATCH 004/362] Add LambdaNN and Li4 to hypernuclei gun (#2065) --- MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun b/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun index 3b4a8d274..8bda8396e 100644 --- a/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun +++ b/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun @@ -6,3 +6,5 @@ 1010010030 20 0.2 10 -1 1 1010010040 20 0.2 10 -1 1 1010020040 20 0.2 10 -1 1 +1010000030 10 0.2 10 -1 1 +1000030040 10 0.2 10 -1 1 From 5035ac19dfbe8796783b7452438771826cb35d20 Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:39:43 +0200 Subject: [PATCH 005/362] Fixing issue with 5TeV generator (#2066) Co-authored-by: Lucamicheletti93 --- .../generator/GeneratorPromptCharmonia.C | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index ceff8e6a6..75210ea78 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -810,6 +810,32 @@ FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp13TeV() return genCocktailEvtGen; } +FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsiFwdY; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsiFwdY; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiMuon); + + return genCocktailEvtGen; +} + FairGenerator* GeneratorParamPromptPsiToJpsiPiPiEvtGen_pp13TeV(TString pdgs = "100443") From 0c5f7c50eb607023f5e266be42205c4a27c6c01b Mon Sep 17 00:00:00 2001 From: Niveditha Ramasubramanian Date: Fri, 18 Jul 2025 15:34:08 +0200 Subject: [PATCH 006/362] Adding a CCDB-path-single --- DATA/production/calib/mft-noise-aggregator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/production/calib/mft-noise-aggregator.sh b/DATA/production/calib/mft-noise-aggregator.sh index 6155032ca..5bb5feeca 100755 --- a/DATA/production/calib/mft-noise-aggregator.sh +++ b/DATA/production/calib/mft-noise-aggregator.sh @@ -9,7 +9,7 @@ source common/getCommonArgs.sh PROXY_INSPEC="A:MFT/DIGITS/0;B:MFT/DIGITSROF/0" WORKFLOW="o2-dpl-raw-proxy $ARGS_ALL --proxy-name mft-noise-input-proxy --dataspec \"$PROXY_INSPEC\" --network-interface ib0 --channel-config \"name=mft-noise-input-proxy,method=bind,type=pull,rateLogging=0,transport=zeromq\" | " -WORKFLOW+="o2-calibration-mft-calib-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --useDigits --prob-threshold 1e-5 --send-to-server DCS-CCDB --path-CCDB \"/MFT/Calib/NoiseMap\" --path-DCS \"/MFT/Config/NoiseMap\" | " +WORKFLOW+="o2-calibration-mft-calib-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --useDigits --prob-threshold 1e-5 --send-to-server DCS-CCDB --path-CCDB \"/MFT/Calib/NoiseMap\" --path-DCS \"/MFT/Config/NoiseMap\" --path-CCDB-single \"/MFT/Calib/NoiseMapSingle\" | " WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"http://o2-ccdb.internal\" --sspec-min 0 --sspec-max 0 | " WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"$DCSCCDBSERVER_PERS\" --sspec-min 1 --sspec-max 1 --name-extention dcs | " WORKFLOW+="o2-dpl-run $ARGS_ALL $GLOBALDPLOPT" From 8156096ddeb38bf23602cbd61ef51b702fd579ac Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:25:02 +0200 Subject: [PATCH 007/362] Add sigmapi resonance config (#2067) Co-authored-by: Francesco Mazzaschi --- .../ini/GeneratorLFSigmaPiResonances.ini | 7 +++++ .../generator/sigmapi_resonances_gun.json | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLFSigmaPiResonances.ini create mode 100644 MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json diff --git a/MC/config/PWGLF/ini/GeneratorLFSigmaPiResonances.ini b/MC/config/PWGLF/ini/GeneratorLFSigmaPiResonances.ini new file mode 100644 index 000000000..e58e173c7 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFSigmaPiResonances.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C +funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json", true, 4) + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json b/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json new file mode 100644 index 000000000..6d7e4b2b3 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json @@ -0,0 +1,29 @@ +{ + "lambda(1405)" : { + "pdg": 102132, + "n": 2, + "ptMin": 0.0, + "ptMax": 10, + "etaMin": -1.2, + "etaMax": 1.2, + "genDecayed": true + }, + "lambda(1520)" : { + "pdg": 102134, + "n": 2, + "ptMin": 0.0, + "ptMax": 10, + "etaMin": -1.2, + "etaMax": 1.2, + "genDecayed": true + }, + "sigma(1385)" : { + "pdg": 3214, + "n": 2, + "ptMin": 0.0, + "ptMax": 10, + "etaMin": -1.2, + "etaMax": 1.2, + "genDecayed": true + } +} From acb078eb570761b503482a2434957875d1bc2e94 Mon Sep 17 00:00:00 2001 From: Mattia Faggin Date: Thu, 24 Jul 2025 11:22:28 +0200 Subject: [PATCH 008/362] Add configurations for MC production for SigmaC background studies. (#2069) * Add configurations for MC production for SigmaC background studies. * Add test macro. * Fix names --------- Co-authored-by: Mattia Faggin --- .../generator_pythia8_gaptriggered_hf.C | 10 +- ...bar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini | 10 + ...ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C | 200 ++++++++++++++++++ ...dronic_with_decays_Mode2_CorrBkgSigmaC.cfg | 84 ++++++++ 4 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C index 0a42500da..cdf472096 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -33,8 +33,8 @@ public: mHadronPdgList = hadronPdgList; mPartPdgToReplaceList = partPdgToReplaceList; mFreqReplaceList = freqReplaceList; - // Ds1*(2700), Ds1*(2860), Ds3*(2860), Xic(3055)+, Xic(3080)+, Xic(3055)0, Xic(3080)0 - mCustomPartPdgs = {30433, 40433, 437, 4315, 4316, 4325, 4326}; + // Ds1*(2700), Ds1*(2860), Ds3*(2860), Xic(3055)+, Xic(3080)+, Xic(3055)0, Xic(3080)0, LambdaC(2625), LambdaC(2595) + mCustomPartPdgs = {30433, 40433, 437, 4315, 4316, 4325, 4326, 4124, 14122}; mCustomPartMasses[30433] = 2.714f; mCustomPartMasses[40433] = 2.859f; mCustomPartMasses[437] = 2.860f; @@ -42,6 +42,8 @@ public: mCustomPartMasses[4316] = 3.0799f; mCustomPartMasses[4325] = 3.0559f; mCustomPartMasses[4326] = 3.0772f; + mCustomPartMasses[4124] = 2.62810f; + mCustomPartMasses[14122] = 2.59225f; mCustomPartWidths[30433] = 0.122f; mCustomPartWidths[40433] = 0.160f; mCustomPartWidths[437] = 0.053f; @@ -49,6 +51,8 @@ public: mCustomPartWidths[4316] = 0.0056f; mCustomPartWidths[4325] = 0.0078f; mCustomPartWidths[4326] = 0.0036f; + mCustomPartWidths[4124] = 0.00052f; + mCustomPartWidths[14122] = 0.0026f; Print(); } @@ -436,4 +440,4 @@ FairGenerator *GeneratorPythia8GapHF(int inputTriggerRatio, float yQuarkMin = -1 myGen->setHadronRapidity(yHadronMin, yHadronMax); return myGen; -} \ No newline at end of file +} diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini new file mode 100644 index 000000000..e219b44b5 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini @@ -0,0 +1,10 @@ + +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.5, 1.5, {413}, {{413, 14122}, {413, 4124}}, {0.5, 0.5}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg +includePartonEvent=false +### not needed for jet studies, hence no need to keep parton event \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C new file mode 100644 index 000000000..a300882c0 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C @@ -0,0 +1,200 @@ +#include "TFile.h" +#include "TTree.h" + +#include +#include + +int External() { + std::string path{"/home/mattia/Documenti/cernbox/Documents/PostDoc/D2H/MC/corrBkgSigmaC/tf1/genevents_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./5.; // one event triggered out of 5 + std::array, 2> pdgReplParticles = {std::array{413, 14122}, std::array{413, 4124}}; + std::array, 2> pdgReplPartCounters = {std::array{0, 0}, std::array{0, 0}}; + std::array freqRepl = {0.5, 0.5}; + std::map sumOrigReplacedParticles = {{413, 0}}; + + std::array checkPdgHadron{14122, 4124}; + std::map>> checkHadronDecays{ // sorted (!) pdg of daughters + //{14122, {{4222, -211}, {4112, 211}, {4122, 211, -211}}}, // Lc(2595)+ + //{4124, {{4222, -211}, {4112, 211}, {4122, 211, -211}}} // Lc(2625)+ + {14122, {{-211, 4222}, {211, 4112}, {-211, 211, 4122}}}, // Lc(2595)+ + {4124, {{-211, 4222}, {211, 4112}, {-211, 211, 4122}}} // Lc(2625)+ + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + + std::cout << std::endl; + + tree->GetEntry(i); + + // check subgenerator information + int subGeneratorId{-1}; + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + auto absPdg = std::abs(pdg); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + std::cout << "==> signal " << absPdg << " found!" << std::endl; + + if (subGeneratorId == checkPdgQuarkOne) { // replacement only for prompt ---> BUT ALSO NON-PROMPT D* SEEM TO BE REPLACED + for (int iRepl{0}; iRepl<2; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { + pdgReplPartCounters[iRepl][0]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } else if (absPdg == pdgReplParticles[iRepl][1]) { + pdgReplPartCounters[iRepl][1]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } + } + } else if (subGeneratorId == checkPdgQuarkTwo) { + std::cout << " NB: we have a " << absPdg << " also in event with quark " << checkPdgQuarkTwo << std::endl; + std::cout << " ### mother indices: "; + int idFirstMother = track.getMotherTrackId(); + int idSecondMother = track.getSecondMotherTrackId(); + std::vector motherIds = {}; + for(int i=idFirstMother; i<=idSecondMother; i++) { + std::cout << i << " "; + motherIds.push_back(i); + } + bool partonicEventOn = false; + if(motherIds != std::vector{-1, -1}) { + std::cout << "The " << absPdg << " particle has mothers. This should mean that it comes directly from parton hadronization, and that the partonic event was kept in the MC production " << std::endl; + partonicEventOn = true; + } + std::cout << " ### mother PDG codes: "; + std::vector motherPdgCodes = {}; + if(partonicEventOn) { + for(int i=idFirstMother; i<=idSecondMother; i++) { + motherPdgCodes.push_back(tracks->at(i).GetPdgCode()); + std::cout << motherPdgCodes.back() << " "; + } + + /// check that among the mothers there is a c/cbar quark + /// This means that the charm hadron comes from the c-quark hadronization, where the c/cbar quark + /// comes from a c-cbar pair present in the current event, tagged with a b-bbar (e.g. double-parton scattering) + if(std::find(motherPdgCodes.begin(), motherPdgCodes.end(), 4) == motherPdgCodes.end() && std::find(motherPdgCodes.begin(), motherPdgCodes.end(), -4) == motherPdgCodes.end()) { + /// if the partinc event is not really saved and we arrive here, it means that motherIds != {-1, -1} because + /// the hadron comes from the decay of a beauty hadron. This can happen if and only if this is not a replaced one (i.e. native from Lambdab0 decay) + if (std::find(motherPdgCodes.begin(), motherPdgCodes.end(), 5122) == motherPdgCodes.end() && std::find(motherPdgCodes.begin(), motherPdgCodes.end(), -5122) == motherPdgCodes.end()) { + std::cerr << "The particle " << absPdg << " does not originate neither from a c/c-bar quark (replaced) nor from a Lambda_b0 decay. There is something wrong, aborting..." << std::endl; + return 1; + } + } + } + std::cout << std::endl; + + /// only if we arrive here it means that everything is ok, and we can safely update the counters for the final statistics + for (int iRepl{0}; iRepl<2; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { + pdgReplPartCounters[iRepl][0]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } else if (absPdg == pdgReplParticles[iRepl][1]) { + pdgReplPartCounters[iRepl][1]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } + } + } + + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + if (track.getFirstDaughterTrackId() >= 0 && track.getLastDaughterTrackId() >= 0) { + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + std::cout << " -- daughter " << j << ": " << pdgDau << std::endl; + if (pdgDau != 333) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + std::cout << " !!! GOOD DECAY FOUND !!!" << std::endl; + break; + } + } + } + } // end loop over tracks + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + float fracForcedDecays = float(nSignalGoodDecay) / nSignals; + if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + for (int iRepl{0}; iRepl<2; ++iRepl) { + + std::cout << " --- pdgReplPartCounters[" << iRepl << "][1] = " << pdgReplPartCounters[iRepl][1] << ", freqRepl[" << iRepl <<"] = " << freqRepl[iRepl] << ", sumOrigReplacedParticles[pdgReplParticles[" << iRepl << "][0]] =" << sumOrigReplacedParticles[pdgReplParticles[iRepl][0]] << std::endl; + + if (std::abs(pdgReplPartCounters[iRepl][1] - freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]) > 2 * std::sqrt(freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]])) { // 2 sigma compatibility + float fracMeas = 0.; + if (sumOrigReplacedParticles[pdgReplParticles[iRepl][0]] > 0.) { + fracMeas = float(pdgReplPartCounters[iRepl][1]) / sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; + } + std::cerr << "Fraction of replaced " << pdgReplParticles[iRepl][0] << " into " << pdgReplParticles[iRepl][1] << " is " << fracMeas <<" (expected "<< freqRepl[iRepl] << ")\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg new file mode 100644 index 000000000..0d61dfe3b --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg @@ -0,0 +1,84 @@ +### authors: Mattia Faggin (mattia.faggin@cern.ch) +### last update: July 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# switch off charm-hadron decays +4122:onMode = off +14122:onMode = off ### Lambda_c(2595)+ already present in PYTHIA +4124:onMode = off ### Lambda_c(2625)+ already present in PYTHIA + +## Λc decays +### Λc+ -> p K- π+ +4122:oneChannel = 1 0.0350 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.0196 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.0108 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.0022 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +4122:onIfMatch = 2212 321 211 +4122:onIfMatch = 2212 313 +4122:onIfMatch = 2224 321 +4122:onIfMatch = 102134 211 +### Λc(2595)+ +14122:oneChannel = 1 0.24 0 4222 -211 ### Λc(2595)+ -> Σc(2455)++ π- (24%) +14122:addChannel = 1 0.24 0 4112 211 ### Λc(2595)+ -> Σc(2455)0 π+ (24%) +14122:addChannel = 1 0.18 0 4122 211 -211 ### Λc(2595)+ -> Λc+ π+ π- (18%) +14122:onIfMatch = 4222 211 ### Λc(2595)+ -> Σc(2455)++ π- +14122:onIfMatch = 4112 211 ### Λc(2595)+ -> Σc(2455)0 π+ +14122:onIfMatch = 4122 211 211 ### Λc(2595)+ -> Λc+ π+ π- +### Λc(2625)+ +4124:oneChannel = 1 0.24 0 4222 -211 ### Λc(2592)+ -> Σc(2455)++ π- (24%) +4124:addChannel = 1 0.24 0 4112 211 ### Λc(2592)+ -> Σc(2455)0 π+ (24%) +4124:addChannel = 1 0.18 0 4122 211 -211 ### Λc(2592)+ -> Λc+ π+ π- (18%) +4124:onIfMatch = 4222 211 ### Λc(2625)+ -> Σc(2455)++ π- +4124:onIfMatch = 4112 211 ### Λc(2625)+ -> Σc(2455)0 π+ +4124:onIfMatch = 4122 211 211 ### Λc(2625)+ -> Λc+ π+ π- + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +# Correct Breit-Wigner width +4124:mWidth = 0.00052 # <0.52 MeV + +# Force the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 From 6b769addc27fc4372b7767d9e9d39a8192527b7a Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Thu, 24 Jul 2025 19:22:26 +0200 Subject: [PATCH 009/362] Fixing issue with pp ref generator (#2068) Co-authored-by: Lucamicheletti93 --- .../generator/GeneratorPromptCharmonia.C | 150 +++++++++++++++++- ...dPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini | 2 +- 2 files changed, 149 insertions(+), 3 deletions(-) diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index 75210ea78..29891fe74 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -492,6 +492,152 @@ class O2_GeneratorParamChiC2 : public GeneratorTGenerator GeneratorParam* paramChiC2 = nullptr; }; +class O2_GeneratorParamJpsipp5TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsipp5TeV() : GeneratorTGenerator("ParamJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp5TeV, YJPsipp5TeV, V2JPsipp5TeV, IpJPsipp5TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0, 999.); + paramJpsi->SetYRange(-4.2, -2.3); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // (from AliGenParam) -> check this + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsipp5TeV() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // jpsi pT in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.30923; + p2 = 1.82061; + p3 = 4.37563; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // jpsi y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 1; + p1 = 0.0338222; + p2 = 2.96748; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp5TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsipp5TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsipp5TeV() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp5TeV, YPsipp5TeV, V2Psipp5TeV, IpPsipp5TeV); + paramPsi->SetMomentumRange(0., 1.e6); + paramPsi->SetPtRange(0, 999.); + paramPsi->SetYRange(-4.2, -2.3); + paramPsi->SetPhiRange(0., 360.); + paramPsi->SetDecayer(new TPythia6Decayer()); + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // check this + setTGenerator(paramPsi); + }; + + ~O2_GeneratorParamPsipp5TeV() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // psi2s pT in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 2.6444; + p2 = 6.17572; + p3 = 0.701753; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // psi2s y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 1; + p1 = -17.4857; + p2 = 2.98887; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp5TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; + class O2_GeneratorParamJpsiPbPb5TeV : public GeneratorTGenerator { @@ -815,9 +961,9 @@ FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV() auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); - auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsiFwdY; + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsipp5TeV; genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam - auto genPsi = new o2::eventgen::O2_GeneratorParamPsiFwdY; + auto genPsi = new o2::eventgen::O2_GeneratorParamPsipp5TeV; genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini index 47ed20789..50de50adb 100755 --- a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini @@ -4,4 +4,4 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_py funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,11) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_pp5TeV.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg From fda2dc47a112e20584fbe87897ab51d314d9b415 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Fri, 25 Jul 2025 10:37:07 +0200 Subject: [PATCH 010/362] Update H3L injection scheme in Pb--Pb (#2072) --- MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini b/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini index b4159f513..0f731d66c 100644 --- a/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini +++ b/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C -funcName=generateLongLivedGapTriggered({1010010030}, 5, 10) +funcName=generateLongLivedGapTriggered({1010010030}, 0, 20) [GeneratorPythia8] config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg From 8b2fd92275833cfeb0efe49afc4b1178428a802e Mon Sep 17 00:00:00 2001 From: ypwangg <142303052+ypwangg@users.noreply.github.com> Date: Sat, 26 Jul 2025 21:16:03 +0800 Subject: [PATCH 011/362] Non-prmopt psi2S to Jpsi+pipi (#2073) * non-prompt psi2s to jpsi pipi * remove unused code * small change in decay name --------- Co-authored-by: Yiping Wang --- .../DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC | 167 ++++++++++++++++++ MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C | 4 + ...pythia8_NonPromptSignals_gaptriggered_dq.C | 38 ++++ ...atorHF_bbbar_PsiToJpsi_midy_triggerGap.ini | 14 ++ ...eratorHF_bbbar_PsiToJpsi_midy_triggerGap.C | 104 +++++++++++ 5 files changed, 327 insertions(+) create mode 100644 MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC create mode 100644 MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.ini create mode 100644 MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.C diff --git a/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC new file mode 100644 index 000000000..82102bf60 --- /dev/null +++ b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC @@ -0,0 +1,167 @@ +#### +Decay B0 +# B -> cc= s +0.000310000 psi(2S) K_S0 SVS; #[Reconstructed PDG2011] +0.000310000 psi(2S) K_L0 SVS; #[Reconstructed PDG2011] +# +# +0.000610000 psi(2S) K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] + +0.0004 psi(2S) K+ pi- PHSP; +0.0002 psi(2S) K0 pi0 PHSP; +0.0002 psi(2S) K0 pi- pi+ PHSP; +0.0001 psi(2S) K0 pi0 pi0 PHSP; +0.0001 psi(2S) K+ pi- pi0 PHSP; +0.0004 psi(2S) K_10 PHSP; +# +#### +0.000620000 psi(2S) K0 PHSP; #[New mode added] #[Reconstructed PDG2011] + +Enddecay + +Decay anti-B0 +# +0.000310000 psi(2S) K_S0 SVS; #[Reconstructed PDG2011] +0.000310000 psi(2S) K_L0 SVS; #[Reconstructed PDG2011] +# +# +0.000610000 psi(2S) anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] + +0.0004 psi(2S) K- pi+ PHSP; +0.0002 psi(2S) anti-K0 pi0 PHSP; +0.0002 psi(2S) anti-K0 pi+ pi- PHSP; +0.0001 psi(2S) anti-K0 pi0 pi0 PHSP; +0.0001 psi(2S) K- pi+ pi0 PHSP; +0.0004 psi(2S) anti-K_10 PHSP; +# +0.000620000 psi(2S) anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +#### +Enddecay + +Decay B- +# +# B -> cc= s sum = 1.92% +# +0.000646000 psi(2S) K- SVS; #[Reconstructed PDG2011] +0.000620000 psi(2S) K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.0004 psi(2S) anti-K0 pi- PHSP; +0.0002 psi(2S) K- pi0 PHSP; +0.001900000 psi(2S) K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.0001 psi(2S) K- pi0 pi0 PHSP; +0.0001 psi(2S) anti-K0 pi- pi0 PHSP; +0.0004 psi(2S) K_1- PHSP; +# +0.000025800 psi(2S) pi- PHSP; #[New mode added] #[Reconstructed PDG2011] + +Enddecay + +Decay B+ +# +# B -> cc= s sum = 1.92% +# +0.000646000 psi(2S) K+ SVS; #[Reconstructed PDG2011] +0.000620000 psi(2S) K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.0004 psi(2S) K0 pi+ PHSP; +0.0002 psi(2S) K+ pi0 PHSP; +0.001900000 psi(2S) K+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.0001 psi(2S) K+ pi0 pi0 PHSP; +0.0001 psi(2S) K0 pi+ pi0 PHSP; +0.0004 psi(2S) K_1+ PHSP; +# +#### +0.000025800 psi(2S) pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] + +Enddecay + +Decay B_s0 +# psi' = 0.34% CLNS 94/1315 +0.000465 psi(2S) eta' SVS; +0.000235 psi(2S) eta SVS; +0.000680000 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.0003 psi(2S) K- K+ PHSP; +0.0003 psi(2S) anti-K0 K0 PHSP; +0.0003 psi(2S) K0 K- pi+ PHSP; +0.0003 psi(2S) anti-K0 K0 pi0 PHSP; +0.0003 psi(2S) K- K+ pi0 PHSP; +0.00034 psi(2S) phi pi+ pi- PHSP; +0.00034 psi(2S) phi pi0 pi0 PHSP; +0.0002 psi(2S) eta pi+ pi- PHSP; +0.0002 psi(2S) eta pi0 pi0 PHSP; +0.0004 psi(2S) eta' pi+ pi- PHSP; +0.0004 psi(2S) eta' pi0 pi0 PHSP; +0.0002 psi(2S) pi+ pi- PHSP; +0.0002 psi(2S) pi0 pi0 PHSP; +# +# PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e +0.0000023 phi e+ e- BTOSLLALI; +Enddecay + +Decay anti-B_s0 +# psi' = 0.34% CLNS 94/1315 +# +0.000465 psi(2S) eta' SVS; +0.000235 psi(2S) eta SVS; +0.000680000 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.0003 psi(2S) K- K+ PHSP; +0.0003 psi(2S) anti-K0 K0 PHSP; +0.0003 psi(2S) anti-K0 K+ pi- PHSP; +0.0003 psi(2S) anti-K0 K0 pi0 PHSP; +0.0003 psi(2S) K- K+ pi0 PHSP; +0.00034 psi(2S) phi pi+ pi- PHSP; +0.00034 psi(2S) phi pi0 pi0 PHSP; +0.0002 psi(2S) eta pi+ pi- PHSP; +0.0002 psi(2S) eta pi0 pi0 PHSP; +0.0004 psi(2S) eta' pi+ pi- PHSP; +0.0004 psi(2S) eta' pi0 pi0 PHSP; +0.0002 psi(2S) pi+ pi- PHSP; +0.0002 psi(2S) pi0 pi0 PHSP; +# +# PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e +0.0000023 phi e- e+ BTOSLLALI; + +Enddecay + +Decay Lambda_b0 + 0.00038 Lambda0 psi(2S) PHSP; +Enddecay + +Decay anti-Lambda_b0 + 0.00038 anti-Lambda0 psi(2S) PHSP; +Enddecay + +Decay Xi_b- + 0.00038 Xi- psi(2S) PHSP; +Enddecay + +Decay anti-Xi_b+ + 0.00038 anti-Xi+ psi(2S) PHSP; +Enddecay + +Decay Omega_b- + 0.00038 Omega- psi(2S) PHSP; +Enddecay + +Decay anti-Omega_b+ + 0.00038 anti-Omega+ psi(2S) PHSP; +Enddecay + +Decay B_c- +# SemiLeptonic Decays +0.00094 psi(2S) e- anti-nu_e PHOTOS PHSP; +Enddecay + +Decay B_c+ +# SemiLeptonic Decays +0.00094 psi(2S) e+ nu_e PHOTOS PHSP; +Enddecay + +Decay psi(2S) +1.000 J/psi pi+ pi- VVPIPI; +Enddecay + +Decay J/psi +### from DECAY.DEC +1.000 e+ e- PHOTOS VLL; +Enddecay + +End \ No newline at end of file diff --git a/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C b/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C index da0b1aa6a..18abd5ddf 100644 --- a/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C +++ b/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C @@ -42,6 +42,7 @@ enum DecayModeEvt { kEvtAll = 0, kEvtElectronEM, kEvtDiElectronEM, kEvtGammaEM, + kEvtBtoPsi2SToJpsiPiPi, kEvtBeautyUpgrade }; namespace o2 @@ -355,6 +356,9 @@ class GeneratorEvtGen : public T case kEvtBeautyUpgrade: SetDecayTable(Form("%s/BEAUTYUPGRADE.DEC", pathO2.Data())); break; + case kEvtBtoPsi2SToJpsiPiPi: + SetDecayTable(Form("%s/BTOPSITOJPSIPIPI.DEC", pathO2.Data())); + break; } return; }; diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C index eb26e89f3..b2050175b 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C @@ -351,3 +351,41 @@ FairGenerator* return gen; } +FairGenerator* + GeneratorBeautyToPsiToJpsi_EvtGenMidY(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBtoPsi2SToJpsiPiPi); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.ini new file mode 100644 index 000000000..a891cc8d1 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.ini @@ -0,0 +1,14 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiToJpsi_EvtGenMidY() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hf.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-1.5,1.5) \ No newline at end of file diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.C new file mode 100644 index 000000000..5c50cd1af --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.C @@ -0,0 +1,104 @@ +int External() +{ + int checkPdgSignal[] = {100443}; + int checkPdgDecay[] = {443, 211, -211}; + int leptonPdg = 11; + Double_t rapidityWindow = 1.0; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal[0] << "\n decay PDG " << checkPdgDecay[0] << ", " << checkPdgDecay[1] << ", " << checkPdgDecay[2] << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPionsPos{}; + int nSignalPionsNeg{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPionsPosWithinAcc{}; + int nSignalPionsNegWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + int idJpsi = -1; int IdChild0 = -1; int IdChild1 = -1; + if (pdg == leptonPdg) { + // count leptons + nLeptons++; + } else if(pdg == -leptonPdg) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0]) { + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + nSignalPsi2S++; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + if(TMath::Abs(pdgDau) == checkPdgDecay[0] ) { nSignalJpsi++; if( std::abs(track.GetRapidity()) < rapidityWindow) nSignalJpsiWithinAcc++; idJpsi = j; } + if(pdgDau == checkPdgDecay[1] ) { nSignalPionsPos++; if( std::abs(track.GetRapidity()) < rapidityWindow) nSignalPionsPosWithinAcc++; } + if(pdgDau == checkPdgDecay[2] ) { nSignalPionsNeg++; if( std::abs(track.GetRapidity()) < rapidityWindow) nSignalPionsNegWithinAcc++; } + } + + auto trackJpsi = tracks->at(idJpsi); + for (int j{trackJpsi.getFirstDaughterTrackId()}; j <= trackJpsi.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + if(pdgDau == leptonPdg ) IdChild0 = j; + if(pdgDau == -leptonPdg ) IdChild1 = j; + } + auto child0 = tracks->at(IdChild0); + auto child1 = tracks->at(IdChild1); + // check for parent-child relations + auto pdg0 = child0.GetPdgCode(); + auto pdg1 = child1.GetPdgCode(); + if (std::abs(pdg0) == leptonPdg && std::abs(pdg1) == leptonPdg && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0.getToBeDone() && child1.getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- psi2S): " << nSignalJpsi << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalJpsiWithinAcc << "\n" + << "#signal (pi+ <- psi2S): " << nSignalPionsPos << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalPionsPosWithinAcc << "\n" + << "#signal (pi- <- psi2S): " << nSignalPionsNeg << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalPionsNegWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} \ No newline at end of file From cd5d613bdaf9a6e31ed52d777de01407b72ba9c5 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Tue, 29 Jul 2025 11:20:28 +0200 Subject: [PATCH 012/362] Fix H3L injection scheme in Pb--Pb (#2075) --- MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini b/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini index 0f731d66c..a1d8f67e9 100644 --- a/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini +++ b/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C -funcName=generateLongLivedGapTriggered({1010010030}, 0, 20) +funcName=generateLongLivedGapTriggered({1010010030}, 1, 20) [GeneratorPythia8] config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg From 1ae12109a9ed9a6f92d2f8b326404a77285b2580 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Tue, 29 Jul 2025 17:59:35 +0200 Subject: [PATCH 013/362] Add option to have AO2Ds with prepropagated tracks (#2076) * Add option to have AO2Ds with prepropagated tracks * Update setenv_extra.sh --- DATA/production/configurations/asyncReco/setenv_extra.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 6cdd3203a..d911c63a6 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -802,6 +802,10 @@ if [[ $ALIEN_JDL_THINAODS == "1" ]] ; then export ARGS_EXTRA_PROCESS_o2_aod_producer_workflow+=" --thin-tracks" fi +if [[ $ALIEN_JDL_PREPROPAGATE == "1" ]] ; then + export ARGS_EXTRA_PROCESS_o2_aod_producer_workflow+=" --propagate-tracks --propagate-tracks-max-xiu 5" +fi + # Enabling QC if [[ $ALIEN_JDL_QCOFF != "1" ]]; then export WORKFLOW_PARAMETERS="QC,${WORKFLOW_PARAMETERS}" From eed375d468769115db590d2b76c798b43155ade3 Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 29 Jul 2025 17:50:18 +0200 Subject: [PATCH 014/362] Make sure non-number INST_IR_FOR_TPC is not evaluated as a number --- DATA/production/configurations/asyncReco/setenv_extra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index d911c63a6..2128f9686 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -463,7 +463,7 @@ elif [[ $ALIGNLEVEL == 1 ]]; then # set IR for TPC, even if it is not used for corrections scaling - if (( $(echo "$INST_IR_FOR_TPC > 0" | bc -l) )) ; then # externally imposed CTP IR + if [[ "$INST_IR_FOR_TPC" =~ ^-?[0-9]*\.?[0-9]+$ ]] && (( $(echo "$INST_IR_FOR_TPC > 0" | bc -l) )) ; then # externally imposed CTP IR echo "Applying externally provided istantaneous IR $INST_IR_FOR_TPC Hz" export TPC_CORR_SCALING+=";TPCCorrMap.lumiInst=$INST_IR_FOR_TPC" elif [[ $INST_IR_FOR_TPC == "CTP" ]]; then From 53f40301f1dbba9eb798fcb8d8a8aba682feee0c Mon Sep 17 00:00:00 2001 From: cpuggion84 <90757182+cpuggion84@users.noreply.github.com> Date: Thu, 31 Jul 2025 14:41:53 +0200 Subject: [PATCH 015/362] Config oo pp ne (#2044) * Update zdc.json new config for oxigen, proton and ne * Update zdcPbPb.json * Update zdcPbPb.json fixed error bin in histograms TDCAZEMvsTDCT * Update zdc.json Add Data sources for Post Processing * Update zdc.json Adjust Bin TDCAH and ADCH --- DATA/production/qc-async/zdc.json | 23 ++-- DATA/production/qc-async/zdcPbPb.json | 2 +- DATA/production/qc-postproc-async/zdc.json | 150 +++++++++++++++------ 3 files changed, 121 insertions(+), 54 deletions(-) diff --git a/DATA/production/qc-async/zdc.json b/DATA/production/qc-async/zdc.json index 2f74fb164..5059a95c9 100644 --- a/DATA/production/qc-async/zdc.json +++ b/DATA/production/qc-async/zdc.json @@ -36,28 +36,29 @@ "query": "zdc-bcrec:ZDC/BCREC/0;zdc-energyrec:ZDC/ENERGY/0;zdc-tdcrec:ZDC/TDCDATA/0;zdc-inforec:ZDC/INFO/0" }, "taskParameters": { - "ADC": "3600; -3;357", + "ADC": "3025;-100;12000", "ADCZEM": "3025;-100;12000", - "ADCH": "2300;-3;20", + "ADCH": "3100;-100;3000", "TDCT": "2400;-13.5;11.45", - "TDCA": "3600; -3;357", + "TDCA": "2050;-0.5;4099.5", "TDCAZEM": "2050;-0.5;4099.5", - "TDCAH": "2300;-3;20", - "ADCSUMvsTC": "144;-3;357;144;-3;357", + "TDCAH": "1010;-10;1000", + "ADCSUMvsTC": "121;-100;12000;121;-100;12000", "ADCZEMvsADCZEM": "121;-100;12000;121;-100;12000", - "ADCZEMvsTC": "144;-3;357;121;-100;12000", - "ADCvsTDCT": "120;-13.5;11.45;144;-3;357", + "ADCZEMvsTC": "121;-100;12000;121;-100;12000", + "ADCvsTDCT": "120;-13.5;11.45;121;-100;12000", "ADCZEMvsTDCT": "120;-13.5;11.45;121;-100;12000", "TDCDIFF": "240;-27;22.90;240;-27;22.90", - "TDCAvsTDCT": "120;-13.5;11.45;144;-3;357", + "TDCAvsTDCT": "120;-13.5;11.45;125;-1;3999", "TDCAZEMvsTDCT": "120;-13.5;11.45;125;-1;3999", - "TDCAvsTDCA": "144;-3;357;144;-3;357", + "TDCAvsTDCA": "125;-1;3999;125;-1;3999", "TDCAZEMvsTDCAZEM": "125;-1;3999;125;-1;3999", - "TDCAZEMvsTDCA": "144;-3;357;125;-1;3999", + "TDCAZEMvsTDCA": "125;-1;3999;125;-1;3999", "CENTR_ZNA": "200;-2;2;200;-2;2", "CENTR_ZNC": "200;-2;2;200;-2;2", "CENTR_ZPA": "2240;0;22.4", - "CENTR_ZPC": "2240;-22.4;0" + "CENTR_ZPC": "2240;-22.4;0", + "CENTRAL_EVENT_CONFIG": "2.5;1" } } } diff --git a/DATA/production/qc-async/zdcPbPb.json b/DATA/production/qc-async/zdcPbPb.json index 1d1ae0577..0b1f7d091 100644 --- a/DATA/production/qc-async/zdcPbPb.json +++ b/DATA/production/qc-async/zdcPbPb.json @@ -50,7 +50,7 @@ "ADCZEMvsTDCT": "120;-13.5;11.45;121;-100;12000", "TDCDIFF": "240;-27;22.90;240;-27;22.90", "TDCAvsTDCT": "120;-13.5;11.45;144;-3;357", - "TDCAZEMvsTDCT": ";125;-1;3999;120;-13.5;11.45", + "TDCAZEMvsTDCT": "120;-13.5;11.45;125;-1;3999", "TDCAvsTDCA": "144;-3;357;144;-3;357", "TDCAZEMvsTDCAZEM": "125;-1;3999;125;-1;3999", "TDCAZEMvsTDCA": "125;-1;3999;144;-3;357;", diff --git a/DATA/production/qc-postproc-async/zdc.json b/DATA/production/qc-postproc-async/zdc.json index a744a53d1..986d0bd28 100644 --- a/DATA/production/qc-postproc-async/zdc.json +++ b/DATA/production/qc-postproc-async/zdc.json @@ -87,6 +87,48 @@ ] } ], + "dataSourcesTDCA": [ + { + "type": "repository", + "path": "ZDC/MO/Rec", + "names": [ + "ZNAC:h_TDC_ZNA_TC_A", + "ZNAS:h_TDC_ZNA_SUM_A", + "ZPAC:h_TDC_ZPA_TC_A", + "ZPAS:h_TDC_ZPA_SUM_A", + "ZEM1:h_TDC_ZEM1_A", + "ZEM2:h_TDC_ZEM2_A", + "ZNCC:h_TDC_ZNC_TC_A", + "ZNCS:h_TDC_ZNC_SUM_A", + "ZPCC:h_TDC_ZPC_TC_A", + "ZPCS:h_TDC_ZPC_SUM_A" + ] + } + ], + "dataSourcesPeak1n": [ + { + "type": "repository", + "path": "ZDC/MO/Rec", + "names": [ + "ZNAC:h_TDC_ZNA_TC_A", + "ZNAS:h_TDC_ZNA_SUM_A", + "ZNCC:h_TDC_ZNC_TC_A", + "ZNCS:h_TDC_ZNC_SUM_A" + ] + } + ], + "dataSourcesPeak1p": [ + { + "type": "repository", + "path": "ZDC/MO/Rec", + "names": [ + "ZPAC:h_TDC_ZPA_TC_A", + "ZPAS:h_TDC_ZPA_SUM_A", + "ZPCC:h_TDC_ZPC_TC_A", + "ZPCS:h_TDC_ZPC_SUM_A" + ] + } + ], "initTrigger": [ "userorcontrol" ], @@ -117,7 +159,7 @@ { "name": "ZDCQuality/ZDCQuality", "title": "ZDC Quality", - "messageBad": "Inform on-call immediately", + "messageBad": "Bad histograms", "messageMedium": "Add bookkeeping entry", "messageGood": "All checks are OK", "messageNull": "Some histograms are empty!!!" @@ -156,53 +198,77 @@ "detectorName": "ZDC", "policy": "OnAny", "checkParameters": { - "ADC_ZNAC": "700;200;400", - "ADC_ZNA1": "260;100;200", - "ADC_ZNA2": "300;100;200", - "ADC_ZNA3": "170;100;200", - "ADC_ZNA4": "170;100;200", - "ADC_ZNAS": "700;200;400", - "ADC_ZPAC": "700;200;400", - "ADC_ZPA1": "60;50;100", - "ADC_ZPA2": "80;50;100", - "ADC_ZPA3": "245;50;100", - "ADC_ZPA4": "700;200;400", - "ADC_ZPAS": "850;200;400", - "ADC_ZEM1": "1230;200;400", - "ADC_ZEM2": "1275;200;400", - "ADC_ZNCC": "700;200;400", - "ADC_ZNC1": "130;100;200", - "ADC_ZNC2": "280;100;200", - "ADC_ZNC3": "130;100;200", - "ADC_ZNC4": "260;100;200", - "ADC_ZNCS": "600;200;400", - "ADC_ZPCC": "790;200;400", - "ADC_ZPC1": "770;200;400", - "ADC_ZPC2": "350;100;200", - "ADC_ZPC3": "97;50;100", - "ADC_ZPC4": "67;50;67", - "ADC_ZPCS": "1044;200;400", - "ADC_POS_MSG_X": "0.15", - "ADC_POS_MSG_Y": "0.92", - "TDC_ZNAC": "0.0;2.0;4.0", - "TDC_ZNAS": "0.0;2.0;4.0", - "TDC_ZPAC": "0.0;2.0;4.0", - "TDC_ZPAS": "0.0;2.0;4.0", - "TDC_ZEM1": "0.0;2.0;4.0", - "TDC_ZEM2": "0.0;2.0;4.0", - "TDC_ZNCC": "0.0;2.0;4.0", - "TDC_ZNCS": "0.0;2.0;4.0", - "TDC_ZPCC": "0.0;2.0;4.0", - "TDC_ZPCS": "0.0;2.0;4.0", - "TDC_POS_MSG_X": "0.01", - "TDC_POS_MSG_Y": "0.92" + "ADC_ZNAC" : "40.2;10;20", + "ADC_ZNA1" : "10.6;1000;2000", + "ADC_ZNA2" : "11.8;1000;2000", + "ADC_ZNA3" : "8.6;1000;2000", + "ADC_ZNA4" : "6.9;1000;2000", + "ADC_ZNAS" : "41.7;1000;2000", + "ADC_ZPAC" : "17.7;1000;2000", + "ADC_ZPA1" : "1.63;1000;2000", + "ADC_ZPA2" : "2.86;1000;2000", + "ADC_ZPA3" : "5.30;1000;2000", + "ADC_ZPA4" : "12.25;1000;2000", + "ADC_ZPAS" : "20.2;1000;2000", + "ADC_ZEM1" : "803.2;1000;2000", + "ADC_ZEM2" : "891.2;1000;2000", + "ADC_ZNCC" : "40.7;1000;2000", + "ADC_ZNC1" : "9.7;1000;2000", + "ADC_ZNC2" : "15.8;1000;2000", + "ADC_ZNC3" : "6.2;1000;2000", + "ADC_ZNC4" : "8.6;1000;2000", + "ADC_ZNCS" : "42.3;1000;2000", + "ADC_ZPCC" : "19.6;1000;2000", + "ADC_ZPC1" : "14.19;1000;2000", + "ADC_ZPC2" : "7.63;1000;2000", + "ADC_ZPC3" : "2.96;1000;2000", + "ADC_ZPC4" : "1.21;1000;2000", + "ADC_ZPCS" : "20.9;1000;2000", + "ADC_POS_MSG_X": "0.15", + "ADC_POS_MSG_Y": "0.92", + "TDC_ZNAC" : "0.14;1000;2000", + "TDC_ZNAS" : "0.05;1000;2000", + "TDC_ZPAC" : "-0.39;1000;2000", + "TDC_ZPAS" : "-0.11;1000;2000", + "TDC_ZEM1" : "0.07;1000;2000", + "TDC_ZEM2" : "0.02;1000;2000", + "TDC_ZNCC" : "0.19;1000;2000", + "TDC_ZNCS" : "0.08;1000;2000", + "TDC_ZPCC" : "-0.29;1000;2000", + "TDC_ZPCS" : "-0.20;1000;2000", + "TDC_POS_MSG_X": "0.01", + "TDC_POS_MSG_Y": "0.92", + "TDCA_ZNAC" : "326;1000;2000", + "TDCA_ZNAS" : "331;1000;2000", + "TDCA_ZPAC" : "130;1000;2000", + "TDCA_ZPAS" : "146;1000;2000", + "TDCA_ZEM1" : "1203;1000;2000", + "TDCA_ZEM2" : "1265;1000;2000", + "TDCA_ZNCC" : "329;1000;2000", + "TDCA_ZNCS" : "339;1000;2000", + "TDCA_ZPCC" : "146;1000;2000", + "TDCA_ZPCS" : "150;1000;2000", + "TDCA_POS_MSG_X": "0.01", + "TDCA_POS_MSG_Y": "0.92", + "PEAK1N_ZNAC" : "40;1000;2000", + "PEAK1N_ZNAS" : "40;1000;2000", + "PEAK1N_ZNCC" : "40;1000;2000", + "PEAK1N_ZNCS" : "40;1000;2000", + "PEAK1N_POS_MSG_X": "0.01", + "PEAK1N_POS_MSG_Y": "0.92", + "PEAK1P_ZPAC" : "52;1000;2000", + "PEAK1P_ZPAS" : "52;1000;2000", + "PEAK1P_ZPCC" : "52;1000;2000", + "PEAK1P_ZPCS" : "52;1000;2000", + "PEAK1P_POS_MSG_X": "0.01", + "PEAK1P_POS_MSG_Y": "0.92" }, "dataSource": [ { "type": "PostProcessing", "name": "RecPP", "MOs": [ - "h_summary_ADC", "h_summary_TDC" + "h_summary_ADC" , "h_summary_TDC", "h_summary_TDCA", "h_summary_Peak1n", "h_summary_Peak1p" ] } ] From c02c68fa90be8c5a5ab3be1f942845660711181c Mon Sep 17 00:00:00 2001 From: Banajit Barman <113376372+BanajitBarman@users.noreply.github.com> Date: Sun, 3 Aug 2025 00:22:22 +0530 Subject: [PATCH 016/362] added cfg and ini for PYTHIA CR tune with CR mode=1 (#2079) --- MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini | 9 ++++++++ .../generator/pythia8_pp_cr_136tev.cfg | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini b/MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini new file mode 100644 index 000000000..420f99495 --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg new file mode 100644 index 000000000..c3303726e --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg @@ -0,0 +1,21 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13600. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes +# default: Monash 2013 +Tune:pp = 14 + +### CR configurations +ColourReconnection:mode = 1 # new colour reconnection scheme +ColourReconnection:allowJunctions = on + +BeamRemnants:remnantMode = 1 # work with CR mode = 1 + + From 7be1cfd2233691036e2425360ddf4d5cce2c1e96 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Sat, 2 Aug 2025 23:19:46 +0200 Subject: [PATCH 017/362] Skip Chi0c and Chi1c transport by default for EPOS4 (#2078) --- MC/config/examples/epos4/generator_EPOS4.C | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/MC/config/examples/epos4/generator_EPOS4.C b/MC/config/examples/epos4/generator_EPOS4.C index ded97ec17..987bed823 100644 --- a/MC/config/examples/epos4/generator_EPOS4.C +++ b/MC/config/examples/epos4/generator_EPOS4.C @@ -15,16 +15,15 @@ class GeneratorEPOS4 : public o2::eventgen::GeneratorHepMC LOG(error) << "Failed to import particles from HepMC event!"; return false; } - // Remove charmonia chi_0c and chi_1c from the particles list (incompatible with default G4 physics list) + // Skip transport of charmonia chi_0c and chi_1c (incompatible with default G4 physics list) // These are not decayed by EPOS4 (no daughters) if (!mEnChi) { for (int a = 0; a < mParticles.size(); ++a) { if (mParticles[a].GetPdgCode() == 10441 || mParticles[a].GetPdgCode() == 20443) { - LOG(debug) << "Removing charmonium state " << mParticles[a].GetPdgCode() << " from particles list"; - mParticles.erase(mParticles.begin() + a); - --a; // Adjust index after erasing + LOG(debug) << "Setting charmonium state " << mParticles[a].GetPdgCode() << " with index " << a << " not to be transported"; + mParticles[a].SetBit(ParticleStatus::kToBeDone, false); } } } @@ -34,7 +33,7 @@ class GeneratorEPOS4 : public o2::eventgen::GeneratorHepMC void setChiFlag(bool &flag) { mEnChi = flag; if (!flag) { - LOG(info) << "Charmonium states chi_0c and chi_1c will be removed from the particles list"; + LOG(info) << "Charmonium states chi_0c and chi_1c will not be transported."; } } From 63c1986f4da238a1a7b0182cb66a3ecbafaa867c Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Mon, 4 Aug 2025 19:34:59 +0200 Subject: [PATCH 018/362] Fix optns labels (#2080) --- MC/config/examples/epos4/generator/example.optns | 2 +- MC/config/examples/epos4/generator/examplehq.optns | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MC/config/examples/epos4/generator/example.optns b/MC/config/examples/epos4/generator/example.optns index 22620815f..015d51a06 100644 --- a/MC/config/examples/epos4/generator/example.optns +++ b/MC/config/examples/epos4/generator/example.optns @@ -1,5 +1,5 @@ !-------------------------------------------------------------------- -! proton-proton collision no hydro no hadronic cascade +! proton-proton collisions with hydro and hadronic cascade !-------------------------------------------------------------------- !--------------------------------------- diff --git a/MC/config/examples/epos4/generator/examplehq.optns b/MC/config/examples/epos4/generator/examplehq.optns index 209f96a55..40afb362a 100755 --- a/MC/config/examples/epos4/generator/examplehq.optns +++ b/MC/config/examples/epos4/generator/examplehq.optns @@ -1,5 +1,5 @@ !-------------------------------------------------------------------- -! proton-proton collision no hydro no hadronic cascade +! proton-proton collisions with hydro and hadronic cascade !-------------------------------------------------------------------- !--------------------------------------- From f189fcbd80f8c2ed2fac44a6ad056601abd59abf Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Tue, 5 Aug 2025 11:09:05 +0200 Subject: [PATCH 019/362] Adaptable QED events based on INTRATE --- MC/bin/o2dpg_sim_workflow.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 7636763c4..435e10263 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -519,7 +519,10 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): # preproduce the collision context / timeframe structure for all timeframes at once precollneeds=[GRP_TASK['name']] -NEventsQED=10000 # max number of QED events to simulate per timeframe +# max number of QED events simulated per timeframe. +# A large pool of QED events (0.6*INTRATE) is needed to avoid repetition of events in the same or +# neighbouring ITS readout frames, which would fire already activated pixel, discarding the event. +NEventsQED = 10000 if (INTRATE <= 16668) else int(INTRATE*0.6) # Hadronic cross section values are taken from Glauber MC XSecSys = {'PbPb': 8., 'OO': 1.273, 'NeNe': 1.736} # QED cross section values were calculated with TEPEMGEN @@ -723,7 +726,6 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): QEDdigiargs = "" if includeQED: - NEventsQED=10000 # 35K for a full timeframe? qedneeds=[GRP_TASK['name'], PreCollContextTask['name']] QED_task=createTask(name='qedsim_'+str(tf), needs=qedneeds, tf=tf, cwd=timeframeworkdir, cpu='1') ######################################################################################################## From 72874248bf0db77fbe5374029e4f1270b8c7640d Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Tue, 5 Aug 2025 14:18:59 +0200 Subject: [PATCH 020/362] Update o2dpg_sim_workflow.py --- MC/bin/o2dpg_sim_workflow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 435e10263..ebc5daa30 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -522,7 +522,8 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): # max number of QED events simulated per timeframe. # A large pool of QED events (0.6*INTRATE) is needed to avoid repetition of events in the same or # neighbouring ITS readout frames, which would fire already activated pixel, discarding the event. -NEventsQED = 10000 if (INTRATE <= 16668) else int(INTRATE*0.6) +# Discussed in detail in https://its.cern.ch/jira/browse/O2-5861 +NEventsQED = max(10000, int(INTRATE*0.6)) # Hadronic cross section values are taken from Glauber MC XSecSys = {'PbPb': 8., 'OO': 1.273, 'NeNe': 1.736} # QED cross section values were calculated with TEPEMGEN From cf85984f46b39bbdadf752650e942bd0616b5eef Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 5 Aug 2025 00:07:00 +0200 Subject: [PATCH 021/362] Improve help message --- MC/bin/o2dpg_sim_workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index ebc5daa30..e64c44031 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -70,7 +70,7 @@ parser.add_argument('-proc',help='process type: inel, dirgamma, jets, ccbar, ...', default='none') parser.add_argument('-trigger',help='event selection: particle, external', default='') parser.add_argument('-ini',help='generator init parameters file (full paths required), for example: ${O2DPG_ROOT}/MC/config/PWGHF/ini/GeneratorHF.ini', default='') -parser.add_argument('-confKey',help='generator or trigger configuration key values, for example: "GeneratorPythia8.config=pythia8.cfg;A.x=y"', default='') +parser.add_argument('-confKey',help='o2sim, generator or trigger configuration key values, for example: "GeneratorPythia8.config=pythia8.cfg;A.x=y"', default='') parser.add_argument('--readoutDets',help='comma separated string of detectors readout (does not modify material budget - only hit creation)', default='all') parser.add_argument('--make-evtpool', help='Generate workflow for event pool creation.', action='store_true') From 1502a4d074f08af2c1411e271e389ecfd9c46ecc Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 5 Aug 2025 00:08:05 +0200 Subject: [PATCH 022/362] AOD conversion: Check if --created-by option is available --- MC/bin/o2dpg_sim_workflow.py | 16 +++++++++++----- MC/bin/o2dpg_workflow_utils.py | 5 +++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index e64c44031..f31211b05 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -234,8 +234,8 @@ def load_external_config(configfile): # We still may need adjust configurations manually for consistency: # # * Force simpler TPC digitization of if TPC reco does not have the mc-time-gain option: -tpc_envfile = 'env_async.env' if environ.get('ALIEN_JDL_O2DPG_ASYNC_RECO_TAG') is not None else None -tpcreco_mctimegain = option_if_available('o2-tpc-reco-workflow', '--tpc-mc-time-gain', envfile=tpc_envfile) +async_envfile = 'env_async.env' if environ.get('ALIEN_JDL_O2DPG_ASYNC_RECO_TAG') is not None else None +tpcreco_mctimegain = option_if_available('o2-tpc-reco-workflow', '--tpc-mc-time-gain', envfile=async_envfile) if tpcreco_mctimegain == '': # this was communicated by Jens Wiechula@TPC; avoids dEdX issue https://its.cern.ch/jira/browse/O2-5486 for the 2tag mechanism print ("TPC reco does not support --tpc-mc-time-gain. Adjusting some config for TPC digitization") @@ -1599,10 +1599,15 @@ def getDigiTaskName(det): aod_creator = f.getvalue().strip() print (f"Determined GRID username {aod_creator}") + # this option might not be universally available + created_by_option = option_if_available('o2-aod-producer-workflow', '--created-by', envfile=async_envfile) + if created_by_option != '': + created_by_option += ' ' + aod_creator + AODtask = createTask(name='aod_'+str(tf), needs=aodneeds, tf=tf, cwd=timeframeworkdir, lab=["AOD"], mem='4000', cpu='1') AODtask['cmd'] = ('','ln -nfs ../bkg_Kine.root . ;')[doembedding] - AODtask['cmd'] += '[ -f AO2D.root ] && rm AO2D.root; ' - AODtask["cmd"] += task_finalizer([ + AODtask['cmd'] += '[ -f AO2D.root ] && rm AO2D.root; ' + AODtask['cmd'] += task_finalizer([ "${O2_ROOT}/bin/o2-aod-producer-workflow", "--reco-mctracks-only 1", "--aod-writer-keep dangling", @@ -1614,13 +1619,14 @@ def getDigiTaskName(det): f"--lpmp-prod-tag {args.productionTag}", "--anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}", "--anchor-prod ${ALIEN_JDL_LPMANCHORPRODUCTION:-unknown}", - f"--created-by {aod_creator}", + created_by_option, "--combine-source-devices" if not args.no_combine_dpl_devices else "", "--disable-mc" if args.no_mc_labels else "", "--enable-truncation 0" if environ.get("O2DPG_AOD_NOTRUNCATE") or environ.get("ALIEN_JDL_O2DPG_AOD_NOTRUNCATE") else "", "--disable-strangeness-tracker" if args.no_strangeness_tracking else "", f"--aod-timeframe-id ${{ALIEN_PROC_ID}}{aod_df_id}" if not args.run_anchored else "", ]) + # Consider in future: AODtask['disable_alternative_reco_software'] = True # do not apply reco software here (we prefer latest aod converter) workflow['stages'].append(AODtask) # diff --git a/MC/bin/o2dpg_workflow_utils.py b/MC/bin/o2dpg_workflow_utils.py index c15d9633b..31860856a 100755 --- a/MC/bin/o2dpg_workflow_utils.py +++ b/MC/bin/o2dpg_workflow_utils.py @@ -315,8 +315,9 @@ def matches_or_inherits_label(taskid, label, cache): for taskid in range(len(workflowspec['stages'])): if (matches_or_inherits_label(taskid, from_stage, matches_label)): # now we do the final adjust (as annotation) in the workflow itself - if workflowspec['stages'][taskid].get("alternative_alienv_package") == None: - workflowspec['stages'][taskid]["alternative_alienv_package"] = package + if workflowspec['stages'][taskid].get('disable_alternative_reco_software', False) != True: + if workflowspec['stages'][taskid].get("alternative_alienv_package") == None: + workflowspec['stages'][taskid]["alternative_alienv_package"] = package def merge_dicts(dict1, dict2): """ From 2d944cc6ac38656a21ca6c89b8003b9d53ae517c Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Tue, 5 Aug 2025 19:22:04 +0200 Subject: [PATCH 023/362] added EPOS4 generator for pp collisions at 13 TeV (#2082) * added EPOS4 generator for pp collisions at 13 TeV * added validation routine --- .../generator/pp_13TeV_hydro_cascade.optns | 32 ++++++++++ .../examples/ini/GeneratorEPOS4_pp13TeV.ini | 11 ++++ .../ini/tests/GeneratorEPOS4_pp13TeV.C | 64 +++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns create mode 100644 MC/config/examples/ini/GeneratorEPOS4_pp13TeV.ini create mode 100644 MC/config/examples/ini/tests/GeneratorEPOS4_pp13TeV.C diff --git a/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns b/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns new file mode 100644 index 000000000..6081a0fa4 --- /dev/null +++ b/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 13 TeV with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13000 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/ini/GeneratorEPOS4_pp13TeV.ini b/MC/config/examples/ini/GeneratorEPOS4_pp13TeV.ini new file mode 100644 index 000000000..3e5080bf1 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4_pp13TeV.ini @@ -0,0 +1,11 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4_pp13TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4_pp13TeV.C new file mode 100644 index 000000000..eac9c321b --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4_pp13TeV.C @@ -0,0 +1,64 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + // check if each event has two protons with 6500 GeV of energy + // exits if the particle is not a proton + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + // Check if track energy is approximately equal to 6500 GeV (a tolerance of 65 keV is considered, straight equality does not work due to floating point precision) + if (std::abs(energy - 6500) < 1e-4) + { + if (track.GetPdgCode() != 2212){ + std::cerr << "Found 6500 GeV particle with pdgID " << track.GetPdgCode() << "\n"; + return 1; + } + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 protons at 6500 GeV\n"; + return 1; + } + } + return 0; +} From 529b92a4701ccd94fd1756b34c27b50a3886437a Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 5 Aug 2025 19:48:33 +0200 Subject: [PATCH 024/362] Allow TPC derivative scaling corrections with CTP --- DATA/production/configurations/asyncReco/setenv_extra.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 2128f9686..fb74d36f3 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -487,6 +487,9 @@ elif [[ $ALIGNLEVEL == 1 ]]; then elif [[ $TPC_SCALING_SOURCE == "CTP" ]]; then echo "CTP Lumi from data will be used for TPC scaling" export TPC_CORR_SCALING+=" --lumi-type 1 " + if [[ $ALIEN_JDL_USEDERIVATIVESFORSCALING == "1" ]]; then + export TPC_CORR_SCALING+=" --corrmap-lumi-mode 1 " + fi elif [[ $TPC_SCALING_SOURCE == "IDCCCDB" ]]; then echo "TPC correction with IDC from CCDB will be used" export TPC_CORR_SCALING+=" --lumi-type 2 " From e0a508a921dda41f7b992b1e99ff2927ea6a3d87 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Thu, 7 Aug 2025 10:02:25 +0200 Subject: [PATCH 025/362] [PWGLF] Add OO cascade-enriched ini file (#2071) * [PWGLF] Add OO cascade-enriched ini file Leverages existing extra-strangeness code and just switches the cfg file to the common OO one. * Increase omega injection to improve efficiency determination for omegas * Add test for OO cascade configuration --- ...neratorLF_Strangeness_OO5360_injection.ini | 6 ++++ ...GeneratorLF_Strangeness_OO5360_injection.C | 28 +++++++++++++++++++ .../generator_pythia8_extraStrangeness.C | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini new file mode 100644 index 000000000..edb6a5626 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C b/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C index c7a57f956..a43612ca5 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C @@ -227,7 +227,7 @@ Double_t boltzPlusPower(const Double_t *x, const Double_t *p) // OMEGA ABUNDANCE FIX //Adjust relative abundance of multi-strange particles by injecting some Double_t lExpectedOmegaToPion = TMath::Max(8.55057e-04 - 7.38732e-04*TMath::Exp(-nChargedParticlesAtMidRap/2.40545e+01) - 6.56785e-05,0.); - Double_t lExpectedOmega = 5.0*nPionsAtMidRap*lExpectedOmegaToPion; // extra rich, factor 5 + Double_t lExpectedOmega = 30.0*nPionsAtMidRap*lExpectedOmegaToPion; // extra rich, factor 30 (omega -> rarer -> smaller Nch bias -> ok to enrich more) Int_t lOmegaYield = gRandom->Poisson(3*lExpectedOmega); //factor 3: fix the rapidity acceptance m = 1.67245; pdg = 3334; From d3ec5a362fb4cf9bd4e7c1b9caec37faa9a798cc Mon Sep 17 00:00:00 2001 From: Michal Broz Date: Sat, 26 Jul 2025 12:04:25 +0200 Subject: [PATCH 026/362] Extra Jpsi decay and Neon setup --- MC/config/PWGUD/external/generator/GeneratorStarlight.C | 1 + MC/config/PWGUD/ini/makeStarlightConfig.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlight.C b/MC/config/PWGUD/external/generator/GeneratorStarlight.C index 9c317ac81..91a6d2776 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlight.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlight.C @@ -119,6 +119,7 @@ class GeneratorStarlight_class : public Generator {"kCohJpsiToEl", 2, 443011, 20, -1.0, -1.0, 443, 0 }, // {"kCohJpsiToElRad", 2, 443011, 20, -1.0, -1.0, 443, 1 }, // {"kCohJpsiToProton", 2, 4432212, 20, -1.0, -1.0, 443, 0 }, // + {"kCohJpsiToLLbar", 2, 4433122, 20, -1.0, -1.0, 443, 0 }, // {"kCohJpsi4Prong", 2, 443013, 20, -1.0, -1.0, 443, 1 }, // {"kCohJpsi6Prong", 2, 443013, 20, -1.0, -1.0, 443, 1 }, // {"kCohPsi2sToMu", 2, 444013, 20, -1.0, -1.0, 100443, 0 }, // diff --git a/MC/config/PWGUD/ini/makeStarlightConfig.py b/MC/config/PWGUD/ini/makeStarlightConfig.py index 48feb7548..cc03d82fd 100755 --- a/MC/config/PWGUD/ini/makeStarlightConfig.py +++ b/MC/config/PWGUD/ini/makeStarlightConfig.py @@ -8,7 +8,7 @@ parser = argparse.ArgumentParser(description='Make Starlight configuration', formatter_class=argparse.ArgumentDefaultsHelpFormatter) -parser.add_argument('--collType',default='PbPb', choices=['PbPb', 'pPb', 'Pbp', 'pp', 'OO', 'pO', 'Op'], +parser.add_argument('--collType',default='PbPb', choices=['PbPb', 'pPb', 'Pbp', 'pp', 'OO', 'pO', 'Op', 'NeNe'], help='Colission system') parser.add_argument('--eCM', type=float, default='5360', @@ -74,6 +74,11 @@ pA = 16 tZ = 1 tA = 1 +if 'NeNe' in args.collType: + pZ = 10 + pA = 20 + tZ = 10 + tA = 20 ### open output file fout = open(args.output, 'w') From 5367c37fa2a019c72e687f03efcefcb80a757db8 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 5 Aug 2025 15:38:52 +0200 Subject: [PATCH 027/362] Improvements for grid_submit * ability to just wait for any succeeding job in a split * some cleanup/renaming --- GRID/utils/grid_submit.sh | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/GRID/utils/grid_submit.sh b/GRID/utils/grid_submit.sh index 7dddd5e80..b3d6372d2 100755 --- a/GRID/utils/grid_submit.sh +++ b/GRID/utils/grid_submit.sh @@ -216,6 +216,7 @@ while [ $# -gt 0 ] ; do --prodsplit) PRODSPLIT=$2; shift 2 ;; # allows to set JDL production split level (useful to easily replicate workflows) --singularity) SINGULARITY=ON; shift 1 ;; # run everything inside singularity --wait) WAITFORALIEN=ON; shift 1 ;; #wait for alien jobs to finish + --wait-any) WAITFORALIENANY=ON; WAITFORALIEN=ON; shift 1 ;; #wait for any good==done alien jobs to return --outputspec) OUTPUTSPEC=$2; shift 2 ;; #provide comma separate list of JDL file specs to be put as part of JDL Output field (example '"*.log@disk=1","*.root@disk=2"') -h) Usage ; exit ;; --help) Usage ; exit ;; @@ -227,6 +228,7 @@ export JOBTTL export JOBLABEL export MATTERMOSTHOOK export CONTROLSERVER + [[ $PRODSPLIT -gt 100 ]] && echo "Production split needs to be smaller than 100 for the moment" && exit 1 # check for presence of jq (needed in code path to fetch output files) @@ -270,9 +272,10 @@ pok "Set the job name by running $0 " # Generate local workdir # if [[ "${ONGRID}" == "0" ]]; then - WORKDIR=${WORKDIR:-/tmp/alien_work/$(basename "$MY_JOBWORKDIR")} - [ ! -d "${WORKDIR}" ] && mkdir -p ${WORKDIR} - [ ! "${CONTINUE_WORKDIR}" ] && cp "${MY_JOBSCRIPT}" "${WORKDIR}/alien_jobscript.sh" + GRID_SUBMIT_WORKDIR=${GRID_SUBMIT_WORKDIR:-/tmp/alien_work/$(basename "$MY_JOBWORKDIR")} + echo "WORKDIR FOR THIS JOB IS ${GRID_SUBMIT_WORKDIR}" + [ ! -d "${GRID_SUBMIT_WORKDIR}" ] && mkdir -p ${GRID_SUBMIT_WORKDIR} + [ ! "${CONTINUE_WORKDIR}" ] && cp "${MY_JOBSCRIPT}" "${GRID_SUBMIT_WORKDIR}/alien_jobscript.sh" fi # @@ -349,7 +352,7 @@ if [[ "${IS_ALIEN_JOB_SUBMITTER}" ]]; then cd "$(dirname "$0")" THIS_SCRIPT="$PWD/$(basename "$0")" - cd "${WORKDIR}" + cd "${GRID_SUBMIT_WORKDIR}" QUOT='"' # ---- Generate JDL ---------------- @@ -436,11 +439,18 @@ EOF continue fi let counter=0 # reset counter - JOBSTATUS=$(alien.py ps -j ${MY_JOBID} | awk '//{print $3}') - # echo -ne "Waiting for jobs to return; Last status ${JOBSTATUS}" + + # this is the global job status (a D here means the production is done) + JOBSTATUS=$(alien.py ps -j ${MY_JOBID} | awk '//{print $3}') # this is the global job status + # in addition we may query individual splits + if [ "${WAITFORANY}" ]; then + if ALIENPY_JSON=true alien.py ps -a -m "${MY_JOBID}" | grep "status" | grep -q "DONE"; then + JOBSTATUS="D" # a D here means == some job finished successfully + fi + fi if [ "${JOBSTATUS}" == "D" ]; then - echo "Job done" + echo "${WAITFORALIENANY:+At least one }Job(s) done" WAITFORALIEN="" # guarantees to go out of outer while loop if [ "${FETCHOUTPUT}" ]; then @@ -473,10 +483,6 @@ EOF done fi fi - if [[ "${FOO:0:1}" == [EK] ]]; then - echo "Job error occured" - exit 1 - fi done # get the job data products locally if requested @@ -490,7 +496,7 @@ if [[ ${SINGULARITY} ]]; then # if singularity was asked we restart this script within a container # it's actually much like the GRID mode --> which is why we set JALIEN_TOKEN_CERT set -x - cp $0 ${WORKDIR} + cp $0 ${GRID_SUBMIT_WORKDIR} # detect architecture (ARM or X86) ARCH=$(uname -i) @@ -508,15 +514,15 @@ if [[ ${SINGULARITY} ]]; then APPTAINER_EXEC="/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer" # we can actually analyse the local JDL to find the package and set it up for the container - ${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${WORKDIR}:/workdir --pwd /workdir -C ${CONTAINER} /workdir/grid_submit.sh \ + ${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${GRID_SUBMIT_WORKDIR}:/workdir --pwd /workdir -C ${CONTAINER} /workdir/grid_submit.sh \ ${CONTINUE_WORKDIR:+"-c ${CONTINUE_WORKDIR}"} --local ${O2TAG:+--o2tag ${O2TAG}} --ttl ${JOBTTL} --label ${JOBLABEL:-label} ${MATTERMOSTHOOK:+--mattermost ${MATTERMOSTHOOK}} ${CONTROLSERVER:+--controlserver ${CONTROLSERVER}} set +x exit $? fi if [[ "${ONGRID}" == 0 ]]; then - banner "Executing job in directory ${WORKDIR}" - cd "${WORKDIR}" 2> /dev/null + banner "Executing job in directory ${GRID_SUBMIT_WORKDIR}" + cd "${GRID_SUBMIT_WORKDIR}" 2> /dev/null fi exec &> >(tee -a alien_log_${ALIEN_PROC_ID:-0}.txt) From e0cf052648af450f40924a36a5ac81d9aa521056 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 19 Mar 2025 16:43:28 +0100 Subject: [PATCH 028/362] Setup to test anchorMC in the 2tag approach Provides * Template file to generate anchored MC jobs * A driver script creating actual test jobs and executing them on the GRID * CSV data file specifying which software tags should be tested The idea is that this should be used to check if MC (daily) releases are compatible with the 2tag approach relative to a given set of async software releases. --- .../ANCHOR/tests/test_anchor_2tag_template.sh | 57 +++++++ MC/run/ANCHOR/tests/test_anchor_cases.csv | 22 +++ MC/run/ANCHOR/tests/test_looper.sh | 142 ++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 MC/run/ANCHOR/tests/test_anchor_2tag_template.sh create mode 100644 MC/run/ANCHOR/tests/test_anchor_cases.csv create mode 100755 MC/run/ANCHOR/tests/test_looper.sh diff --git a/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh new file mode 100644 index 000000000..f97e7f233 --- /dev/null +++ b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh @@ -0,0 +1,57 @@ +#!/bin/bash +#JDL_OUTPUT=*.txt@disk=1,AO2D.root@disk=2,*.log@disk=1,*stat*@disk=1,*.json@disk=1,debug*tgz@disk=2 +#JDL_ERROROUTPUT=*.txt@disk=1,AO2D.root@disk=2,*.log@disk=1,*.json@disk=1,debug*tgz@disk=2 +#JDL_PACKAGE=%{SOFTWARETAG_SIM} +#JDL_REQUIRE=%{JDL_REQUIREMENT} + +# +# A template anchoring script to test various anchoring setups +# and software combinations +# + +# only relevant if executed locally +if [ ! ${O2_ROOT} ]; then + source <(/cvmfs/alice.cern.ch/bin/alienv printenv %{SOFTWARETAG_SIM}) +fi + +# meta configuration of the job (influences reco config) +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_CPULIMIT=8 + +export ALIEN_JDL_LPMANCHORPASSNAME=%{PASSNAME} +export ALIEN_JDL_MCANCHOR=%{PASSNAME} +export ALIEN_JDL_COLLISIONSYSTEM=%{COL_SYSTEM} +export ALIEN_JDL_LPMPASSNAME=%{PASSNAME} +export ALIEN_JDL_LPMRUNNUMBER=%{RUN_NUMBER} +export ALIEN_JDL_LPMANCHORRUN=%{RUN_NUMBER} + +export ALIEN_JDL_LPMINTERACTIONTYPE=%{INTERACTIONTYPE} +export ALIEN_JDL_LPMPRODUCTIONTAG=%{PRODUCTION_TAG} +export ALIEN_JDL_LPMANCHORPRODUCTION=%{ANCHOR_PRODUCTION} +export ALIEN_JDL_LPMANCHORYEAR=%{ANCHORYEAR} +export ALIEN_JDL_O2DPG_ASYNC_RECO_TAG="%{SOFTWARETAG_ASYNC}" + +# get custom O2DPG for 2tag treatment (could be used to test different O2DPG branches) +# git clone https://github.com/AliceO2Group/O2DPG O2DPG +# export O2DPG_ROOT=${PWD}/O2DPG +# export ALIEN_JDL_O2DPG_OVERWRITE=${PWD}/O2DPG + +# dimension the job +export NTIMEFRAMES=1 + +# further configuration of the job +export ALIEN_JDL_ADDTIMESERIESINMC=0 +export DISABLE_QC=1 +export ALIEN_JDL_MC_ORBITS_PER_TF=10000:10000000:2 # puts just 2 orbit for large enough interaction rates +export ALIEN_JDL_O2DPGWORKFLOWTARGET="aod" + +# select anchoring points +export PRODSPLIT=${ALIEN_O2DPG_GRIDSUBMIT_PRODSPLIT:-100} +export SPLITID=${ALIEN_O2DPG_GRIDSUBMIT_SUBJOBID:-50} +export CYCLE=0 + +# generator and other sim configuration +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="%{SIM_OPTIONS}" + +# execute MC +# ${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/ANCHOR/tests/test_anchor_cases.csv b/MC/run/ANCHOR/tests/test_anchor_cases.csv new file mode 100644 index 000000000..490b7bba5 --- /dev/null +++ b/MC/run/ANCHOR/tests/test_anchor_cases.csv @@ -0,0 +1,22 @@ +# comment (no empty lines allowed) +%{SOFTWARETAG_SIM},%{SOFTWARETAG_ASYNC},%{PASSNAME},%{COL_SYSTEM},%{RUN_NUMBER},%{INTERACTIONTYPE},%{ANCHOR_PRODUCTION},%{ANCHORYEAR},%{SIM_OPTIONS},%{PRODUCTION_TAG} +#O2sim::v20250306-1,O2PDPSuite::async-async-v1-01-08-slc9-alidist-async-v1-01-01-1,apass7,p-p,526641,pp,LHC25a9_Plus10,LHC22o,2022,-gen pythia8 +#O2sim::v20250305-1,O2PDPSuite::async-async-v1-01-12-slc9-alidist-async-v1-01-01-1,apass1,p-p,551398,pp,LHC25a7_Plus10,LHC24ag,2024,-gen pythia8 +#O2sim::v20250305-1,O2PDPSuite::async-async-v1-02-10-slc9-alidist-async-v1-02-01-1,apass1,Pb-Pb,559544,PbPb,LHC25c5b,LHC24ar,2024,-gen pythia8 -confKey 'SimCutParams.globalDensityFactor=0.9f' +#O2sim::v20250806-1,O2PDPSuite::async-async-2024-PbPb-apass1-v2-slc9-alidist-async-2024-PbPb-apass1-v2-1,apass1,Pb-Pb,559544,PbPb,LHC25c5b,LHC24ar,2024,-gen pythia8 +# 2022 +# O2PDPSuite::async-async-2022-pp-apass7-v1,apass7, | 526641 +# 2023 +O2sim::v20250806-1,O2PDPSuite::async-async-2023-PbPb-apass5-v5-slc9-alidist-async-2023-PbPb-apass5-v5-1,apass5,Pb-Pb,544091,PbPb,LHC23zzh,2023,-gen pythia8 +# 2024 +O2sim::v20250806-1,O2PDPSuite::async-async-2024-pp-apass1-v7-slc9-alidist-async-2024-pp-apass1-v7-1,apass1,p-p,553185,pp,LHC24al,2024,-gen pythia8 +O2sim::v20250806-1,O2PDPSuite::async-async-2024-ppRef-apass1-v1-slc9-alidist-async-2024-ppRef-apass1-v1-1,apass1,p-p,559348,pp,LHC24ap,2024,-gen pythia8 +O2sim::v20250806-1,O2PDPSuite::async-async-2024-pbpb-apass2-v3-slc9-alidist-async-2024-pbpb-apass2-v3-1,apass2,Pb-Pb,559545,PbPb,LHC24ar,2024,-gen pythia8 +# 2025 +O2sim::v20250806-1,O2PDPSuite::async-async-2025-pO-apass1-v2-slc9-alidist-async-2025-pO-apass1-v2-1,apass1,p-O,564251,pO,LHC25ad,2025,-gen pythia8 +O2sim::v20250806-1,O2PDPSuite::async-async-2025-OO-apass1-v2-slc9-alidist-async-2025-OO-apass1-v2-1,apass1,O-O,564356,OO,LHC25ae,2025,-gen pythia8 +O2sim::v20250806-1,O2PDPSuite::async-async-2025-NeNe-apass1-v2-slc9-alidist-async-2025-NeNe-apass1-v2-1,apass1,Ne-Ne,564468,NeNe,LHC25af,2025,-gen pythia8 +# apass2 +O2sim::v20250806-1,O2PDPSuite::async-async-2025-pO-apass2-v1-slc9-alidist-async-2025-pO-apass2-v1-1,apass2,p-O,564251,pO,LHC25ad,2025,-gen pythia8 +O2sim::v20250806-1,O2PDPSuite::async-async-2025-OO-apass2-v1-slc9-alidist-async-2025-OO-apass2-v1-1,apass2,O-O,564356,OO,LHC25ae,2025,-gen pythia8 +O2sim::v20250806-1,O2PDPSuite::async-async-2025-NeNe-apass2-v1-slc9-alidist-async-2025-NeNe-apass2-v1-1,apass2,Ne-Ne,564468,NeNe,LHC25af,2025,-gen pythia8 \ No newline at end of file diff --git a/MC/run/ANCHOR/tests/test_looper.sh b/MC/run/ANCHOR/tests/test_looper.sh new file mode 100755 index 000000000..7a243746b --- /dev/null +++ b/MC/run/ANCHOR/tests/test_looper.sh @@ -0,0 +1,142 @@ +#!/bin/bash +# loops over all test cases and executes them + +# Read the CSV file +INPUT_FILE="test_anchor_cases.csv" +TEMPLATE_FILE="test_anchor_2tag_template.sh" +OUTPUT_FILE="test_anchor_generated" + +DAILYTAGTOTEST=${1:-O2sim::v20250804-1} + +SITES_FILE="test_GRID_sites.dat" + +WORKING_DIR="${PWD}/workdir_$(date +%s)_$RANDOM" +echo "WORKING DIR ${WORKING_DIR}" +mkdir -p ${WORKING_DIR} + +INPUT_FILE_STRIPPED=${WORKING_DIR}/${INPUT_FILE}_clean + +REQUIRE_STRING="" +{ + while read -r -a values; do + if [ ! "${REQUIRE_STRING}" == "" ]; then + REQUIRE_STRING="${REQUIRE_STRING} ||" + fi + REQUIRE_STRING="${REQUIRE_STRING} (other.CE == \"${values}\")" + done +} < ${SITES_FILE} +REQUIRE_STRING="(${REQUIRE_STRING});" + +echo "REQUIRE STRING ${REQUIRE_STRING}" + +# strip comments from CSV file +grep -v '#' ${INPUT_FILE} > ${INPUT_FILE_STRIPPED} + +# Read the header line and convert it into variable names +IFS=',' read -r -a headers < "$INPUT_FILE_STRIPPED" + +# Replace placeholders in the header (e.g., %{VAR} → VAR) +for i in "${!headers[@]}"; do + headers[$i]=$(echo "${headers[$i]}" | sed -E 's/#?%\{//;s/\}//g') +done + +# Read and process each subsequent line +{ + read # Skip the header line + + count=1 # Counter for output files + datestring=$(date +"%Y%m%d_%H%M%S") + while IFS=',' read -r -a values; do + # Assign each value to its corresponding variable + for i in "${!headers[@]}"; do + declare "${headers[$i]}"="${values[$i]}" + done + + PRODUCTION_TAG="2tagtest_${datestring}_${count}" + # Example: Print assigned variables + echo "SOFTWARETAG_SIM: $SOFTWARETAG_SIM" + echo "SOFTWARETAG_ASYNC: $SOFTWARETAG_ASYNC" + echo "PASSNAME: $PASSNAME" + echo "COL_SYSTEM: $COL_SYSTEM" + echo "RUN_NUMBER: $RUN_NUMBER" + echo "INTERACTIONTYPE: $INTERACTIONTYPE" + echo "PRODUCTION_TAG: $PRODUCTION_TAG" + echo "ANCHOR_PRODUCTION: $ANCHOR_PRODUCTION" + echo "ANCHORYEAR: $ANCHORYEAR" + echo "SIM_OPTIONS: $SIM_OPTIONS" + echo "--------------------------------" + + if [ "${DAILYTAGTOTEST}" ]; then + SOFTWARETAG_SIM=${DAILYTAGTOTEST} + fi + + OUTPUT_FILE_FINAL="${WORKING_DIR}/${OUTPUT_FILE}_case${count}.sh" + + # create final test script with these values + cp "$TEMPLATE_FILE" "${OUTPUT_FILE_FINAL}" + for var in "${headers[@]}"; do + sed -i "s|%{$var}|${!var}|g" "$OUTPUT_FILE_FINAL" + done + # put the require spec + sed -i "s/%{JDL_REQUIREMENT}/${REQUIRE_STRING}/g" "$OUTPUT_FILE_FINAL" + + # we submit the test to the GRID (multiplicity of 4) + # ${WORKING_DIR}/submit_case${count}_${SOFTWARETAG_ASYNC//::/-} + echo "${O2DPG_ROOT}/GRID/utils/grid_submit.sh --prodsplit 4 --singularity --ttl 3600 --script ${OUTPUT_FILE_FINAL} --jobname "anchorTest_${count}" --wait-any --topworkdir 2tag_release_testing_${SOFTWARETAG_SIM}" > ${WORKING_DIR}/submit_case${count}.sh + # TODO: optional local execution with --local option + + ((count++)) # Increment counter for next row + done +} < "${INPUT_FILE_STRIPPED}" #Redirect file input here to avoid subshell issues + +cd ${WORKING_DIR} + +# now we submit all the jobs in the background and wait for them to return +for s in `ls submit*.sh`; do + echo "submitting ${s}" + export GRID_SUBMIT_WORKDIR="${WORKING_DIR}/${s}_workdir" + ( + bash ${s} &> log_${s} + echo "Job ${s} returned" + ) & +done + +# for for all (GRID) jobs to return +echo "Waiting for jobs to return/finish" +wait + +# verify / validate the output produced from these jobs +# The test is successfull if at least one subjob from each test +# produced the AO2D output. +echo "-- Jobs done ... validating --" + +FINAL_SUCCESS=0 +for s in `ls submit*.sh`; do + # find output path + TEST_OUTPUT_PATH="${WORKING_DIR}/${s}_workdir" # $(grep "Local working directory is" log_${s} | awk '//{print $5}') + + # get the Output path on JAlien from the JDL + ALIEN_OUTPUT_FOLDER=$(grep 'OutputDir' ${TEST_OUTPUT_PATH}/*.jdl | cut -d'"' -f2 | sed 's|/[^/]*#.*#.*$||') + + # see if there is an AO2D.root and a workflow.json in one of the jobs in that folder + AODS_FOUND=$(alien.py find ${ALIEN_OUTPUT_FOLDER} AO2D.root) + WORKFLOWS_FOUND=$(alien.py find ${ALIEN_OUTPUT_FOLDER} workflow.json) + + if [[ -z ${WORKFLOWS_FOUND} || -z ${AODS_FOUND} ]]; then + echo "❌ Missing files for case $s" + FINAL_SUCCESS=1 # mark as failure + else + echo "✅ Files found in $s" + fi +done + +if [[ ${FINAL_SUCCESS} -eq 0 ]]; then + echo "✅ All submissions have required files." +else + echo "❌ Some submissions are missing required files." +fi + +#TODO: echo "-- Cleaning up ... " +cd .. + +exit ${FINAL_SUCCESS} \ No newline at end of file From 1b06695bb6e5db83fa751155c51e74a7801ff5c4 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 5 Aug 2025 20:27:58 +0200 Subject: [PATCH 029/362] commit missing file --- MC/run/ANCHOR/tests/test_GRID_sites.dat | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 MC/run/ANCHOR/tests/test_GRID_sites.dat diff --git a/MC/run/ANCHOR/tests/test_GRID_sites.dat b/MC/run/ANCHOR/tests/test_GRID_sites.dat new file mode 100644 index 000000000..3d1e1042e --- /dev/null +++ b/MC/run/ANCHOR/tests/test_GRID_sites.dat @@ -0,0 +1,27 @@ +ALICE::DCSC_KU::ARC 1:40 +ALICE::IHEP_CN::LCG 1:49 +ALICE::HIP::SLURM 2:03 +ALICE::CNAF::CNAF-DUE 2:19 +ALICE::NIKHEF::LCG 2:19 +ALICE::Poznan::ARC 2:30 +ALICE::CNAF::LCG 2:33 +ALICE::SARA::LCG 2:48 +ALICE::LBL_HPCS::HPCS_Lr 2:59 +ALICE::CCIN2P3::HTC 3:09 +ALICE::Trieste::Trieste 3:10 +ALICE::Prague::LCG 3:14 +ALICE::Torino::Torino-HTC 3:25 +ALICE::CCIN2P3::HTC_2 3:26 +ALICE::JINR::ARC 3:28 +ALICE::LBL::Perlmutter 3:29 +ALICE::Birmingham::LCG 3:30 +ALICE::RAL::LCG 3:34 +ALICE::Vienna::LCG 3:34 +ALICE::GRIF_IPNO::IJCLAB 3:35 +ALICE::Legnaro::HTC 3:37 +ALICE::LBL_HPCS::HPCS 3:38 +ALICE::Kolkata::LCG 3:44 +ALICE::Bari::HTC 3:46 +ALICE::CERN::CERN-SIRIUS 3:49 +ALICE::FZK::HTC 3:52 +ALICE::CERN::CERN-CORONA 3:55 \ No newline at end of file From 1a30c42b05fb92dfbfdfce5a82166035f2ab5132 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 5 Aug 2025 20:57:09 +0200 Subject: [PATCH 030/362] typo fix --- MC/run/ANCHOR/tests/test_anchor_2tag_template.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh index f97e7f233..0f984bd2f 100644 --- a/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh +++ b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh @@ -54,4 +54,4 @@ export CYCLE=0 export ALIEN_JDL_ANCHOR_SIM_OPTIONS="%{SIM_OPTIONS}" # execute MC -# ${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh From e03a51388c6ba35c3485222c6f8858099ca48e38 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 6 Aug 2025 20:04:37 +0200 Subject: [PATCH 031/362] Allow TPC residual extraction in MC and data corr maps in the reco Apply ccdb remapping if ALIEN_JDL_REMAPPINGS is defined --- MC/bin/o2dpg_sim_workflow.py | 85 +++++++++++++++++++++++++++++++----- MC/run/ANCHOR/anchorMC.sh | 5 +++ 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index f31211b05..d7f0265b6 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -153,6 +153,7 @@ # TPC options parser.add_argument('--tpc-distortion-type', default=0, type=int, help='Simulate distortions in the TPC (0=no distortions, 1=distortions without scaling, 2=distortions with CTP scaling)') +parser.add_argument('--tpc-corrmap-lumi-mode', default=2, type=int, help='TPC corrections mode (0=linear, 1=derivative, 2=derivative for special MC maps') parser.add_argument('--ctp-scaler', default=0, type=float, help='CTP raw scaler value used for distortion simulation') # Global Forward reconstruction configuration parser.add_argument('--fwdmatching-assessment-full', action='store_true', help='enables complete assessment of global forward reco') @@ -472,28 +473,32 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): workflow['stages'].append(globalinittask) #### +usebkgcache=args.use_bkg_from!=None +includeFullQC=args.include_qc=='True' or args.include_qc==True +includeLocalQC=args.include_local_qc=='True' or args.include_local_qc==True +includeAnalysis = args.include_analysis +includeTPCResiduals=True if environ.get('ALIEN_JDL_DOTPCRESIDUALEXTRACTION') == '1' else False +ccdbRemap = environ.get('ALIEN_JDL_REMAPPINGS') + +qcdir = "QC" +if (includeLocalQC or includeFullQC) and not isdir(qcdir): + mkdir(qcdir) + def getDPL_global_options(bigshm=False, ccdbbackend=True): common=" -b --run " if len(args.dpl_child_driver) > 0: common=common + ' --child-driver ' + str(args.dpl_child_driver) if ccdbbackend: common=common + " --condition-not-after " + str(args.condition_not_after) + if ccdbRemap != None: + common=common + " --condition-remap " + ccdbRemap if args.noIPC!=None: return common + " --no-IPC " if bigshm: return common + " --shm-segment-size ${SHMSIZE:-50000000000} " else: return common - -usebkgcache=args.use_bkg_from!=None -includeFullQC=args.include_qc=='True' or args.include_qc==True -includeLocalQC=args.include_local_qc=='True' or args.include_local_qc==True -includeAnalysis = args.include_analysis - -qcdir = "QC" -if (includeLocalQC or includeFullQC) and not isdir(qcdir): - mkdir(qcdir) - + # create/publish the GRPs and other GLO objects for consistent use further down the pipeline orbitsPerTF=int(args.orbitsPerTF) GRP_TASK = createTask(name='grpcreate', cpu='0') @@ -1170,17 +1175,19 @@ def getDigiTaskName(det): # in case of PbPb the conversion factor ZDC ->FT0 (pp) must be set tpc_corr_options_mc='' + tpcCorrmapLumiMode = args.tpc_corrmap_lumi_mode + if tpcDistortionType == 0: # disable distortion corrections tpc_corr_options_mc=' --corrmap-lumi-mode 0 ' tpcLocalCFreco['TPCCorrMap.lumiMean'] = '-1'; elif tpcDistortionType == 1: # disable scaling - tpc_corr_options_mc=' --corrmap-lumi-mode 2 ' + tpc_corr_options_mc=' --corrmap-lumi-mode ' + str(tpcCorrmapLumiMode) + ' ' tpcLocalCFreco['TPCCorrMap.lumiInst'] = str(CTPSCALER) tpcLocalCFreco['TPCCorrMap.lumiMean'] = str(CTPSCALER) elif tpcDistortionType == 2: # full scaling with CTP values if COLTYPE == 'PbPb': tpcLocalCFreco['TPCCorrMap.lumiInstFactor'] = str(lumiInstFactor) - tpc_corr_options_mc=' --corrmap-lumi-mode 2 ' + tpc_corr_options_mc=' --corrmap-lumi-mode ' + str(tpcCorrmapLumiMode) + ' ' tpcLocalCFreco['TPCCorrMap.lumiInst'] = str(CTPSCALER) # Setup the TPC correction scaling options for reco; They come from the anchoring setup @@ -1629,6 +1636,60 @@ def getDigiTaskName(det): # Consider in future: AODtask['disable_alternative_reco_software'] = True # do not apply reco software here (we prefer latest aod converter) workflow['stages'].append(AODtask) + if includeTPCResiduals: + print ("Adding TPC residuals extraction and aggregation") + + #<------------- TPC residuals extraction + scdcalib_vertex_sources = dpl_option_from_config(anchorConfig, + 'o2-tpc-scdcalib-interpolation-workflow', + 'vtx-sources', + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') + + scdcalib_track_sources = dpl_option_from_config(anchorConfig, + 'o2-tpc-scdcalib-interpolation-workflow', + 'tracking-sources', + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') + + scdcalib_track_extraction = dpl_option_from_config(anchorConfig, + 'o2-tpc-scdcalib-interpolation-workflow', + 'tracking-sources-map-extraction', + default_value='ITS-TPC') + + SCDCALIBtask = createTask(name='scdcalib_'+str(tf), needs=[PVFINDERtask['name']], tf=tf, cwd=timeframeworkdir, lab=["CALIB"], mem='4000') + SCDCALIBtask['cmd'] = task_finalizer( + [ '${O2_ROOT}/bin/o2-tpc-scdcalib-interpolation-workflow', + getDPL_global_options(bigshm=True), + putConfigValues(['scdcalib']), + '--vtx-sources ' + scdcalib_vertex_sources, + '--tracking-sources ' + scdcalib_track_sources, + '--tracking-sources-map-extraction ' + scdcalib_track_extraction, + '--sec-per-slot 1 ', + '--send-track-data' + ]) + workflow['stages'].append(SCDCALIBtask) + + #<------------- TPC residuals aggregator + scdaggreg_secperslot = dpl_option_from_config(anchorConfig, + 'o2-calibration-residual-aggregator', + 'sec-per-slot', + default_value='600') + scdaggreg_outputtype = dpl_option_from_config(anchorConfig, + 'o2-calibration-residual-aggregator', + 'output-type', + default_value='trackParams,unbinnedResid') + + SCDAGGREGtask = createTask(name='scdaggreg_'+str(tf), needs=[SCDCALIBtask['name']], tf=tf, cwd=timeframeworkdir, lab=["CALIB"], mem='1500') + SCDAGGREGtask['cmd'] = task_finalizer( + [ '${O2_ROOT}/bin/o2-calibration-residual-aggregator', + getDPL_global_options(bigshm=True), + '--sec-per-slot ' + scdaggreg_secperslot, + '--enable-ctp ', + '--output-dir ./', + '--output-type ' + scdaggreg_outputtype + ]) + workflow['stages'].append(SCDAGGREGtask) + + # conditional # # QC tasks follow # diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index ba1794c7b..63f39c13e 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -393,6 +393,11 @@ if [[ "${MCRC}" == "0" && "${ALIEN_JDL_ADDTIMESERIESINMC}" != "0" ]]; then # Note: We could maybe avoid this if-else by including `tpctimes` directly in the workflow-targets above fi +if [[ "${MCRC}" == "0" && "${ALIEN_JDL_DOTPCRESIDUALEXTRACTION}" = "1" ]]; then + echo_info "Running TPC residuals extraction and aggregation" + ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt scdaggreg +fi + [[ -n "${DISABLE_QC}" ]] && echo_info "QC is disabled, skip it." if [[ -z "${DISABLE_QC}" && "${MCRC}" == "0" && "${remainingargs}" == *"--include-local-qc"* ]] ; then From db61c442c7ce1f13817b951ad98cf3bc77d17ea8 Mon Sep 17 00:00:00 2001 From: Michal Broz Date: Fri, 8 Aug 2025 09:03:00 +0200 Subject: [PATCH 032/362] Extra process in the script --- MC/config/PWGUD/ini/makeStarlightConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGUD/ini/makeStarlightConfig.py b/MC/config/PWGUD/ini/makeStarlightConfig.py index cc03d82fd..cd68ac8a5 100755 --- a/MC/config/PWGUD/ini/makeStarlightConfig.py +++ b/MC/config/PWGUD/ini/makeStarlightConfig.py @@ -17,7 +17,7 @@ parser.add_argument('--rapidity', default='cent', choices=['cent_rap', 'muon_rap', 'cent_eta', 'muon_eta'], help='Rapidity to select') -parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToEl3Pi', 'kTauLowToPo3Pi', 'kTauMediumToEl3Pi', 'kTauMediumToPo3Pi', 'kTauHighToEl3Pi', 'kTauHighToPo3Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], +parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsiToLLbar', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToEl3Pi', 'kTauLowToPo3Pi', 'kTauMediumToEl3Pi', 'kTauMediumToPo3Pi', 'kTauHighToEl3Pi', 'kTauHighToPo3Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], help='Process to switch on') From 889a725149ab4d9c4d65817ae06f84f1d7678a00 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 8 Aug 2025 14:23:45 +0200 Subject: [PATCH 033/362] Add TPC residuals merging stage for tfs of a job --- MC/bin/o2dpg_sim_workflow.py | 8 ++++++++ MC/run/ANCHOR/anchorMC.sh | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index d7f0265b6..1160dbf87 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1971,6 +1971,14 @@ def remove_json_prefix(path): POOL_merge_task['cmd'] += '; RC=$?; root -l -q -b -e "auto f=TFile::Open(\\\"evtpool.root\\\"); auto t=(TTree*)f->Get(\\\"o2sim\\\"); int n=t->GetEntries(); std::ofstream((\\\"0_0_0_\\\"+std::to_string(n)+\\\".stat\\\").c_str()) << \\\"# MonaLisa stat file for event pools\\\";" ; [[ ${RC} == 0 ]]' workflow['stages'].append(POOL_merge_task) +# if TPC residuals extraction was requested, we have to merge per-tf trees +tpcResidMergingNeeds = ['scdaggreg_' + str(tf) for tf in range(1, NTIMEFRAMES + 1)] +TPCResid_merge_task = createTask(name='tpcresidmerge', needs = tpcResidMergingNeeds, lab=["CALIB"], mem='2000', cpu='1') +TPCResid_merge_task['cmd'] = ' set -e ; [ -f tpcresidmerge_input.txt ] && rm tpcresidmerge_input.txt; ' +TPCResid_merge_task['cmd'] += ' for i in `seq 1 ' + str(NTIMEFRAMES) + '`; do find tf${i} -name "o2tpc_residuals_*.root" >> tpcresidmerge_input.txt; done; ' +TPCResid_merge_task['cmd'] += '${O2DPG_ROOT}/UTILS/root_merger.py -o o2tpc_residuals.root -i $(grep -v \"^$\" tpcresidmerge_input.txt | paste -sd, -)' +workflow['stages'].append(TPCResid_merge_task) + # adjust for alternate (RECO) software environments adjust_RECO_environment(workflow, args.alternative_reco_software) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 63f39c13e..7e14faabe 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -394,8 +394,8 @@ if [[ "${MCRC}" == "0" && "${ALIEN_JDL_ADDTIMESERIESINMC}" != "0" ]]; then fi if [[ "${MCRC}" == "0" && "${ALIEN_JDL_DOTPCRESIDUALEXTRACTION}" = "1" ]]; then - echo_info "Running TPC residuals extraction and aggregation" - ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt scdaggreg + echo_info "Running TPC residuals extraction, aggregation and merging" + ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt tpcresidmerge fi [[ -n "${DISABLE_QC}" ]] && echo_info "QC is disabled, skip it." From 6e3720e21b7ec21dba34dff1e941706dfb004803 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 11 Aug 2025 02:06:38 +0200 Subject: [PATCH 034/362] Store CTP lumi in CTP digits in anchored sim. --- MC/bin/o2dpg_sim_workflow.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 1160dbf87..3369ef881 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1101,7 +1101,7 @@ def createRestDigiTask(name, det='ALLSMALLER'): det_to_digitask[det]=t # detectors serving CTP need to be treated somewhat special since CTP needs - # these inputs at the same time --> still need to be made better + # these inputs at the same time --> still need to be made better. tneeds = [ContextTask['name']] if includeQED: tneeds += [QED_task['name']] @@ -1116,6 +1116,7 @@ def createRestDigiTask(name, det='ALLSMALLER'): '--onlyDet FT0,FV0,EMC,CTP', f'--interactionRate {INTRATE}', f'--incontext {CONTEXTFILE}', + f'--store-ctp-lumi {CTPSCALER}', '--disable-write-ini', putConfigValues(listOfMainKeys=['EMCSimParam','FV0DigParam','FT0DigParam'], localCF={"DigiParams.seed" : str(TFSEED)}), ('--combine-devices','')[args.no_combine_dpl_devices], @@ -1684,8 +1685,10 @@ def getDigiTaskName(det): getDPL_global_options(bigshm=True), '--sec-per-slot ' + scdaggreg_secperslot, '--enable-ctp ', + '--enable-track-input', '--output-dir ./', - '--output-type ' + scdaggreg_outputtype + '--output-type ' + scdaggreg_outputtype, + '--meta-output-dir /dev/null' ]) workflow['stages'].append(SCDAGGREGtask) From 7844f382b9edd9324571e77457a051a748944902 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 6 Aug 2025 15:19:20 +0200 Subject: [PATCH 035/362] improve 2tag testing output report AliEn URLs used --- MC/run/ANCHOR/tests/test_looper.sh | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/MC/run/ANCHOR/tests/test_looper.sh b/MC/run/ANCHOR/tests/test_looper.sh index 7a243746b..66e40f119 100755 --- a/MC/run/ANCHOR/tests/test_looper.sh +++ b/MC/run/ANCHOR/tests/test_looper.sh @@ -92,6 +92,8 @@ done cd ${WORKING_DIR} # now we submit all the jobs in the background and wait for them to return +declare -A logfiles +declare -A urls for s in `ls submit*.sh`; do echo "submitting ${s}" export GRID_SUBMIT_WORKDIR="${WORKING_DIR}/${s}_workdir" @@ -99,9 +101,32 @@ for s in `ls submit*.sh`; do bash ${s} &> log_${s} echo "Job ${s} returned" ) & + logfiles["$s"]="log_${s}" done -# for for all (GRID) jobs to return +# Next stage is to wait until all jobs are actually running on +# AliEn +waitcounter=0 +maxwait=100 +while (( ${#logfiles[@]} > 0 && waitcounter < maxwait )); do + for script in "${!logfiles[@]}"; do + logfile=${logfiles["$script"]} + if grep -q "https://alimonitor.cern.ch/agent/jobs/details.jsp?pid=" "$logfile" 2>/dev/null; then + # Extract URL: strip ANSI codes, find URL, take first match + url=$(sed 's/\x1B\[[0-9;]*[a-zA-Z]//g' "$logfile" \ + | grep -o 'https://alimonitor.cern.ch/agent/jobs/details.jsp?pid=[0-9]*' \ + | head -n1) + + echo "Job ${script} has AliEn job URL: ${url}" + urls["$script"]=${url} + unset logfiles["$script"] + fi + done + sleep 1 + ((waitcounter++)) +done + +# wait for all (GRID) jobs to return echo "Waiting for jobs to return/finish" wait @@ -123,7 +148,7 @@ for s in `ls submit*.sh`; do WORKFLOWS_FOUND=$(alien.py find ${ALIEN_OUTPUT_FOLDER} workflow.json) if [[ -z ${WORKFLOWS_FOUND} || -z ${AODS_FOUND} ]]; then - echo "❌ Missing files for case $s" + echo "❌ Missing files for case $s: Check here for logs ${urls[${s}]}" FINAL_SUCCESS=1 # mark as failure else echo "✅ Files found in $s" From 617b5e8249a4cd157d29d72c0c0cee1f710e2453 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 6 Aug 2025 22:02:20 +0200 Subject: [PATCH 036/362] make TPC residual merging conditional --- MC/bin/o2dpg_sim_workflow.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 3369ef881..02adc08e1 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1975,13 +1975,15 @@ def remove_json_prefix(path): workflow['stages'].append(POOL_merge_task) # if TPC residuals extraction was requested, we have to merge per-tf trees -tpcResidMergingNeeds = ['scdaggreg_' + str(tf) for tf in range(1, NTIMEFRAMES + 1)] -TPCResid_merge_task = createTask(name='tpcresidmerge', needs = tpcResidMergingNeeds, lab=["CALIB"], mem='2000', cpu='1') -TPCResid_merge_task['cmd'] = ' set -e ; [ -f tpcresidmerge_input.txt ] && rm tpcresidmerge_input.txt; ' -TPCResid_merge_task['cmd'] += ' for i in `seq 1 ' + str(NTIMEFRAMES) + '`; do find tf${i} -name "o2tpc_residuals_*.root" >> tpcresidmerge_input.txt; done; ' -TPCResid_merge_task['cmd'] += '${O2DPG_ROOT}/UTILS/root_merger.py -o o2tpc_residuals.root -i $(grep -v \"^$\" tpcresidmerge_input.txt | paste -sd, -)' -workflow['stages'].append(TPCResid_merge_task) - +if includeTPCResiduals: + tpcResidMergingNeeds = ['scdaggreg_' + str(tf) for tf in range(1, NTIMEFRAMES + 1)] + TPCResid_merge_task = createTask(name='tpcresidmerge', needs = tpcResidMergingNeeds, lab=["CALIB"], mem='2000', cpu='1') + TPCResid_merge_task['cmd'] = ' set -e ; [ -f tpcresidmerge_input.txt ] && rm tpcresidmerge_input.txt; ' + TPCResid_merge_task['cmd'] += ' for i in `seq 1 ' + str(NTIMEFRAMES) + '`; do find tf${i} -name "o2tpc_residuals_*.root" >> tpcresidmerge_input.txt; done; ' + TPCResid_merge_task['cmd'] += '${O2DPG_ROOT}/UTILS/root_merger.py -o o2tpc_residuals.root -i $(grep -v \"^$\" tpcresidmerge_input.txt | paste -sd, -)' + workflow['stages'].append(TPCResid_merge_task) + + # adjust for alternate (RECO) software environments adjust_RECO_environment(workflow, args.alternative_reco_software) From a767cbc9c6f63b11c488d047a090b13768a342d8 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 7 Aug 2025 00:52:30 +0200 Subject: [PATCH 037/362] allow for custom O2DPG repo in anchored testing --- MC/run/ANCHOR/tests/test_anchor_2tag_template.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh index 0f984bd2f..4eb32bbc7 100644 --- a/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh +++ b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh @@ -53,5 +53,12 @@ export CYCLE=0 # generator and other sim configuration export ALIEN_JDL_ANCHOR_SIM_OPTIONS="%{SIM_OPTIONS}" +# we allow the possibility to use a special O2DPG version +if [ "${O2DPG_CUSTOM_REPO}" ]; then + git clone "${O2DPG_CUSTOM_REPO}" O2DPG + export O2DPG_ROOT=${PWD}/O2DPG + export ALIEN_JDL_O2DPG_OVERWRITE=${PWD}/O2DPG +fi + # execute MC ${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh From a7433af84fbe6b4750812a9d088f42d104cc9b45 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 7 Aug 2025 01:10:41 +0200 Subject: [PATCH 038/362] more improvements for 2tag testing --- MC/run/ANCHOR/tests/test_anchor_2tag_template.sh | 5 +++++ MC/run/ANCHOR/tests/test_looper.sh | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh index 4eb32bbc7..1baa1f65f 100644 --- a/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh +++ b/MC/run/ANCHOR/tests/test_anchor_2tag_template.sh @@ -53,11 +53,16 @@ export CYCLE=0 # generator and other sim configuration export ALIEN_JDL_ANCHOR_SIM_OPTIONS="%{SIM_OPTIONS}" +export O2DPG_CUSTOM_REPO="%{O2DPG_CUSTOM_REPO}" + # we allow the possibility to use a special O2DPG version if [ "${O2DPG_CUSTOM_REPO}" ]; then + echo "Checking out custom O2DPG repo ${O2DPG_CUSTOM_REPO}" git clone "${O2DPG_CUSTOM_REPO}" O2DPG export O2DPG_ROOT=${PWD}/O2DPG export ALIEN_JDL_O2DPG_OVERWRITE=${PWD}/O2DPG +else + echo "Using O2DPG from released software tag ${O2DPG_ROOT}" fi # execute MC diff --git a/MC/run/ANCHOR/tests/test_looper.sh b/MC/run/ANCHOR/tests/test_looper.sh index 66e40f119..c817c9edc 100755 --- a/MC/run/ANCHOR/tests/test_looper.sh +++ b/MC/run/ANCHOR/tests/test_looper.sh @@ -80,9 +80,17 @@ done # put the require spec sed -i "s/%{JDL_REQUIREMENT}/${REQUIRE_STRING}/g" "$OUTPUT_FILE_FINAL" + # inject custom repo if available + if [ "${O2DPG_CUSTOM_REPO}" ]; then + sed -i "s|%{O2DPG_CUSTOM_REPO}|${O2DPG_CUSTOM_REPO}|g" "$OUTPUT_FILE_FINAL" + fi + + TOPWORKDIR=2tag_release_testing_${BUILD_TAG:-${SOFTWARETAG_SIM}} + # we submit the test to the GRID (multiplicity of 4) # ${WORKING_DIR}/submit_case${count}_${SOFTWARETAG_ASYNC//::/-} - echo "${O2DPG_ROOT}/GRID/utils/grid_submit.sh --prodsplit 4 --singularity --ttl 3600 --script ${OUTPUT_FILE_FINAL} --jobname "anchorTest_${count}" --wait-any --topworkdir 2tag_release_testing_${SOFTWARETAG_SIM}" > ${WORKING_DIR}/submit_case${count}.sh + echo "${O2DPG_ROOT}/GRID/utils/grid_submit.sh --prodsplit 4 --singularity --ttl 3600 --script ${OUTPUT_FILE_FINAL} \ + --jobname "anchorTest_${count}" --wait-any --topworkdir ${TOPWORKDIR}" > ${WORKING_DIR}/submit_case${count}.sh # TODO: optional local execution with --local option ((count++)) # Increment counter for next row From 6821a4cc027b44f03a5dc416d5b92cb2827caa27 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 7 Aug 2025 00:13:41 +0200 Subject: [PATCH 039/362] improvements to grid_submit * use TMPDIR if available * improvements to early exit condition for job waiting --- GRID/utils/grid_submit.sh | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/GRID/utils/grid_submit.sh b/GRID/utils/grid_submit.sh index b3d6372d2..1d1bf8b5d 100755 --- a/GRID/utils/grid_submit.sh +++ b/GRID/utils/grid_submit.sh @@ -272,7 +272,7 @@ pok "Set the job name by running $0 " # Generate local workdir # if [[ "${ONGRID}" == "0" ]]; then - GRID_SUBMIT_WORKDIR=${GRID_SUBMIT_WORKDIR:-/tmp/alien_work/$(basename "$MY_JOBWORKDIR")} + GRID_SUBMIT_WORKDIR=${GRID_SUBMIT_WORKDIR:-${TMPDIR:-/tmp}/alien_work/$(basename "$MY_JOBWORKDIR")} echo "WORKDIR FOR THIS JOB IS ${GRID_SUBMIT_WORKDIR}" [ ! -d "${GRID_SUBMIT_WORKDIR}" ] && mkdir -p ${GRID_SUBMIT_WORKDIR} [ ! "${CONTINUE_WORKDIR}" ] && cp "${MY_JOBSCRIPT}" "${GRID_SUBMIT_WORKDIR}/alien_jobscript.sh" @@ -443,9 +443,20 @@ EOF # this is the global job status (a D here means the production is done) JOBSTATUS=$(alien.py ps -j ${MY_JOBID} | awk '//{print $3}') # this is the global job status # in addition we may query individual splits - if [ "${WAITFORANY}" ]; then - if ALIENPY_JSON=true alien.py ps -a -m "${MY_JOBID}" | grep "status" | grep -q "DONE"; then - JOBSTATUS="D" # a D here means == some job finished successfully + if [ -n "${WAITFORALIENANY}" ]; then + DETAILED_STATUS_JSON=$(ALIENPY_JSON=true alien.py ps -a -m "${MY_JOBID}") + # check if any is already marked as DONE + if jq -e '.results | any(.status == "DONE")' <<<"${DETAILED_STATUS_JSON}" >/dev/null; then + JOBSTATUS="D" + echo "At least one good job" + else + # check if there are still jobs running/waiting; if not also finish + # this could happen when all jobs are zombies (in which case we also finish) + if ! jq -e '.results | any(.status == "WAITING" or .status == "RUNNING" or .status == "SAVING" or .status == "INSERTING")' \ + <<<"${DETAILED_STATUS_JSON}" >/dev/null; then + JOBSTATUS="D" # some job finished successfully + echo "No remaining good job" + fi fi fi From 26daf2090f9bb66a71391aec23c342b42a589886 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 8 Aug 2025 18:38:04 +0200 Subject: [PATCH 040/362] [MCH] improvements to the pedestal calibrator Added few options to the MCH pedestal calibration aggregator script: - configurable number of threads for the aggregator task - configurable logging interval - option to disable the final upload of the CCDB objects (for testing purposes) --- .../calib/mch-badchannel-aggregator.sh | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/DATA/production/calib/mch-badchannel-aggregator.sh b/DATA/production/calib/mch-badchannel-aggregator.sh index 91920a495..0f962b8f4 100755 --- a/DATA/production/calib/mch-badchannel-aggregator.sh +++ b/DATA/production/calib/mch-badchannel-aggregator.sh @@ -15,12 +15,25 @@ MCH_MAX_NOISE=${MCH_MAX_NOISE:-2.0} MCH_MIN_ENTRIES=${MCH_MIN_ENTRIES:-100} MCH_MIN_FRACTION=${MCH_MIN_FRACTION:-0.5} MCH_END_OF_STREAM_ONLY=${MCH_END_OF_STREAM_ONLY:-true} -BADCHANNEL_CONFIG="${ARGS_ALL_CONFIG};MCHBadChannelCalibratorParam.maxPed=${MCH_MAX_PEDESTAL};MCHBadChannelCalibratorParam.maxNoise=${MCH_MAX_NOISE};MCHBadChannelCalibratorParam.minRequiredNofEntriesPerChannel=${MCH_MIN_ENTRIES};MCHBadChannelCalibratorParam.minRequiredCalibratedFraction=${MCH_MIN_FRACTION};MCHBadChannelCalibratorParam.onlyAtEndOfStream=${MCH_END_OF_STREAM_ONLY}" +BADCHANNEL_CONFIG="${ARGS_ALL_CONFIG};MCHBadChannelCalibratorParam.maxPed=${MCH_MAX_PEDESTAL};MCHBadChannelCalibratorParam.maxNoise=${MCH_MAX_NOISE};MCHBadChannelCalibratorParam.minRequiredNofEntriesPerChannel=${MCH_MIN_ENTRIES};MCHBadChannelCalibratorParam.minRequiredCalibratedFraction=${MCH_MIN_FRACTION};MCHBadChannelCalibratorParam.onlyAtEndOfStream=${MCH_END_OF_STREAM_ONLY};" + +if [ -n "${MCH_NTHREADS}" ]; then + BADCHANNEL_CONFIG+="MCHBadChannelCalibratorParam.nThreads=${MCH_NTHREADS};" +fi + +MCH_LOGGING_OPT= +if [ -n "${MCH_LOGGING_INTERVAL}" ]; then + MCH_LOGGING_OPT="--logging-interval ${MCH_LOGGING_INTERVAL}" +fi WORKFLOW="o2-dpl-raw-proxy $ARGS_ALL --proxy-name mch-badchannel-input-proxy --dataspec \"$PROXY_INSPEC\" --network-interface ib0 --channel-config \"name=mch-badchannel-input-proxy,method=bind,type=pull,rateLogging=0,transport=zeromq\" | " -WORKFLOW+="o2-calibration-mch-badchannel-calib-workflow $ARGS_ALL --configKeyValues \"$BADCHANNEL_CONFIG\" | " -WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"http://o2-ccdb.internal\" --sspec-min 0 --sspec-max 0 | " -WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"$DCSCCDBSERVER_PERS\" --sspec-min 1 --sspec-max 1 --name-extention dcs | " +WORKFLOW+="o2-calibration-mch-badchannel-calib-workflow $ARGS_ALL --configKeyValues \"$BADCHANNEL_CONFIG\" ${MCH_LOGGING_OPT} | " + +if [ -z "${MCH_SKIP_CCDB_UPLOAD}" ]; then + WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"http://o2-ccdb.internal\" --sspec-min 0 --sspec-max 0 | " + WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"$DCSCCDBSERVER_PERS\" --sspec-min 1 --sspec-max 1 --name-extention dcs | " +fi + add_QC_from_consul "/o2/components/qc/ANY/any/mch-badchannel" "" WORKFLOW+="o2-dpl-run $ARGS_ALL $GLOBALDPLOPT" From f68d1aea77c5ae391157cca5cb59366f425a7f48 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Wed, 13 Aug 2025 16:46:51 +0200 Subject: [PATCH 041/362] Fix shellcheck issues --- MC/run/ANCHOR/tests/test_looper.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MC/run/ANCHOR/tests/test_looper.sh b/MC/run/ANCHOR/tests/test_looper.sh index c817c9edc..43abfad5f 100755 --- a/MC/run/ANCHOR/tests/test_looper.sh +++ b/MC/run/ANCHOR/tests/test_looper.sh @@ -102,7 +102,7 @@ cd ${WORKING_DIR} # now we submit all the jobs in the background and wait for them to return declare -A logfiles declare -A urls -for s in `ls submit*.sh`; do +for s in submit*.sh; do echo "submitting ${s}" export GRID_SUBMIT_WORKDIR="${WORKING_DIR}/${s}_workdir" ( @@ -144,7 +144,7 @@ wait echo "-- Jobs done ... validating --" FINAL_SUCCESS=0 -for s in `ls submit*.sh`; do +for s in submit*.sh; do # find output path TEST_OUTPUT_PATH="${WORKING_DIR}/${s}_workdir" # $(grep "Local working directory is" log_${s} | awk '//{print $5}') @@ -172,4 +172,4 @@ fi #TODO: echo "-- Cleaning up ... " cd .. -exit ${FINAL_SUCCESS} \ No newline at end of file +exit ${FINAL_SUCCESS} From 6bbcd05fb4dd5c83c8901c60107a1c03196c03ce Mon Sep 17 00:00:00 2001 From: Sebastian Scheid Date: Thu, 14 Aug 2025 11:23:53 +0200 Subject: [PATCH 042/362] Add generator energies for MC sims (#2096) --- MC/config/ALICE3/ini/pythia8_pp_536tev.ini | 9 +++++++++ MC/config/ALICE3/ini/pythia8_pp_7tev.ini | 9 +++++++++ .../pythia8/generator/pythia8_pp_536tev.cfg | 16 ++++++++++++++++ .../ALICE3/pythia8/generator/pythia8_pp_7tev.cfg | 16 ++++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 MC/config/ALICE3/ini/pythia8_pp_536tev.ini create mode 100644 MC/config/ALICE3/ini/pythia8_pp_7tev.ini create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_536tev.ini b/MC/config/ALICE3/ini/pythia8_pp_536tev.ini new file mode 100644 index 000000000..528de37c2 --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_536tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_7tev.ini b/MC/config/ALICE3/ini/pythia8_pp_7tev.ini new file mode 100644 index 000000000..5c4b1336e --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_7tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg new file mode 100644 index 000000000..1f270e206 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg @@ -0,0 +1,16 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg new file mode 100644 index 000000000..c1bc3b3c0 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg @@ -0,0 +1,16 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 7000. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on From 5622cefd1e93461412d11ad7b2e5fabd779badab Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Thu, 14 Aug 2025 13:01:58 +0200 Subject: [PATCH 043/362] Flat Gas external generator (#2094) * Flat Gas external generator --- .../common/external/generator/TPCLoopers.C | 204 ++++++++++++++++-- .../common/ini/GeneratorLoopersFlatGas.ini | 5 + 2 files changed, 191 insertions(+), 18 deletions(-) create mode 100644 MC/config/common/ini/GeneratorLoopersFlatGas.ini diff --git a/MC/config/common/external/generator/TPCLoopers.C b/MC/config/common/external/generator/TPCLoopers.C index fb53c7a50..22184f451 100644 --- a/MC/config/common/external/generator/TPCLoopers.C +++ b/MC/config/common/external/generator/TPCLoopers.C @@ -215,21 +215,61 @@ class GenTPCLoopers : public Generator mGenPairs.clear(); // Clear the vector of compton electrons mGenElectrons.clear(); - // Set number of loopers if poissonian params are available - if (mPoissonSet) + if (mFlatGas) { - mNLoopersPairs = static_cast(std::round(mMultiplier[0] * PoissonPairs())); - } - if (mGaussSet) - { - mNLoopersCompton = static_cast(std::round(mMultiplier[1] * GaussianElectrons())); - } + unsigned int nLoopers, nLoopersPairs, nLoopersCompton; + LOG(debug) << "mCurrentEvent is " << mCurrentEvent; + LOG(debug) << "Current event time: " << ((mCurrentEvent < mInteractionTimeRecords.size() - 1) ? std::to_string(mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns()) : std::to_string(mIntTimeRecMean)) << " ns"; + LOG(debug) << "Current time offset wrt BC: " << mInteractionTimeRecords[mCurrentEvent].getTimeOffsetWrtBC() << " ns"; + mTimeLimit = (mCurrentEvent < mInteractionTimeRecords.size() - 1) ? mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns() : mIntTimeRecMean; + // With flat gas the number of loopers are adapted based on time interval widths + nLoopers = mFlatGasNumber * (mTimeLimit / mIntTimeRecMean); + nLoopersPairs = static_cast(std::round(nLoopers * mLoopsFractionPairs)); + nLoopersCompton = nLoopers - nLoopersPairs; + SetNLoopers(nLoopersPairs, nLoopersCompton); + LOG(info) << "Flat gas loopers: " << nLoopers << " (pairs: " << nLoopersPairs << ", compton: " << nLoopersCompton << ")"; + generateEvent(mTimeLimit); + mCurrentEvent++; + } else { + // Set number of loopers if poissonian params are available + if (mPoissonSet) + { + mNLoopersPairs = static_cast(std::round(mMultiplier[0] * PoissonPairs())); + } + if (mGaussSet) + { + mNLoopersCompton = static_cast(std::round(mMultiplier[1] * GaussianElectrons())); + } + // Generate pairs + for (int i = 0; i < mNLoopersPairs; ++i) + { + std::vector pair = mONNX_pair->generate_sample(); + // Apply the inverse transformation using the scaler + std::vector transformed_pair = mScaler_pair->inverse_transform(pair); + mGenPairs.push_back(transformed_pair); + } + // Generate compton electrons + for (int i = 0; i < mNLoopersCompton; ++i) + { + std::vector electron = mONNX_compton->generate_sample(); + // Apply the inverse transformation using the scaler + std::vector transformed_electron = mScaler_compton->inverse_transform(electron); + mGenElectrons.push_back(transformed_electron); + } + } + return true; + } + + Bool_t generateEvent(double &time_limit) + { + LOG(info) << "Time constraint for loopers: " << time_limit << " ns"; // Generate pairs for (int i = 0; i < mNLoopersPairs; ++i) { std::vector pair = mONNX_pair->generate_sample(); // Apply the inverse transformation using the scaler std::vector transformed_pair = mScaler_pair->inverse_transform(pair); + transformed_pair[9] = gRandom->Uniform(0., time_limit); // Regenerate time, scaling is not needed because time_limit is already in nanoseconds mGenPairs.push_back(transformed_pair); } // Generate compton electrons @@ -238,8 +278,10 @@ class GenTPCLoopers : public Generator std::vector electron = mONNX_compton->generate_sample(); // Apply the inverse transformation using the scaler std::vector transformed_electron = mScaler_compton->inverse_transform(electron); + transformed_electron[6] = gRandom->Uniform(0., time_limit); // Regenerate time, scaling is not needed because time_limit is already in nanoseconds mGenElectrons.push_back(transformed_electron); } + LOG(info) << "Generated Particles with time limit"; return true; } @@ -301,9 +343,9 @@ class GenTPCLoopers : public Generator return true; } - short int PoissonPairs() + unsigned int PoissonPairs() { - short int poissonValue; + unsigned int poissonValue; do { // Generate a Poisson-distributed random number with mean mPoisson[0] @@ -313,9 +355,9 @@ class GenTPCLoopers : public Generator return poissonValue; } - short int GaussianElectrons() + unsigned int GaussianElectrons() { - short int gaussValue; + unsigned int gaussValue; do { // Generate a Normal-distributed random number with mean mGass[0] and stddev mGauss[1] @@ -325,7 +367,7 @@ class GenTPCLoopers : public Generator return gaussValue; } - void SetNLoopers(short int &nsig_pair, short int &nsig_compton) + void SetNLoopers(unsigned int &nsig_pair, unsigned int &nsig_compton) { if(mPoissonSet) { LOG(info) << "Poissonian parameters correctly loaded."; @@ -354,6 +396,52 @@ class GenTPCLoopers : public Generator } } + void setFlatGas(Bool_t &flat, const Int_t &number = -1) + { + mFlatGas = flat; + if (mFlatGas) + { + if (number < 0) + { + LOG(warn) << "Warning: Number of loopers per event must be non-negative! Switching option off."; + mFlatGas = false; + mFlatGasNumber = -1; + } else { + mFlatGasNumber = number; + mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr; + mCollisionContext = mContextFile ? (o2::steer::DigitizationContext *)mContextFile->Get("DigitizationContext") : nullptr; + mInteractionTimeRecords = mCollisionContext ? mCollisionContext->getEventRecords() : std::vector{}; + if (mInteractionTimeRecords.empty()) + { + LOG(error) << "Error: No interaction time records found in the collision context!"; + exit(1); + } else { + LOG(info) << "Interaction Time records has " << mInteractionTimeRecords.size() << " entries."; + mCollisionContext->printCollisionSummary(); + } + for (int c = 0; c < mInteractionTimeRecords.size() - 1; c++) + { + mIntTimeRecMean += mInteractionTimeRecords[c + 1].bc2ns() - mInteractionTimeRecords[c].bc2ns(); + } + mIntTimeRecMean /= (mInteractionTimeRecords.size() - 1); // Average interaction time record used as reference + } + } else { + mFlatGasNumber = -1; + } + LOG(info) << "Flat gas loopers: " << (mFlatGas ? "ON" : "OFF") << ", Reference loopers number per event: " << mFlatGasNumber; + } + + void setFractionPairs(float &fractionPairs) + { + if (fractionPairs < 0 || fractionPairs > 1) + { + LOG(fatal) << "Error: Loops fraction for pairs must be in the range [0, 1]."; + exit(1); + } + mLoopsFractionPairs = fractionPairs; + LOG(info) << "Pairs fraction set to: " << mLoopsFractionPairs; + } + private: std::unique_ptr mONNX_pair = nullptr; std::unique_ptr mONNX_compton = nullptr; @@ -363,8 +451,8 @@ class GenTPCLoopers : public Generator double mGauss[4] = {0.0, 0.0, 0.0, 0.0}; // Mean, Std, Min, Max std::vector> mGenPairs; std::vector> mGenElectrons; - short int mNLoopersPairs = -1; - short int mNLoopersCompton = -1; + unsigned int mNLoopersPairs = -1; + unsigned int mNLoopersCompton = -1; std::array mMultiplier = {1., 1.}; bool mPoissonSet = false; bool mGaussSet = false; @@ -374,6 +462,15 @@ class GenTPCLoopers : public Generator TDatabasePDG *mPDG = TDatabasePDG::Instance(); double mMass_e = mPDG->GetParticle(11)->Mass(); double mMass_p = mPDG->GetParticle(-11)->Mass(); + int mCurrentEvent = 0; // Current event number, used for adaptive loopers + TFile *mContextFile = nullptr; // Input collision context file + o2::steer::DigitizationContext *mCollisionContext = nullptr; // Pointer to the digitization context + std::vector mInteractionTimeRecords; // Interaction time records from collision context + Bool_t mFlatGas = false; // Flag to indicate if flat gas loopers are used + Int_t mFlatGasNumber = -1; // Number of flat gas loopers per event + double mIntTimeRecMean = 1.0; // Average interaction time record used for the reference + double mTimeLimit = 0.0; // Time limit for the current event + float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs }; } // namespace eventgen @@ -387,8 +484,8 @@ class GenTPCLoopers : public Generator FairGenerator * Generator_TPCLoopers(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", std::string poisson = "poisson.csv", std::string gauss = "gauss.csv", std::string scaler_pair = "scaler_pair.json", - std::string scaler_compton = "scaler_compton.json", std::array mult = {1., 1.}, short int nloopers_pairs = 1, - short int nloopers_compton = 1) + std::string scaler_compton = "scaler_compton.json", std::array mult = {1., 1.}, unsigned int nloopers_pairs = 1, + unsigned int nloopers_compton = 1) { // Expand all environment paths model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); @@ -450,4 +547,75 @@ FairGenerator * generator->SetNLoopers(nloopers_pairs, nloopers_compton); generator->SetMultiplier(mult); return generator; -} \ No newline at end of file +} + +// Generator with flat gas loopers. Number of loopers starts from a reference value and changes +// based on the BC time intervals in each event. +FairGenerator * +Generator_TPCLoopersFlat(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string scaler_pair = "scaler_pair.json", std::string scaler_compton = "scaler_compton.json", + bool flat_gas = true, const int loops_num = 500, float fraction_pairs = 0.08) +{ + // Expand all environment paths + model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); + model_compton = gSystem->ExpandPathName(model_compton.c_str()); + scaler_pair = gSystem->ExpandPathName(scaler_pair.c_str()); + scaler_compton = gSystem->ExpandPathName(scaler_compton.c_str()); + const std::array models = {model_pairs, model_compton}; + const std::array local_names = {"WGANpair.onnx", "WGANcompton.onnx"}; + const std::array isAlien = {models[0].starts_with("alien://"), models[1].starts_with("alien://")}; + const std::array isCCDB = {models[0].starts_with("ccdb://"), models[1].starts_with("ccdb://")}; + if (std::any_of(isAlien.begin(), isAlien.end(), [](bool v) + { return v; })) + { + if (!gGrid) + { + TGrid::Connect("alien://"); + if (!gGrid) + { + LOG(fatal) << "AliEn connection failed, check token."; + exit(1); + } + } + for (size_t i = 0; i < models.size(); ++i) + { + if (isAlien[i] && !TFile::Cp(models[i].c_str(), local_names[i].c_str())) + { + LOG(fatal) << "Error: Model file " << models[i] << " does not exist!"; + exit(1); + } + } + } + if (std::any_of(isCCDB.begin(), isCCDB.end(), [](bool v) + { return v; })) + { + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("http://alice-ccdb.cern.ch"); + for (size_t i = 0; i < models.size(); ++i) + { + if (isCCDB[i]) + { + auto model_path = models[i].substr(7); // Remove "ccdb://" + // Treat filename if provided in the CCDB path + auto extension = model_path.find(".onnx"); + if (extension != std::string::npos) + { + auto last_slash = model_path.find_last_of('/'); + model_path = model_path.substr(0, last_slash); + } + std::map filter; + if (!ccdb_api.retrieveBlob(model_path, "./", filter, o2::ccdb::getCurrentTimestamp(), false, local_names[i].c_str())) + { + LOG(fatal) << "Error: issues in retrieving " << model_path << " from CCDB!"; + exit(1); + } + } + } + } + model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; + model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; + auto generator = new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); + generator->setFractionPairs(fraction_pairs); + generator->setFlatGas(flat_gas, loops_num); + return generator; +} diff --git a/MC/config/common/ini/GeneratorLoopersFlatGas.ini b/MC/config/common/ini/GeneratorLoopersFlatGas.ini new file mode 100644 index 000000000..68c7648ae --- /dev/null +++ b/MC/config/common/ini/GeneratorLoopersFlatGas.ini @@ -0,0 +1,5 @@ +# TPC loopers injector +#---> GeneratorTPCloopers +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/TPCLoopers.C +funcName = Generator_TPCLoopersFlat("ccdb://Users/m/mgiacalo/WGAN_ExtGenPair", "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerPairParams.json", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerComptonParams.json") \ No newline at end of file From 58478fda6ed5c0b06ae0c6efc4be964ece6e4d34 Mon Sep 17 00:00:00 2001 From: gluparel Date: Thu, 14 Aug 2025 13:03:07 +0200 Subject: [PATCH 044/362] Add config for pools of undecayed Xic+ in pp collisions at 13 TeV (#2085) * Add config for pools of undecayed Xic+ in pp collisions at 13 TeV * separate cfg files for XiC0 and XiC+ * fix ini files * fix test files --- ...atorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini | 8 ++ ...atorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini | 8 ++ ...eratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C | 83 ++++++++++++++++++ ...eratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C | 84 +++++++++++++++++++ .../pythia8_charmhadronic_XiC_NoDecay.cfg | 2 +- .../pythia8_charmhadronic_XiCplus_NoDecay.cfg | 42 ++++++++++ 6 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini new file mode 100644 index 000000000..4d073970a --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini new file mode 100644 index 000000000..ba9fb1e09 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C new file mode 100644 index 000000000..3e245d287 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark = 5; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C new file mode 100644 index 000000000..a2b4d3499 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark = 4; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg index 7719e8b32..6ce71ed4f 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg @@ -38,5 +38,5 @@ BeamRemnants:saturation 5 #OmegaC 4332:tau0 = 0.0803 -### switch off XiC decays +### switch off XiC0 decays 4132:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg new file mode 100644 index 000000000..51771aee8 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg @@ -0,0 +1,42 @@ +### configuration for XiC + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +#Correct decay lengths(wrong in PYTHIA8 decay table) +#Lb +5122:tau0 = 0.4390 +#Xic0 +4132:tau0 = 0.0455 +#OmegaC +4332:tau0 = 0.0803 + +### switch off XiC+ decays +4232:onMode = off From 01f1eb02d8b34742a8ebb40c72900c8a32852d2d Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 14 Aug 2025 14:49:58 +0200 Subject: [PATCH 045/362] Update test_looper.sh --- MC/run/ANCHOR/tests/test_looper.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MC/run/ANCHOR/tests/test_looper.sh b/MC/run/ANCHOR/tests/test_looper.sh index 43abfad5f..7a356242e 100755 --- a/MC/run/ANCHOR/tests/test_looper.sh +++ b/MC/run/ANCHOR/tests/test_looper.sh @@ -83,6 +83,8 @@ done # inject custom repo if available if [ "${O2DPG_CUSTOM_REPO}" ]; then sed -i "s|%{O2DPG_CUSTOM_REPO}|${O2DPG_CUSTOM_REPO}|g" "$OUTPUT_FILE_FINAL" + else + sed -i "/%{O2DPG_CUSTOM_REPO}/d" "$OUTPUT_FILE_FINAL" fi TOPWORKDIR=2tag_release_testing_${BUILD_TAG:-${SOFTWARETAG_SIM}} From 56d1ff5f1b11bc16d4e8e488e18cbc2274ff3294 Mon Sep 17 00:00:00 2001 From: Sebastian Scheid Date: Sat, 16 Aug 2025 09:31:12 +0200 Subject: [PATCH 046/362] Add pythia pp 5.02 TeV to generators (#2098) --- MC/config/ALICE3/ini/pythia8_pp_502tev.ini | 9 +++++++++ .../pythia8/generator/pythia8_pp_502tev.cfg | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 MC/config/ALICE3/ini/pythia8_pp_502tev.ini create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_502tev.ini b/MC/config/ALICE3/ini/pythia8_pp_502tev.ini new file mode 100644 index 000000000..3c73b4e1a --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_502tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg new file mode 100644 index 000000000..68e3ef034 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg @@ -0,0 +1,16 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5020. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on From a53c0bd7b2759954c22698947c1b2de7cf004db7 Mon Sep 17 00:00:00 2001 From: chengtt0406 <39661669+chengtt0406@users.noreply.github.com> Date: Mon, 18 Aug 2025 14:04:47 +0200 Subject: [PATCH 047/362] Separate the cgf files for each baryon (#2097) * Separate the cgf files for each baryon * Try to retrigger a test with a dummy commit --- ..._D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini | 2 +- ...rHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini | 2 +- ...D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini | 2 +- ..._D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini | 2 +- ...rHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini | 2 +- ...D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini | 2 +- ...mhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg} | 8 +--- ...charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg | 43 +++++++++++++++++++ ...mhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg | 43 +++++++++++++++++++ 9 files changed, 93 insertions(+), 13 deletions(-) rename MC/config/PWGHF/pythia8/generator/{pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg => pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg} (89%) create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini index 5ae8c3f42..1f335d8b9 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -4,5 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini index 942e2be65..52218bc9d 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -4,5 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini index ca98bb303..5bc9cfd04 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -4,5 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4232}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini index 09db15af0..5e2d34dd3 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -4,5 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini index a25594bc9..4425b2f9a 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -4,5 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini index 0231b40bf..892665f6d 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -4,5 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4232}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg similarity index 89% rename from MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg rename to MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg index 024c6fa8e..60732359a 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_NoDecay_Mode2_pp_ref.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg @@ -1,5 +1,5 @@ ### author: Tiantian Cheng (tiantian.cheng@cern.ch) -### last update: July 2025 +### last update: August 2025 ### beams Beams:idA 2212 # proton @@ -39,11 +39,5 @@ BeamRemnants:saturation 5 # OmegaC 4332:tau0 = 0.0803 -### switch off Xic0 decays -4132:onMode = off - -### switch off Xic+ decays -4232:onMode = off - ### switch off OmegaC decays 4332:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg new file mode 100644 index 000000000..7ca299325 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg @@ -0,0 +1,43 @@ +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### switch off Xic0 decays +4132:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg new file mode 100644 index 000000000..34e80be24 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg @@ -0,0 +1,43 @@ +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### switch off Xic+ decays +4232:onMode = off From cee54bde5486891c153ab5941faf96782308a711 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 20 Aug 2025 13:49:13 +0200 Subject: [PATCH 048/362] Adding utility to remove duplicate BCs from a MC-AO2D This should fix the situation discussed in https://its.cern.ch/jira/browse/O2-6227 Also apply the processing step as part of the O2DPG MC chain, so as to avoid the problem in the future. --- MC/bin/o2dpg_sim_workflow.py | 5 +- MC/utils/AODBcRewriter.C | 306 +++++++++++++++++++++++++++++++++++ 2 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 MC/utils/AODBcRewriter.C diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 02adc08e1..fa57b4aea 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1950,9 +1950,12 @@ def remove_json_prefix(path): AOD_merge_task = createTask(name='aodmerge', needs = aodmergerneeds, lab=["AOD"], mem='2000', cpu='1') AOD_merge_task['cmd'] = ' set -e ; [ -f aodmerge_input.txt ] && rm aodmerge_input.txt; ' AOD_merge_task['cmd'] += ' for i in `seq 1 ' + str(NTIMEFRAMES) + '`; do echo "tf${i}/AO2D.root" >> aodmerge_input.txt; done; ' - AOD_merge_task['cmd'] += ' o2-aod-merger --input aodmerge_input.txt --output AO2D.root' + AOD_merge_task['cmd'] += ' o2-aod-merger --input aodmerge_input.txt --output AO2D_pre.root' # produce MonaLisa event stat file AOD_merge_task['cmd'] += ' ; ${O2DPG_ROOT}/MC/bin/o2dpg_determine_eventstat.py' + # reindex the BC + connected tables because it there could be duplicate BC entries due to the orbit-early treatment + # see https://its.cern.ch/jira/browse/O2-6227 + AOD_merge_task['cmd'] += ' ; root -q -b -l "${O2DPG_ROOT}/MC/utils/AODBcRewriter.C(\\\"AO2D_pre.root\\\",\\\"AO2D.root\\\")"' AOD_merge_task['alternative_alienv_package'] = "None" # we want latest software for this step workflow['stages'].append(AOD_merge_task) diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C new file mode 100644 index 000000000..23cefe437 --- /dev/null +++ b/MC/utils/AODBcRewriter.C @@ -0,0 +1,306 @@ +// A utility to remove duplicate bunch crossing entries +// from the O2bc_ table/TTree and to adjust all tables refering +// to fIndexBC. +// Situations of duplicate BCs can arise in O2DPG MC and are harder to avoid +// directly in the AO2D creation. This tool provides a convenient +// post-processing step to rectify the situation. +// The tool might need adjustment whenever the AO2D data format changes, for +// instance when new tables are added which are directly joinable to the BC +// table. + +// started by sandro.wenzel@cern.ch August 2025 + +// Usage: root -l -b -q 'AODBcRewriter.C("input.root","output.root")' + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "TBranch.h" +#include "TDirectory.h" +#include "TFile.h" +#include "TKey.h" +#include "TLeaf.h" +#include "TString.h" +#include "TTree.h" + +#include +#include +#include +#include +#include +#include +#endif + +/// Helper to manage branch buffers and copying +struct BranchHandler { + std::string name; + std::string type; + void *inBuf = nullptr; + void *outBuf = nullptr; + TBranch *inBranch = nullptr; + TBranch *outBranch = nullptr; + + BranchHandler(TBranch *br, TTree *outTree = nullptr) { + inBranch = br; + name = br->GetName(); + TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); + type = leaf->GetTypeName(); + + if (type == "Int_t") { + inBuf = new Int_t; + if (outTree) { + outBuf = new Int_t; + outBranch = outTree->Branch(name.c_str(), (Int_t *)outBuf); + } + } else if (type == "ULong64_t") { + inBuf = new ULong64_t; + if (outTree) { + outBuf = new ULong64_t; + outBranch = outTree->Branch(name.c_str(), (ULong64_t *)outBuf); + } + } else if (type == "UChar_t") { + inBuf = new UChar_t; + if (outTree) { + outBuf = new UChar_t; + outBranch = outTree->Branch(name.c_str(), (UChar_t *)outBuf); + } + } else { + std::cerr << "Unsupported type " << type << " for branch " << name + << std::endl; + } + if (inBuf) + inBranch->SetAddress(inBuf); + } + + void copyValue() { + if (inBuf && outBuf) { + TLeaf *leaf = (TLeaf *)inBranch->GetListOfLeaves()->At(0); + size_t sz = leaf->GetLenType(); + memcpy(outBuf, inBuf, sz); + } + } + + ~BranchHandler() { deleteBuffer(); } + + void deleteBuffer() { + if (type == "Int_t") { + delete (Int_t *)inBuf; + delete (Int_t *)outBuf; + } else if (type == "ULong64_t") { + delete (ULong64_t *)inBuf; + delete (ULong64_t *)outBuf; + } else if (type == "UChar_t") { + delete (UChar_t *)inBuf; + delete (UChar_t *)outBuf; + } + inBuf = outBuf = nullptr; + } +}; + +/// Copy any TObject (tree or dir handled recursively) +void copyObject(TObject *obj, TDirectory *outDir) { + if (!obj || !outDir) + return; + outDir->cd(); + if (obj->InheritsFrom("TDirectory")) { + TDirectory *srcDir = (TDirectory *)obj; + std::cout << "📂 Copying directory: " << srcDir->GetName() << std::endl; + TDirectory *newDir = outDir->mkdir(srcDir->GetName()); + TIter nextKey(srcDir->GetListOfKeys()); + TKey *key; + while ((key = (TKey *)nextKey())) { + TObject *subObj = key->ReadObj(); + copyObject(subObj, newDir); + } + } else if (obj->InheritsFrom("TTree")) { + TTree *t = (TTree *)obj; + std::cout << " Copying untouched TTree: " << t->GetName() << std::endl; + TTree *tnew = t->CloneTree(-1, "fast"); + tnew->SetDirectory(outDir); + tnew->Write(); + } else { + std::cout << " Copying object: " << obj->GetName() << " [" + << obj->ClassName() << "]" << std::endl; + obj->Write(); + } +} + +/// Process one DF_* directory +void processDF(TDirectory *dirIn, TDirectory *dirOut) { + std::cout << "\n====================================================" + << std::endl; + std::cout << "▶ Processing DF folder: " << dirIn->GetName() << std::endl; + + TTree *treeBCs = nullptr; + TTree *treeFlags = nullptr; + std::vector treesWithBCid; + std::vector otherObjects; + + // Inspect folder contents + for (auto subkeyObj : *(dirIn->GetListOfKeys())) { + TKey *subkey = (TKey *)subkeyObj; + TObject *obj = dirIn->Get(subkey->GetName()); + if (obj->InheritsFrom(TTree::Class())) { + TTree *tree = (TTree *)obj; + TString tname = tree->GetName(); + if (tname.BeginsWith("O2bc_")) { + treeBCs = tree; + std::cout << " Found O2bc: " << tname << std::endl; + } else if (tname == "O2bcflag") { + // this is a special table as it is directly joinable to O2bc + // according to the datamodel + treeFlags = tree; + std::cout << " Found O2bcflag" << std::endl; + } else if (tree->GetBranch("fIndexBCs")) { + treesWithBCid.push_back(tree); + std::cout << " Needs reindex: " << tname << std::endl; + } else { + otherObjects.push_back(tree); + std::cout << " Unaffected TTree: " << tname << std::endl; + } + } else { + otherObjects.push_back(obj); + } + } + + if (!treeBCs) { + std::cout << "⚠ No O2bc found in " << dirIn->GetName() + << " → just copying objects" << std::endl; + for (auto obj : otherObjects) { + copyObject(obj, dirOut); + } + return; + } + + // Read fGlobalBC values + ULong64_t fGlobalBC; + treeBCs->SetBranchAddress("fGlobalBC", &fGlobalBC); + std::vector originalBCs(treeBCs->GetEntries()); + for (Long64_t i = 0; i < treeBCs->GetEntries(); i++) { + treeBCs->GetEntry(i); + originalBCs[i] = fGlobalBC; + } + + std::cout << " O2bc entries: " << originalBCs.size() << std::endl; + + // Build mapping + std::vector indexMap(originalBCs.size(), -1); + std::vector uniqueBCs; + std::vector order(originalBCs.size()); + std::iota(order.begin(), order.end(), 0); + std::sort(order.begin(), order.end(), [&](size_t a, size_t b) { + return originalBCs[a] < originalBCs[b]; + }); + Int_t newIdx = -1; + ULong64_t prevVal = -1; + std::unordered_map> newIndexOrigins; + for (auto oldIdx : order) { + ULong64_t val = originalBCs[oldIdx]; + if (newIdx < 0 || val != prevVal) { + ++newIdx; + prevVal = val; + uniqueBCs.push_back(val); + } + indexMap[oldIdx] = newIdx; + newIndexOrigins[newIdx].push_back(oldIdx); + } + std::cout << " Unique BCs after deduplication: " << uniqueBCs.size() + << std::endl; + + // --- Rewrite O2bc --- + dirOut->cd(); + TTree *treeBCsOut = new TTree(treeBCs->GetName(), "fixed O2bc tree"); + std::vector> bcBranches; + for (auto brObj : *treeBCs->GetListOfBranches()) { + TBranch *br = (TBranch *)brObj; + if (TString(br->GetName()) == "fGlobalBC") + continue; + bcBranches.emplace_back(std::make_unique(br, treeBCsOut)); + } + ULong64_t outBC; + treeBCsOut->Branch("fGlobalBC", &outBC, "fGlobalBC/l"); + + for (int newIdx = 0; newIdx < uniqueBCs.size(); newIdx++) { + auto &oldIndices = newIndexOrigins[newIdx]; + if (oldIndices.empty()) + continue; + size_t oldIdx = oldIndices.front(); + treeBCs->GetEntry(oldIdx); + outBC = originalBCs[oldIdx]; + for (auto &bh : bcBranches) { + bh->copyValue(); + } + treeBCsOut->Fill(); + } + std::cout << " Wrote O2bc with " << treeBCsOut->GetEntries() << " entries" + << std::endl; + treeBCsOut->Write(); + + // --- Rewrite O2bcflag --- + if (treeFlags) { + std::cout << " Rebuilding O2bcflag..." << std::endl; + dirOut->cd(); + TTree *treeFlagsOut = treeFlags->CloneTree(0); + std::vector> flagBranches; + for (auto brObj : *treeFlags->GetListOfBranches()) { + TBranch *br = (TBranch *)brObj; + flagBranches.emplace_back( + std::make_unique(br, treeFlagsOut)); + } + for (int newIdx = 0; newIdx < uniqueBCs.size(); newIdx++) { + auto &oldIndices = newIndexOrigins[newIdx]; + if (oldIndices.empty()) + continue; + size_t oldIdx = oldIndices.front(); + treeFlags->GetEntry(oldIdx); + for (auto &fh : flagBranches) { + fh->copyValue(); + } + treeFlagsOut->Fill(); + } + std::cout << " Wrote O2bcflag with " << treeFlagsOut->GetEntries() + << " entries" << std::endl; + treeFlagsOut->Write(); + } + + // --- Rewrite trees with fIndexBCs --- + for (auto tree : treesWithBCid) { + std::cout << " Reindexing tree " << tree->GetName() << std::endl; + dirOut->cd(); + TTree *treeOut = tree->CloneTree(0); + Int_t oldBCid, newBCid; + tree->SetBranchAddress("fIndexBCs", &oldBCid); + treeOut->SetBranchAddress("fIndexBCs", &newBCid); + for (Long64_t i = 0; i < tree->GetEntries(); i++) { + tree->GetEntry(i); + newBCid = indexMap[oldBCid]; + treeOut->Fill(); + } + std::cout << " Wrote " << treeOut->GetEntries() << " entries" + << std::endl; + treeOut->Write(); + } + + // Copy unaffected objects + for (auto obj : otherObjects) { + copyObject(obj, dirOut); + } +} + +void AODBcRewriter(const char *inFileName = "input.root", + const char *outFileName = "output.root") { + TFile *fin = TFile::Open(inFileName, "READ"); + TFile *fout = TFile::Open(outFileName, "RECREATE"); + fout->SetCompressionSettings(fin->GetCompressionSettings()); + for (auto keyObj : *(fin->GetListOfKeys())) { + TKey *key = (TKey *)keyObj; + TObject *obj = key->ReadObj(); + if (obj->InheritsFrom(TDirectory::Class()) && + TString(key->GetName()).BeginsWith("DF_")) + processDF((TDirectory *)obj, fout->mkdir(key->GetName())); + else { + fout->cd(); + copyObject(obj, fout); + } + } + fout->Close(); + fin->Close(); +} From ba0105c2c56fc633dc37d1bbfc2249567d508897 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 21 Aug 2025 06:00:27 +0200 Subject: [PATCH 049/362] 2stage testing logfile keeping --- MC/run/ANCHOR/tests/test_looper.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MC/run/ANCHOR/tests/test_looper.sh b/MC/run/ANCHOR/tests/test_looper.sh index 7a356242e..f9db7b110 100755 --- a/MC/run/ANCHOR/tests/test_looper.sh +++ b/MC/run/ANCHOR/tests/test_looper.sh @@ -40,6 +40,8 @@ for i in "${!headers[@]}"; do headers[$i]=$(echo "${headers[$i]}" | sed -E 's/#?%\{//;s/\}//g') done +TOPWORKDIR="" + # Read and process each subsequent line { read # Skip the header line @@ -160,6 +162,8 @@ for s in submit*.sh; do if [[ -z ${WORKFLOWS_FOUND} || -z ${AODS_FOUND} ]]; then echo "❌ Missing files for case $s: Check here for logs ${urls[${s}]}" FINAL_SUCCESS=1 # mark as failure + # also upload log file to AliEn for later inspection + alien.py cp file:./log_${s} alien:~/${TOPWORKDIR} else echo "✅ Files found in $s" fi From fef755cf0470458574b1b79549ff2b5e9c7fae7e Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 22 Aug 2025 19:05:34 +0200 Subject: [PATCH 050/362] Fix decreasing time trend of loopers in last event (#2102) --- MC/config/common/external/generator/TPCLoopers.C | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/MC/config/common/external/generator/TPCLoopers.C b/MC/config/common/external/generator/TPCLoopers.C index 22184f451..2d2a0074b 100644 --- a/MC/config/common/external/generator/TPCLoopers.C +++ b/MC/config/common/external/generator/TPCLoopers.C @@ -5,6 +5,7 @@ #include #include "CCDB/CCDBTimeStampUtils.h" #include "CCDB/CcdbApi.h" +#include "DetectorsRaw/HBFUtils.h" // Static Ort::Env instance for multiple onnx model loading static Ort::Env global_env(ORT_LOGGING_LEVEL_WARNING, "GlobalEnv"); @@ -219,9 +220,9 @@ class GenTPCLoopers : public Generator { unsigned int nLoopers, nLoopersPairs, nLoopersCompton; LOG(debug) << "mCurrentEvent is " << mCurrentEvent; - LOG(debug) << "Current event time: " << ((mCurrentEvent < mInteractionTimeRecords.size() - 1) ? std::to_string(mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns()) : std::to_string(mIntTimeRecMean)) << " ns"; + LOG(debug) << "Current event time: " << ((mCurrentEvent < mInteractionTimeRecords.size() - 1) ? std::to_string(mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns()) : std::to_string(mTimeEnd - mInteractionTimeRecords[mCurrentEvent].bc2ns())) << " ns"; LOG(debug) << "Current time offset wrt BC: " << mInteractionTimeRecords[mCurrentEvent].getTimeOffsetWrtBC() << " ns"; - mTimeLimit = (mCurrentEvent < mInteractionTimeRecords.size() - 1) ? mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns() : mIntTimeRecMean; + mTimeLimit = (mCurrentEvent < mInteractionTimeRecords.size() - 1) ? mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns() : mTimeEnd - mInteractionTimeRecords[mCurrentEvent].bc2ns(); // With flat gas the number of loopers are adapted based on time interval widths nLoopers = mFlatGasNumber * (mTimeLimit / mIntTimeRecMean); nLoopersPairs = static_cast(std::round(nLoopers * mLoopsFractionPairs)); @@ -424,6 +425,12 @@ class GenTPCLoopers : public Generator mIntTimeRecMean += mInteractionTimeRecords[c + 1].bc2ns() - mInteractionTimeRecords[c].bc2ns(); } mIntTimeRecMean /= (mInteractionTimeRecords.size() - 1); // Average interaction time record used as reference + const auto& hbfUtils = o2::raw::HBFUtils::Instance(); + // Get the start time of the second orbit after the last interaction record + const auto& lastIR = mInteractionTimeRecords.back(); + o2::InteractionRecord finalOrbitIR(0, lastIR.orbit + 2); // Final orbit, BC = 0 + mTimeEnd = finalOrbitIR.bc2ns(); + LOG(debug) << "Final orbit start time: " << mTimeEnd << " ns while last interaction record time is " << mInteractionTimeRecords.back().bc2ns() << " ns"; } } else { mFlatGasNumber = -1; @@ -470,6 +477,7 @@ class GenTPCLoopers : public Generator Int_t mFlatGasNumber = -1; // Number of flat gas loopers per event double mIntTimeRecMean = 1.0; // Average interaction time record used for the reference double mTimeLimit = 0.0; // Time limit for the current event + double mTimeEnd = 0.0; // Time limit for the last event float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs }; From a7b8de25754f908d0b93de589e89260a85b1cb52 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 26 Aug 2025 13:40:21 +0200 Subject: [PATCH 051/362] Iteration on AODBcRewriter Rewrite of AODBcRewriter, now including resorting of TTree refering to fIndexBC. This is necessary since index columns need to be sorted. Also adding 2 tools to check for BC monotonicity in AO2D as well as fIndexBC monotonicity in all tables. Codes are AI co-generated. --- MC/bin/o2dpg_sim_workflow.py | 4 +- MC/utils/AODBcRewriter.C | 1155 +++++++++++++++++----- MC/utils/AOD_check_globalBC_monotonic.C | 141 +++ MC/utils/AOD_detect_unsorted_fIndexBCs.C | 260 +++++ 4 files changed, 1328 insertions(+), 232 deletions(-) create mode 100644 MC/utils/AOD_check_globalBC_monotonic.C create mode 100644 MC/utils/AOD_detect_unsorted_fIndexBCs.C diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index fa57b4aea..ee6de3209 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1951,11 +1951,11 @@ def remove_json_prefix(path): AOD_merge_task['cmd'] = ' set -e ; [ -f aodmerge_input.txt ] && rm aodmerge_input.txt; ' AOD_merge_task['cmd'] += ' for i in `seq 1 ' + str(NTIMEFRAMES) + '`; do echo "tf${i}/AO2D.root" >> aodmerge_input.txt; done; ' AOD_merge_task['cmd'] += ' o2-aod-merger --input aodmerge_input.txt --output AO2D_pre.root' - # produce MonaLisa event stat file - AOD_merge_task['cmd'] += ' ; ${O2DPG_ROOT}/MC/bin/o2dpg_determine_eventstat.py' # reindex the BC + connected tables because it there could be duplicate BC entries due to the orbit-early treatment # see https://its.cern.ch/jira/browse/O2-6227 AOD_merge_task['cmd'] += ' ; root -q -b -l "${O2DPG_ROOT}/MC/utils/AODBcRewriter.C(\\\"AO2D_pre.root\\\",\\\"AO2D.root\\\")"' + # produce MonaLisa event stat file + AOD_merge_task['cmd'] += ' ; ${O2DPG_ROOT}/MC/bin/o2dpg_determine_eventstat.py' AOD_merge_task['alternative_alienv_package'] = "None" # we want latest software for this step workflow['stages'].append(AOD_merge_task) diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C index 23cefe437..0aa48d8f6 100644 --- a/MC/utils/AODBcRewriter.C +++ b/MC/utils/AODBcRewriter.C @@ -1,306 +1,1001 @@ -// A utility to remove duplicate bunch crossing entries -// from the O2bc_ table/TTree and to adjust all tables refering -// to fIndexBC. -// Situations of duplicate BCs can arise in O2DPG MC and are harder to avoid -// directly in the AO2D creation. This tool provides a convenient -// post-processing step to rectify the situation. -// The tool might need adjustment whenever the AO2D data format changes, for -// instance when new tables are added which are directly joinable to the BC -// table. +// AODBcRewriter.C +// Usage: root -l -b -q 'AODBcRewriter.C("AO2D.root","AO2D_rewritten.root")' +// Fixes globalBC ordering and duplication problems in AO2D files; sorts and +// rewrites tables refering to the BC table generic branch code only; No +// knowledge of AOD dataformat used apart from the BC table. -// started by sandro.wenzel@cern.ch August 2025 - -// Usage: root -l -b -q 'AODBcRewriter.C("input.root","output.root")' - -#if !defined(__CLING__) || defined(__ROOTCLING__) +#ifndef __CLING__ +#include "RVersion.h" #include "TBranch.h" +#include "TBufferFile.h" +#include "TClass.h" #include "TDirectory.h" #include "TFile.h" #include "TKey.h" #include "TLeaf.h" +#include "TList.h" +#include "TMap.h" +#include "TObjString.h" +#include "TROOT.h" #include "TString.h" #include "TTree.h" #include +#include +#include #include +#include #include #include +#include +#include #include +#include #include #endif -/// Helper to manage branch buffers and copying -struct BranchHandler { - std::string name; - std::string type; - void *inBuf = nullptr; - void *outBuf = nullptr; - TBranch *inBranch = nullptr; - TBranch *outBranch = nullptr; - - BranchHandler(TBranch *br, TTree *outTree = nullptr) { - inBranch = br; - name = br->GetName(); - TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); - type = leaf->GetTypeName(); +// ----------------- small helpers ----------------- +static inline bool isDF(const char *name) { + return TString(name).BeginsWith("DF_"); +} +static inline bool isBCtree(const char *tname) { + return TString(tname).BeginsWith("O2bc_"); +} +static inline bool isFlagsTree(const char *tname) { + return TString(tname) == "O2bcflag" || TString(tname) == "O2bcflags" || + TString(tname).BeginsWith("O2bcflag"); +} +static const char *findIndexBranchName(TTree *t) { + if (!t) + return nullptr; + if (t->GetBranch("fIndexBCs")) + return "fIndexBCs"; + if (t->GetBranch("fIndexBC")) + return "fIndexBC"; + return nullptr; +} - if (type == "Int_t") { - inBuf = new Int_t; - if (outTree) { - outBuf = new Int_t; - outBranch = outTree->Branch(name.c_str(), (Int_t *)outBuf); - } - } else if (type == "ULong64_t") { - inBuf = new ULong64_t; - if (outTree) { - outBuf = new ULong64_t; - outBranch = outTree->Branch(name.c_str(), (ULong64_t *)outBuf); - } - } else if (type == "UChar_t") { - inBuf = new UChar_t; - if (outTree) { - outBuf = new UChar_t; - outBranch = outTree->Branch(name.c_str(), (UChar_t *)outBuf); - } - } else { - std::cerr << "Unsupported type " << type << " for branch " << name - << std::endl; +// Scalar type tag +enum class ScalarTag { + kInt, + kUInt, + kShort, + kUShort, + kLong64, + kULong64, + kFloat, + kDouble, + kChar, + kUChar, + kBool, + kUnknown +}; +static ScalarTag leafType(TLeaf *leaf) { + if (!leaf) + return ScalarTag::kUnknown; + TString tn = leaf->GetTypeName(); + if (tn == "Int_t") + return ScalarTag::kInt; + if (tn == "UInt_t") + return ScalarTag::kUInt; + if (tn == "Short_t") + return ScalarTag::kShort; + if (tn == "UShort_t") + return ScalarTag::kUShort; + if (tn == "Long64_t") + return ScalarTag::kLong64; + if (tn == "ULong64_t") + return ScalarTag::kULong64; + if (tn == "Float_t") + return ScalarTag::kFloat; + if (tn == "Double_t") + return ScalarTag::kDouble; + if (tn == "Char_t") + return ScalarTag::kChar; + if (tn == "UChar_t") + return ScalarTag::kUChar; + if (tn == "Bool_t") + return ScalarTag::kBool; + return ScalarTag::kUnknown; +} +static size_t scalarSize(ScalarTag t) { + switch (t) { + case ScalarTag::kInt: + return sizeof(Int_t); + case ScalarTag::kUInt: + return sizeof(UInt_t); + case ScalarTag::kShort: + return sizeof(Short_t); + case ScalarTag::kUShort: + return sizeof(UShort_t); + case ScalarTag::kLong64: + return sizeof(Long64_t); + case ScalarTag::kULong64: + return sizeof(ULong64_t); + case ScalarTag::kFloat: + return sizeof(Float_t); + case ScalarTag::kDouble: + return sizeof(Double_t); + case ScalarTag::kChar: + return sizeof(Char_t); + case ScalarTag::kUChar: + return sizeof(UChar_t); + case ScalarTag::kBool: + return sizeof(Bool_t); + default: + return 0; + } +} + +// small Buffer base for lifetime management +struct BufBase { + virtual ~BufBase() {} + virtual void *ptr() = 0; +}; +template struct ScalarBuf : BufBase { + T v; + void *ptr() override { return &v; } +}; +template struct ArrayBuf : BufBase { + std::vector a; + void *ptr() override { return a.data(); } +}; + +template static std::unique_ptr makeScalarBuf() { + return std::make_unique>(); +} +template static std::unique_ptr makeArrayBuf(size_t n) { + auto p = std::make_unique>(); + if (n == 0) + n = 1; + p->a.resize(n); + return p; +} + +// prescan the count branch to determine max length for a VLA +static Long64_t prescanMaxLen(TTree *src, TBranch *countBr, + ScalarTag countTag) { + if (!countBr) + return 1; + // temporary buffer + std::unique_ptr tmp; + switch (countTag) { + case ScalarTag::kInt: + tmp = makeScalarBuf(); + break; + case ScalarTag::kUInt: + tmp = makeScalarBuf(); + break; + case ScalarTag::kShort: + tmp = makeScalarBuf(); + break; + case ScalarTag::kUShort: + tmp = makeScalarBuf(); + break; + case ScalarTag::kLong64: + tmp = makeScalarBuf(); + break; + case ScalarTag::kULong64: + tmp = makeScalarBuf(); + break; + default: + tmp = makeScalarBuf(); + break; + } + countBr->SetAddress(tmp->ptr()); + Long64_t maxLen = 0; + Long64_t nEnt = src->GetEntries(); + for (Long64_t i = 0; i < nEnt; ++i) { + countBr->GetEntry(i); + Long64_t v = 0; + switch (countTag) { + case ScalarTag::kInt: + v = *(Int_t *)tmp->ptr(); + break; + case ScalarTag::kUInt: + v = *(UInt_t *)tmp->ptr(); + break; + case ScalarTag::kShort: + v = *(Short_t *)tmp->ptr(); + break; + case ScalarTag::kUShort: + v = *(UShort_t *)tmp->ptr(); + break; + case ScalarTag::kLong64: + v = *(Long64_t *)tmp->ptr(); + break; + case ScalarTag::kULong64: + v = *(ULong64_t *)tmp->ptr(); + break; + default: + v = *(Int_t *)tmp->ptr(); + break; } - if (inBuf) - inBranch->SetAddress(inBuf); + if (v > maxLen) + maxLen = v; + } + return maxLen; +} + +// bind scalar branch (in and out share same buffer) +static std::unique_ptr bindScalarBranch(TBranch *inBr, TBranch *outBr, + ScalarTag tag) { + switch (tag) { + case ScalarTag::kInt: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kUInt: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kShort: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kUShort: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kLong64: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kULong64: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kFloat: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kDouble: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kChar: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + case ScalarTag::kUChar: { + auto b = makeScalarBuf(); + inBr->SetAddress(b->ptr()); + outBr->SetAddress(b->ptr()); + return b; + } + default: + return nullptr; + } +} + +// bind VLA typed: returns data buffer and outputs count buffer (via +// outCountBuf) +template +static std::unique_ptr +bindArrayTyped(TBranch *inData, TBranch *outData, TBranch *inCount, + TBranch *outCount, ScalarTag countTag, Long64_t maxLen, + std::unique_ptr &outCountBuf) { + // create count buffer + std::unique_ptr countBuf; + switch (countTag) { + case ScalarTag::kInt: + countBuf = makeScalarBuf(); + break; + case ScalarTag::kUInt: + countBuf = makeScalarBuf(); + break; + case ScalarTag::kShort: + countBuf = makeScalarBuf(); + break; + case ScalarTag::kUShort: + countBuf = makeScalarBuf(); + break; + case ScalarTag::kLong64: + countBuf = makeScalarBuf(); + break; + case ScalarTag::kULong64: + countBuf = makeScalarBuf(); + break; + default: + countBuf = makeScalarBuf(); + break; + } + // data buffer (allocate maxLen) + auto dataBuf = makeArrayBuf((size_t)std::max(1, maxLen)); + + inCount->SetAddress(countBuf->ptr()); + outCount->SetAddress(countBuf->ptr()); + inData->SetAddress(dataBuf->ptr()); + outData->SetAddress(dataBuf->ptr()); + + outCountBuf = std::move(countBuf); + return dataBuf; +} + +// ----------------- BC maps builder ----------------- +struct BCMaps { + std::vector originalBCs; + std::vector indexMap; + std::vector uniqueBCs; + std::unordered_map> newIndexOrigins; +}; + +static BCMaps buildBCMaps(TTree *treeBCs) { + BCMaps maps; + if (!treeBCs) + return maps; + TBranch *br = treeBCs->GetBranch("fGlobalBC"); + if (!br) { + std::cerr << "ERROR: no fGlobalBC\n"; + return maps; + } + ULong64_t v = 0; + br->SetAddress(&v); + Long64_t n = treeBCs->GetEntries(); + maps.originalBCs.reserve(n); + for (Long64_t i = 0; i < n; ++i) { + treeBCs->GetEntry(i); + maps.originalBCs.push_back(v); } - void copyValue() { - if (inBuf && outBuf) { - TLeaf *leaf = (TLeaf *)inBranch->GetListOfLeaves()->At(0); - size_t sz = leaf->GetLenType(); - memcpy(outBuf, inBuf, sz); + std::vector order(n); + std::iota(order.begin(), order.end(), 0); + std::sort(order.begin(), order.end(), [&](size_t a, size_t b) { + return maps.originalBCs[a] < maps.originalBCs[b]; + }); + + maps.indexMap.assign(n, -1); + Int_t newIdx = -1; + ULong64_t prev = ULong64_t(-1); + for (auto oldIdx : order) { + ULong64_t val = maps.originalBCs[oldIdx]; + if (newIdx < 0 || val != prev) { + ++newIdx; + prev = val; + maps.uniqueBCs.push_back(val); } + maps.indexMap[oldIdx] = newIdx; + maps.newIndexOrigins[newIdx].push_back(oldIdx); } + std::cout << " BCMaps: oldEntries=" << n + << " unique=" << maps.uniqueBCs.size() << "\n"; + return maps; +} - ~BranchHandler() { deleteBuffer(); } +// ----------------- small helper used for BC/flags copy ----------------- +/* + copyTreeSimple: + - inTree: input tree (assumed POD-only of types Int_t, ULong64_t, UChar_t) + - entryMap: list of input-entry indices to use, in desired output order; + (size_t)-1 entries are skipped + - outName: name for the output tree +*/ +static TTree *copyTreeSimple(TTree *inTree, const std::vector &entryMap, + const char *outName = nullptr) { + if (!inTree) + return nullptr; + TString tname = outName ? outName : inTree->GetName(); + TTree *outTree = new TTree(tname, "rebuilt tree"); + + std::vector inBufs, outBufs; + std::vector inBranches; + std::vector types; + std::vector leafCodes; + std::vector bnames; + + for (auto brObj : *inTree->GetListOfBranches()) { + TBranch *br = (TBranch *)brObj; + TString bname = br->GetName(); + TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); + if (!leaf) + continue; + TString type = leaf->GetTypeName(); + + void *inBuf = nullptr; + void *outBuf = nullptr; + TString leafCode; - void deleteBuffer() { if (type == "Int_t") { - delete (Int_t *)inBuf; - delete (Int_t *)outBuf; + inBuf = new Int_t; + outBuf = new Int_t; + leafCode = "I"; } else if (type == "ULong64_t") { - delete (ULong64_t *)inBuf; - delete (ULong64_t *)outBuf; + inBuf = new ULong64_t; + outBuf = new ULong64_t; + leafCode = "l"; } else if (type == "UChar_t") { - delete (UChar_t *)inBuf; - delete (UChar_t *)outBuf; + inBuf = new UChar_t; + outBuf = new UChar_t; + leafCode = "b"; + } else { + std::cerr << "Unsupported branch type " << type << " in " + << inTree->GetName() << " branch " << bname << " — skipping\n"; + continue; } - inBuf = outBuf = nullptr; + + br->SetAddress(inBuf); + outTree->Branch(bname, outBuf, bname + "/" + leafCode); + + inBufs.push_back(inBuf); + outBufs.push_back(outBuf); + inBranches.push_back(br); + types.push_back(type); + leafCodes.push_back(leafCode); + bnames.push_back(bname); } -}; -/// Copy any TObject (tree or dir handled recursively) -void copyObject(TObject *obj, TDirectory *outDir) { - if (!obj || !outDir) - return; - outDir->cd(); - if (obj->InheritsFrom("TDirectory")) { - TDirectory *srcDir = (TDirectory *)obj; - std::cout << "📂 Copying directory: " << srcDir->GetName() << std::endl; - TDirectory *newDir = outDir->mkdir(srcDir->GetName()); - TIter nextKey(srcDir->GetListOfKeys()); - TKey *key; - while ((key = (TKey *)nextKey())) { - TObject *subObj = key->ReadObj(); - copyObject(subObj, newDir); + // fill using entryMap (representative input indices) + for (size_t idx : entryMap) { + if (idx == (size_t)-1) + continue; + inTree->GetEntry((Long64_t)idx); + for (size_t ib = 0; ib < inBranches.size(); ++ib) { + if (types[ib] == "Int_t") + *(Int_t *)outBufs[ib] = *(Int_t *)inBufs[ib]; + else if (types[ib] == "ULong64_t") + *(ULong64_t *)outBufs[ib] = *(ULong64_t *)inBufs[ib]; + else if (types[ib] == "UChar_t") + *(UChar_t *)outBufs[ib] = *(UChar_t *)inBufs[ib]; } - } else if (obj->InheritsFrom("TTree")) { - TTree *t = (TTree *)obj; - std::cout << " Copying untouched TTree: " << t->GetName() << std::endl; - TTree *tnew = t->CloneTree(-1, "fast"); - tnew->SetDirectory(outDir); - tnew->Write(); - } else { - std::cout << " Copying object: " << obj->GetName() << " [" - << obj->ClassName() << "]" << std::endl; - obj->Write(); + outTree->Fill(); } + + return outTree; } -/// Process one DF_* directory -void processDF(TDirectory *dirIn, TDirectory *dirOut) { - std::cout << "\n====================================================" - << std::endl; - std::cout << "▶ Processing DF folder: " << dirIn->GetName() << std::endl; +// ----------------- Rebuild BCs and Flags (refactored) ----------------- +void rebuildBCsAndFlags(TDirectory *dirIn, TDirectory *dirOut, TTree *&outBCs, + BCMaps &maps) { + std::cout << "------------------------------------------------\n"; + std::cout << "Rebuild BCs+flags in " << dirIn->GetName() << "\n"; + // find O2bc_* (pick first matching) and O2bcflag TTree *treeBCs = nullptr; TTree *treeFlags = nullptr; - std::vector treesWithBCid; - std::vector otherObjects; - - // Inspect folder contents - for (auto subkeyObj : *(dirIn->GetListOfKeys())) { - TKey *subkey = (TKey *)subkeyObj; - TObject *obj = dirIn->Get(subkey->GetName()); - if (obj->InheritsFrom(TTree::Class())) { - TTree *tree = (TTree *)obj; - TString tname = tree->GetName(); - if (tname.BeginsWith("O2bc_")) { - treeBCs = tree; - std::cout << " Found O2bc: " << tname << std::endl; - } else if (tname == "O2bcflag") { - // this is a special table as it is directly joinable to O2bc - // according to the datamodel - treeFlags = tree; - std::cout << " Found O2bcflag" << std::endl; - } else if (tree->GetBranch("fIndexBCs")) { - treesWithBCid.push_back(tree); - std::cout << " Needs reindex: " << tname << std::endl; - } else { - otherObjects.push_back(tree); - std::cout << " Unaffected TTree: " << tname << std::endl; - } - } else { - otherObjects.push_back(obj); + + for (auto keyObj : *dirIn->GetListOfKeys()) { + TKey *key = (TKey *)keyObj; + TObject *obj = dirIn->Get(key->GetName()); + if (!obj) + continue; + if (!obj->InheritsFrom(TTree::Class())) + continue; + TTree *t = (TTree *)obj; + if (isBCtree(t->GetName())) { + treeBCs = t; + } else if (isFlagsTree(t->GetName())) { + treeFlags = t; } } if (!treeBCs) { - std::cout << "⚠ No O2bc found in " << dirIn->GetName() - << " → just copying objects" << std::endl; - for (auto obj : otherObjects) { - copyObject(obj, dirOut); - } + std::cerr << " No BCs tree found in " << dirIn->GetName() + << " — skipping\n"; + outBCs = nullptr; return; } - // Read fGlobalBC values - ULong64_t fGlobalBC; - treeBCs->SetBranchAddress("fGlobalBC", &fGlobalBC); - std::vector originalBCs(treeBCs->GetEntries()); - for (Long64_t i = 0; i < treeBCs->GetEntries(); i++) { - treeBCs->GetEntry(i); - originalBCs[i] = fGlobalBC; + // build maps (dedupe/sort) + maps = buildBCMaps(treeBCs); + + // build representative entryMap: one input entry per new BC index (use first + // contributor) + std::vector entryMap(maps.uniqueBCs.size(), (size_t)-1); + for (size_t newIdx = 0; newIdx < maps.uniqueBCs.size(); ++newIdx) { + const auto &vec = maps.newIndexOrigins.at(newIdx); + if (!vec.empty()) + entryMap[newIdx] = vec.front(); } - std::cout << " O2bc entries: " << originalBCs.size() << std::endl; + dirOut->cd(); + // copy BCs tree using representative entries + outBCs = copyTreeSimple(treeBCs, entryMap, treeBCs->GetName()); + if (outBCs) { + outBCs->SetDirectory(dirOut); + outBCs->Write(); + std::cout << " Wrote " << outBCs->GetName() << " with " + << outBCs->GetEntries() << " entries\n"; + } - // Build mapping - std::vector indexMap(originalBCs.size(), -1); - std::vector uniqueBCs; - std::vector order(originalBCs.size()); - std::iota(order.begin(), order.end(), 0); - std::sort(order.begin(), order.end(), [&](size_t a, size_t b) { - return originalBCs[a] < originalBCs[b]; - }); - Int_t newIdx = -1; - ULong64_t prevVal = -1; - std::unordered_map> newIndexOrigins; - for (auto oldIdx : order) { - ULong64_t val = originalBCs[oldIdx]; - if (newIdx < 0 || val != prevVal) { - ++newIdx; - prevVal = val; - uniqueBCs.push_back(val); + // copy flags if present + if (treeFlags) { + TTree *outFlags = copyTreeSimple(treeFlags, entryMap, treeFlags->GetName()); + if (outFlags) { + outFlags->SetDirectory(dirOut); + outFlags->Write(); + std::cout << " Wrote " << outFlags->GetName() << " with " + << outFlags->GetEntries() << " entries\n"; } - indexMap[oldIdx] = newIdx; - newIndexOrigins[newIdx].push_back(oldIdx); } - std::cout << " Unique BCs after deduplication: " << uniqueBCs.size() - << std::endl; +} - // --- Rewrite O2bc --- - dirOut->cd(); - TTree *treeBCsOut = new TTree(treeBCs->GetName(), "fixed O2bc tree"); - std::vector> bcBranches; - for (auto brObj : *treeBCs->GetListOfBranches()) { - TBranch *br = (TBranch *)brObj; - if (TString(br->GetName()) == "fGlobalBC") +// ----------------- payload rewriting with VLA support ----------------- +struct SortKey { + Long64_t entry; + Long64_t newBC; +}; + +static bool isVLA(TBranch *br) { + if (!br) + return false; + TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); + return leaf && leaf->GetLeafCount(); +} + +// This is the VLA-aware rewritePayloadSorted implementation (keeps previous +// tested behavior) +static void rewritePayloadSorted(TDirectory *dirIn, TDirectory *dirOut, + const BCMaps &maps) { + std::unordered_set skipNames; // for count branches + TIter it(dirIn->GetListOfKeys()); + while (TKey *k = (TKey *)it()) { + if (TString(k->GetClassName()) != "TTree") continue; - bcBranches.emplace_back(std::make_unique(br, treeBCsOut)); - } - ULong64_t outBC; - treeBCsOut->Branch("fGlobalBC", &outBC, "fGlobalBC/l"); + std::unique_ptr holder(k->ReadObj()); // keep alive + TTree *src = dynamic_cast(holder.get()); + if (!src) + continue; + const char *tname = src->GetName(); - for (int newIdx = 0; newIdx < uniqueBCs.size(); newIdx++) { - auto &oldIndices = newIndexOrigins[newIdx]; - if (oldIndices.empty()) + if (isBCtree(tname) || isFlagsTree(tname)) { + std::cout << " skipping BC/flag tree " << tname << "\n"; continue; - size_t oldIdx = oldIndices.front(); - treeBCs->GetEntry(oldIdx); - outBC = originalBCs[oldIdx]; - for (auto &bh : bcBranches) { - bh->copyValue(); } - treeBCsOut->Fill(); - } - std::cout << " Wrote O2bc with " << treeBCsOut->GetEntries() << " entries" - << std::endl; - treeBCsOut->Write(); - // --- Rewrite O2bcflag --- - if (treeFlags) { - std::cout << " Rebuilding O2bcflag..." << std::endl; + const char *idxName = findIndexBranchName(src); + if (!idxName) { + dirOut->cd(); + std::cout << " [copy] " << tname << " (no index) -> cloning\n"; + TTree *c = src->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); + c->Write(); + continue; + } + + std::cout << " [proc] reindex+SORT " << tname << " (index=" << idxName + << ")\n"; + // detect index type and bind input buffer + TBranch *inIdxBr = src->GetBranch(idxName); + if (!inIdxBr) { + std::cerr << " ERR no index branch found\n"; + continue; + } + TLeaf *idxLeaf = (TLeaf *)inIdxBr->GetListOfLeaves()->At(0); + TString idxType = idxLeaf->GetTypeName(); + + enum class IdKind { kI, kUi, kS, kUs, kUnknown }; + IdKind idk = IdKind::kUnknown; + Int_t oldI = 0, newI = 0; + UInt_t oldUi = 0, newUi = 0; + Short_t oldS = 0, newS = 0; + UShort_t oldUs = 0, newUs = 0; + + if (idxType == "Int_t") { + idk = IdKind::kI; + inIdxBr->SetAddress(&oldI); + } else if (idxType == "UInt_t") { + idk = IdKind::kUi; + inIdxBr->SetAddress(&oldUi); + } else if (idxType == "Short_t") { + idk = IdKind::kS; + inIdxBr->SetAddress(&oldS); + } else if (idxType == "UShort_t") { + idk = IdKind::kUs; + inIdxBr->SetAddress(&oldUs); + } else { + std::cerr << " unsupported index type " << idxType + << " -> cloning as-is\n"; + dirOut->cd(); + auto *c = src->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); + c->Write(); + continue; + } + + // build keys vector + Long64_t nEnt = src->GetEntries(); + std::vector keys; + keys.reserve(nEnt); + for (Long64_t i = 0; i < nEnt; ++i) { + inIdxBr->GetEntry(i); + Long64_t oldIdx = 0; + switch (idk) { + case IdKind::kI: + oldIdx = oldI; + break; + case IdKind::kUi: + oldIdx = oldUi; + break; + case IdKind::kS: + oldIdx = oldS; + break; + case IdKind::kUs: + oldIdx = oldUs; + break; + default: + break; + } + Long64_t newBC = -1; + if (oldIdx >= 0 && (size_t)oldIdx < maps.indexMap.size()) + newBC = maps.indexMap[(size_t)oldIdx]; + keys.push_back({i, newBC}); + } + + std::stable_sort(keys.begin(), keys.end(), + [](const SortKey &a, const SortKey &b) { + bool ai = (a.newBC < 0), bi = (b.newBC < 0); + if (ai != bi) + return !ai && bi; // valid first + if (a.newBC != b.newBC) + return a.newBC < b.newBC; + return a.entry < b.entry; + }); + + // prepare output tree dirOut->cd(); - TTree *treeFlagsOut = treeFlags->CloneTree(0); - std::vector> flagBranches; - for (auto brObj : *treeFlags->GetListOfBranches()) { - TBranch *br = (TBranch *)brObj; - flagBranches.emplace_back( - std::make_unique(br, treeFlagsOut)); + TTree *out = src->CloneTree(0, "fast"); + // map branches + std::unordered_map inBranches, outBranches; + for (auto *bobj : *src->GetListOfBranches()) + inBranches[((TBranch *)bobj)->GetName()] = (TBranch *)bobj; + for (auto *bobj : *out->GetListOfBranches()) + outBranches[((TBranch *)bobj)->GetName()] = (TBranch *)bobj; + + // allocate buffers and bind: scalars & VLAs + std::vector> scalarBuffers; // shared in/out + std::vector> vlaDataBuffers; + std::vector> vlaCountBuffers; + std::vector vlaMaxLens; + std::vector vlaCountTags; + // bind index branch in output to new variable + TBranch *outIdxBr = out->GetBranch(idxName); + switch (idk) { + case IdKind::kI: + outIdxBr->SetAddress(&newI); + break; + case IdKind::kUi: + outIdxBr->SetAddress(&newUi); + break; + case IdKind::kS: + outIdxBr->SetAddress(&newS); + break; + case IdKind::kUs: + outIdxBr->SetAddress(&newUs); + break; + default: + break; } - for (int newIdx = 0; newIdx < uniqueBCs.size(); newIdx++) { - auto &oldIndices = newIndexOrigins[newIdx]; - if (oldIndices.empty()) + skipNames.clear(); + skipNames.insert(idxName); + + // loop inBranches and bind + for (auto &kv : inBranches) { + const std::string bname = kv.first; + if (skipNames.count(bname)) + continue; + TBranch *inBr = kv.second; + TBranch *ouBr = outBranches.count(bname) ? outBranches[bname] : nullptr; + if (!ouBr) { + std::cerr << " [warn] no out branch for " << bname << " -> skip\n"; continue; - size_t oldIdx = oldIndices.front(); - treeFlags->GetEntry(oldIdx); - for (auto &fh : flagBranches) { - fh->copyValue(); } - treeFlagsOut->Fill(); + TLeaf *leaf = (TLeaf *)inBr->GetListOfLeaves()->At(0); + if (!leaf) { + std::cerr << " [warn] branch w/o leaf " << bname << "\n"; + continue; + } + + if (!isVLA(inBr)) { + // scalar + ScalarTag tag = leafType(leaf); + if (tag == ScalarTag::kUnknown) { + std::cerr << " [warn] unknown scalar type " + << leaf->GetTypeName() << " for " << bname << "\n"; + continue; + } + auto sb = bindScalarBranch(inBr, ouBr, tag); + if (sb) + scalarBuffers.emplace_back(std::move(sb)); + } else { + // VLA -> find count leaf & branch + TLeaf *cntLeaf = leaf->GetLeafCount(); + if (!cntLeaf) { + std::cerr << " [warn] VLA " << bname + << " has no count leaf -> skip\n"; + continue; + } + TBranch *inCnt = cntLeaf->GetBranch(); + TBranch *outCnt = outBranches.count(inCnt->GetName()) + ? outBranches[inCnt->GetName()] + : nullptr; + if (!outCnt) { + std::cerr << " [warn] missing out count branch " + << inCnt->GetName() << " for VLA " << bname << "\n"; + continue; + } + // avoid double-binding count branch as scalar later + skipNames.insert(inCnt->GetName()); + // detect tags + ScalarTag dataTag = leafType(leaf); + ScalarTag cntTag = leafType(cntLeaf); + if (dataTag == ScalarTag::kUnknown || cntTag == ScalarTag::kUnknown) { + std::cerr << " [warn] unsupported VLA types for " << bname + << "\n"; + continue; + } + // prescan max len + Long64_t maxLen = prescanMaxLen(src, inCnt, cntTag); + if (maxLen <= 0) + maxLen = leaf->GetMaximum(); + if (maxLen <= 0) + maxLen = 1; + // bind typed + std::unique_ptr countBufLocal; + std::unique_ptr dataBufLocal; + switch (dataTag) { + case ScalarTag::kInt: + dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, + cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kUInt: + dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, + cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kShort: + dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, + cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kUShort: + dataBufLocal = bindArrayTyped( + inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kLong64: + dataBufLocal = bindArrayTyped( + inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kULong64: + dataBufLocal = bindArrayTyped( + inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kFloat: + dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, + cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kDouble: + dataBufLocal = bindArrayTyped( + inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kChar: + dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, + cntTag, maxLen, countBufLocal); + break; + case ScalarTag::kUChar: + dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, + cntTag, maxLen, countBufLocal); + break; + default: + break; + } + if (dataBufLocal) + vlaDataBuffers.emplace_back(std::move(dataBufLocal)); + if (countBufLocal) { + vlaCountBuffers.emplace_back(std::move(countBufLocal)); + vlaMaxLens.push_back(maxLen); + vlaCountTags.push_back(cntTag); + } + } + } // end for branches + + // Now fill out in sorted order. For each key: src->GetEntry(entry) -> clamp + // counts -> set new index -> out->Fill() + Long64_t changed = 0; + for (const auto &sk : keys) { + src->GetEntry(sk.entry); + + // clamp count buffers before fill + for (size_t ic = 0; ic < vlaCountBuffers.size(); ++ic) { + void *p = vlaCountBuffers[ic]->ptr(); + Long64_t cnt = 0; + switch (vlaCountTags[ic]) { + case ScalarTag::kInt: + cnt = *(Int_t *)p; + break; + case ScalarTag::kUInt: + cnt = *(UInt_t *)p; + break; + case ScalarTag::kShort: + cnt = *(Short_t *)p; + break; + case ScalarTag::kUShort: + cnt = *(UShort_t *)p; + break; + case ScalarTag::kLong64: + cnt = *(Long64_t *)p; + break; + case ScalarTag::kULong64: + cnt = *(ULong64_t *)p; + break; + default: + cnt = *(Int_t *)p; + break; + } + if (cnt < 0) + cnt = 0; + if (cnt > vlaMaxLens[ic]) { + std::cerr << "WARNING: clamping VLA count " << cnt << " to max " + << vlaMaxLens[ic] << " for tree " << tname << "\n"; + // write back + if (vlaMaxLens[ic] <= std::numeric_limits::max()) { + *(Int_t *)p = (Int_t)vlaMaxLens[ic]; + } else { + *(Long64_t *)p = (Long64_t)vlaMaxLens[ic]; + } + } + } + + // set new index value in out buffer + switch (idk) { + case IdKind::kI: { + Int_t prev = oldI; + newI = (sk.newBC >= 0 ? (Int_t)sk.newBC : -1); + if (newI != prev) + ++changed; + } break; + case IdKind::kUi: { + UInt_t prev = oldUi; + newUi = (sk.newBC >= 0 ? (UInt_t)sk.newBC : 0u); + if (newUi != prev) + ++changed; + } break; + case IdKind::kS: { + Short_t prev = oldS; + newS = (sk.newBC >= 0 ? (Short_t)sk.newBC : (Short_t)-1); + if (newS != prev) + ++changed; + } break; + case IdKind::kUs: { + UShort_t prev = oldUs; + newUs = (sk.newBC >= 0 ? (UShort_t)sk.newBC : (UShort_t)0); + if (newUs != prev) + ++changed; + } break; + default: + break; + } + + out->Fill(); } - std::cout << " Wrote O2bcflag with " << treeFlagsOut->GetEntries() - << " entries" << std::endl; - treeFlagsOut->Write(); - } - // --- Rewrite trees with fIndexBCs --- - for (auto tree : treesWithBCid) { - std::cout << " Reindexing tree " << tree->GetName() << std::endl; + std::cout << " wrote " << out->GetEntries() << " rows; remapped " + << changed << " index values; sorted\n"; + out->Write(); + } // end while keys in dir + + // non-tree objects: copy as-is (but for TMap use WriteTObject to preserve + // class) + it.Reset(); + while (TKey *k = (TKey *)it()) { + if (TString(k->GetClassName()) == "TTree") + continue; + TObject *obj = k->ReadObj(); dirOut->cd(); - TTree *treeOut = tree->CloneTree(0); - Int_t oldBCid, newBCid; - tree->SetBranchAddress("fIndexBCs", &oldBCid); - treeOut->SetBranchAddress("fIndexBCs", &newBCid); - for (Long64_t i = 0; i < tree->GetEntries(); i++) { - tree->GetEntry(i); - newBCid = indexMap[oldBCid]; - treeOut->Fill(); + if (obj->IsA()->InheritsFrom(TMap::Class())) { + std::cout << " Copying TMap " << k->GetName() << " as a whole\n"; + dirOut->WriteTObject(obj, k->GetName(), "Overwrite"); + } else { + obj->Write(k->GetName(), TObject::kOverwrite); } - std::cout << " Wrote " << treeOut->GetEntries() << " entries" - << std::endl; - treeOut->Write(); } +} - // Copy unaffected objects - for (auto obj : otherObjects) { - copyObject(obj, dirOut); +// ----------------- per-DF driver ----------------- +static void processDF(TDirectory *dIn, TDirectory *dOut) { + std::cout << "------------------------------------------------\n"; + std::cout << "Processing DF: " << dIn->GetName() << "\n"; + + // 1) rebuild BCs & flags -> maps + TTree *bcOut = nullptr; + BCMaps maps; + rebuildBCsAndFlags(dIn, dOut, bcOut, maps); + + if (!bcOut) { + std::cout << " No BCs -> deep copying directory\n"; + TIter it(dIn->GetListOfKeys()); + while (TKey *k = (TKey *)it()) { + TObject *obj = k->ReadObj(); + dOut->cd(); + if (obj->InheritsFrom(TTree::Class())) { + TTree *t = (TTree *)obj; + TTree *c = t->CloneTree(-1, "fast"); + c->SetDirectory(dOut); + c->Write(); + } else { + if (obj->IsA()->InheritsFrom(TMap::Class())) { + dOut->WriteTObject(obj, k->GetName(), "Overwrite"); + } else { + obj->Write(k->GetName(), TObject::kOverwrite); + } + } + } + return; } + + // 2) rewrite payload tables (reindex+sort) + rewritePayloadSorted(dIn, dOut, maps); + + std::cout << "Finished DF: " << dIn->GetName() << "\n"; } -void AODBcRewriter(const char *inFileName = "input.root", - const char *outFileName = "output.root") { - TFile *fin = TFile::Open(inFileName, "READ"); - TFile *fout = TFile::Open(outFileName, "RECREATE"); - fout->SetCompressionSettings(fin->GetCompressionSettings()); - for (auto keyObj : *(fin->GetListOfKeys())) { - TKey *key = (TKey *)keyObj; +// ----------------- top-level driver ----------------- +void AODBcRewriter(const char *inFileName = "AO2D.root", + const char *outFileName = "AO2D_rewritten.root") { + std::cout << "Opening input file: " << inFileName << "\n"; + std::unique_ptr fin(TFile::Open(inFileName, "READ")); + if (!fin || fin->IsZombie()) { + std::cerr << "ERROR opening input\n"; + return; + } + + int algo = fin->GetCompressionAlgorithm(); + int lvl = fin->GetCompressionLevel(); + std::cout << "Input compression: algo=" << algo << " level=" << lvl << "\n"; + + // create output applying same compression level when available +#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 30, 0) + std::unique_ptr fout(TFile::Open(outFileName, "RECREATE", "", lvl)); +#else + std::unique_ptr fout(TFile::Open(outFileName, "RECREATE")); +#endif + if (!fout || fout->IsZombie()) { + std::cerr << "ERROR creating output\n"; + return; + } + fout->SetCompressionAlgorithm(algo); + fout->SetCompressionLevel(lvl); + + // top-level keys + TIter top(fin->GetListOfKeys()); + while (TKey *key = (TKey *)top()) { + TString name = key->GetName(); TObject *obj = key->ReadObj(); - if (obj->InheritsFrom(TDirectory::Class()) && - TString(key->GetName()).BeginsWith("DF_")) - processDF((TDirectory *)obj, fout->mkdir(key->GetName())); - else { + if (obj->InheritsFrom(TDirectory::Class()) && isDF(name)) { + std::cout << "Found DF folder: " << name << "\n"; + TDirectory *din = (TDirectory *)obj; + TDirectory *dout = fout->mkdir(name); + processDF(din, dout); + } else { fout->cd(); - copyObject(obj, fout); + if (obj->IsA()->InheritsFrom(TMap::Class())) { + std::cout << "Copying top-level TMap: " << name << "\n"; + fout->WriteTObject(obj, name, "Overwrite"); + } else { + std::cout << "Copying top-level object: " << name << " [" + << obj->ClassName() << "]\n"; + obj->Write(name, TObject::kOverwrite); + } } } + + fout->Write("", TObject::kOverwrite); fout->Close(); fin->Close(); + std::cout << "All done. Output written to " << outFileName << "\n"; } diff --git a/MC/utils/AOD_check_globalBC_monotonic.C b/MC/utils/AOD_check_globalBC_monotonic.C new file mode 100644 index 000000000..b92472d5e --- /dev/null +++ b/MC/utils/AOD_check_globalBC_monotonic.C @@ -0,0 +1,141 @@ +// Scans all DF_* folders for O2bc_001 TTrees and checks that the +// fGlobalBC branch (ULong64_t) is monotonically non-decreasing. + +#ifndef __CLING__ +#include "TBranch.h" +#include "TDirectory.h" +#include "TFile.h" +#include "TKey.h" +#include "TLeaf.h" +#include "TTree.h" +#include +#include +#include +#endif + +struct BCReport { + bool hasBranch = false; + bool monotonic = true; + Long64_t entries = 0; + Long64_t firstViolationEntry = -1; + Long64_t nViolations = 0; + ULong64_t maxBackwardJump = 0; + std::vector>> samples; +}; + +static BCReport checkO2bcTree(TTree *t) { + BCReport r; + if (!t) + return r; + + TBranch *br = t->GetBranch("fGlobalBC"); + if (!br) + return r; + r.hasBranch = true; + + ULong64_t buf = 0; + br->SetAddress(&buf); + + r.entries = t->GetEntries(); + if (r.entries <= 1) + return r; + + bool havePrev = false; + ULong64_t prevVal = 0; + + for (Long64_t i = 0; i < r.entries; ++i) { + t->GetEntry(i); + ULong64_t v = buf; + + if (!havePrev) { + prevVal = v; + havePrev = true; + continue; + } + + if (v < prevVal) { + if (r.firstViolationEntry < 0) + r.firstViolationEntry = i; + ++r.nViolations; + r.monotonic = false; + ULong64_t jump = prevVal - v; + if (jump > r.maxBackwardJump) + r.maxBackwardJump = jump; + if (r.samples.size() < 5) + r.samples.push_back({i, {prevVal, v}}); + } + + prevVal = v; + } + + return r; +} + +void AOD_check_globalBC_monotonic(const char *inFileName = "AO2D.root") { + std::string inFileStr(inFileName); + if (inFileStr.find("alien:") != std::string::npos) { + TGrid::Connect("alien"); + } + + std::cout << "Opening file: " << inFileName << std::endl; + TFile *f = TFile::Open(inFileName, "READ"); + if (!f || f->IsZombie()) { + std::cerr << "ERROR: cannot open input file.\n"; + return; + } + + Long64_t totalTrees = 0; + Long64_t totalWithBranch = 0; + Long64_t totalViolations = 0; + + TIter topKeys(f->GetListOfKeys()); + while (TKey *k = (TKey *)topKeys()) { + TObject *obj = k->ReadObj(); + if (!obj->InheritsFrom(TDirectory::Class())) + continue; + + TDirectory *dir = (TDirectory *)obj; + TString dname = dir->GetName(); + if (!dname.BeginsWith("DF_")) + continue; + + TTree *t = (TTree *)dir->Get("O2bc_001"); + if (!t) + continue; + ++totalTrees; + + BCReport r = checkO2bcTree(t); + + if (!r.hasBranch) { + std::cout << "[skip] " << dir->GetName() + << "/O2bc_001 has no fGlobalBC\n"; + continue; + } + ++totalWithBranch; + + if (r.monotonic) { + std::cout << "[ OK ] " << dir->GetName() << "/O2bc_001 — " << r.entries + << " entries, monotonic\n"; + } else { + ++totalViolations; + std::cout << "[BAD] " << dir->GetName() << "/O2bc_001 — " << r.entries + << " entries, first violation at entry " + << r.firstViolationEntry + << ", total violations: " << r.nViolations + << ", max backward jump: " << r.maxBackwardJump << "\n"; + + for (auto &s : r.samples) { + std::cout << " entry " << s.first << ": " << s.second.first + << " -> " << s.second.second << "\n"; + } + } + } + + std::cout << "\n==================== SUMMARY ====================\n"; + std::cout << "O2bc_001 trees checked: " << totalTrees << "\n"; + std::cout << "With fGlobalBC branch: " << totalWithBranch << "\n"; + std::cout << "Trees NOT monotonic: " << totalViolations << "\n"; + std::cout << "=================================================\n"; + + f->Close(); +} diff --git a/MC/utils/AOD_detect_unsorted_fIndexBCs.C b/MC/utils/AOD_detect_unsorted_fIndexBCs.C new file mode 100644 index 000000000..13571ac85 --- /dev/null +++ b/MC/utils/AOD_detect_unsorted_fIndexBCs.C @@ -0,0 +1,260 @@ +// Scans DF_* folders, finds trees with an Int-like "fIndexBCs" branch, +// and reports those where fIndexBCs is not monotonically non-decreasing. +// Negative values (e.g. -1) are ignored for the monotonicity check. + +#ifndef __CLING__ +#include "TBranch.h" +#include "TDirectory.h" +#include "TFile.h" +#include "TKey.h" +#include "TLeaf.h" +#include "TString.h" +#include "TTree.h" +#include +#include +#include +#include +#include +#endif + +struct MonotonicReport { + bool hasBranch = false; // tree has fIndexBCs + bool monotonic = true; // true if non-decreasing + Long64_t entries = 0; + Long64_t firstViolationEntry = -1; // entry index of first backward step + Long64_t nViolations = 0; // count of backward steps + Long64_t maxBackwardJump = 0; // biggest (prevValid - curr) observed + std::vector>> + samples; // (entry, (prev, curr)) +}; + +/// Try to bind a branch named "fIndexBCs" with an integral buffer. +/// Supports common integer POD types (Int_t, UInt_t, Long64_t, ULong64_t). +/// Returns: pointer to bound buffer as int64_t-compatible view (value is +/// copied), and sets branch address appropriately. +class FIndexBinder { +public: + TBranch *br = nullptr; + std::string type; + // One of these will be used based on the branch's leaf type: + Int_t buf_i = 0; + UInt_t buf_ui = 0; + Long64_t buf_l = 0; + ULong64_t buf_ul = 0; + + // which is active + enum Kind { KNone, KInt, KUInt, KLong64, KULong64 } kind = KNone; + + bool bind(TTree *t, const char *name = "fIndexBCs") { + br = t->GetBranch(name); + if (!br) + return false; + if (br->GetListOfLeaves()->GetEntries() <= 0) + return false; + TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); + type = leaf->GetTypeName(); + + if (type == "Int_t") { + kind = KInt; + br->SetAddress(&buf_i); + } else if (type == "UInt_t") { + kind = KUInt; + br->SetAddress(&buf_ui); + } else if (type == "Long64_t") { + kind = KLong64; + br->SetAddress(&buf_l); + } else if (type == "ULong64_t") { + kind = KULong64; + br->SetAddress(&buf_ul); + } else { + // not an integer POD we handle + kind = KNone; + br = nullptr; + return false; + } + return true; + } + + // Read the current value as signed 64-bit (for comparisons). + // For unsigned, cast safely to signed domain if within range; otherwise + // clamp. + Long64_t valueAsI64() const { + switch (kind) { + case KInt: + return (Long64_t)buf_i; + case KUInt: + return (buf_ui <= (UInt_t)std::numeric_limits::max() + ? (Long64_t)buf_ui + : (Long64_t)std::numeric_limits::max()); + case KLong64: + return buf_l; + case KULong64: + return (buf_ul <= (ULong64_t)std::numeric_limits::max() + ? (Long64_t)buf_ul + : (Long64_t)std::numeric_limits::max()); + default: + return 0; + } + } +}; + +static MonotonicReport checkTreeMonotonic(TTree *t, bool verbose = false) { + MonotonicReport r; + if (!t) + return r; + + // Speed up: only read the target branch + t->SetBranchStatus("*", 0); + if (t->GetBranch("fIndexBCs")) + t->SetBranchStatus("fIndexBCs", 1); + + FIndexBinder binder; + if (!binder.bind(t, "fIndexBCs")) { + r.hasBranch = false; + // Re-enable all for safety if user continues using the tree later + t->SetBranchStatus("*", 1); + return r; + } + r.hasBranch = true; + + r.entries = t->GetEntries(); + if (r.entries <= 1) { + r.monotonic = true; + t->SetBranchStatus("*", 1); + return r; + } + + bool havePrev = false; + Long64_t prevValid = 0; + + for (Long64_t i = 0; i < r.entries; ++i) { + t->GetEntry(i); + Long64_t v = binder.valueAsI64(); + + // Ignore negatives (e.g. -1 sentinel values) + if (v < 0) + continue; + + if (!havePrev) { + prevValid = v; + havePrev = true; + continue; + } + + if (v < prevValid) { + // backward step + if (r.firstViolationEntry < 0) + r.firstViolationEntry = i; + ++r.nViolations; + r.monotonic = false; + Long64_t jump = prevValid - v; + if (jump > r.maxBackwardJump) + r.maxBackwardJump = jump; + if (r.samples.size() < 5) + r.samples.push_back({i, {prevValid, v}}); + // Do not update prevValid here; we keep comparing to last valid + // non-decreasing reference + continue; + } + + // normal non-decreasing step + prevValid = v; + } + + // Restore statuses + t->SetBranchStatus("*", 1); + return r; +} + +void AOD_detect_unsorted_fIndexBCs(const char *inFileName = "AO2D.root", + bool verbosePerTree = false) { + std::cout << "Opening file: " << inFileName << std::endl; + TFile *f = TFile::Open(inFileName, "READ"); + if (!f || f->IsZombie()) { + std::cerr << "ERROR: cannot open input file.\n"; + return; + } + + Long64_t totalTreesChecked = 0; + Long64_t totalWithBranch = 0; + Long64_t totalViolations = 0; + + std::cout << "Scanning top-level for DF_* folders...\n"; + + // Iterate top-level keys + TIter kIt(f->GetListOfKeys()); + while (TKey *k = (TKey *)kIt()) { + TString kname = k->GetName(); + TObject *obj = k->ReadObj(); + + if (!obj->InheritsFrom(TDirectory::Class()) || !kname.BeginsWith("DF_")) { + continue; + } + + auto *dir = (TDirectory *)obj; + std::cout << "\n====================================================\n"; + std::cout << "DF folder: " << dir->GetName() << "\n"; + + // Iterate all keys in this DF directory + TIter dIt(dir->GetListOfKeys()); + while (TKey *dk = (TKey *)dIt()) { + TObject *tobj = dir->Get(dk->GetName()); + if (!tobj->InheritsFrom(TTree::Class())) { + continue; // only trees are relevant + } + + TTree *t = (TTree *)tobj; + ++totalTreesChecked; + + // Only consider trees that *have* fIndexBCs + if (!t->GetBranch("fIndexBCs")) { + if (verbosePerTree) { + std::cout << " [skip] " << t->GetName() << " (no fIndexBCs)\n"; + } + continue; + } + ++totalWithBranch; + + MonotonicReport r = checkTreeMonotonic(t, verbosePerTree); + + if (!r.hasBranch) { + // Shouldn't happen due to prior check, but keep robust + if (verbosePerTree) { + std::cout << " [skip] " << t->GetName() + << " (failed to bind branch)\n"; + } + continue; + } + + if (r.monotonic) { + if (verbosePerTree) { + std::cout << " [ OK ] " << t->GetName() + << " — entries: " << r.entries << " (non-decreasing)\n"; + } + } else { + ++totalViolations; + std::cout << " [BAD] " << t->GetName() << " — entries: " << r.entries + << ", first violation at entry " << r.firstViolationEntry + << ", total backward steps: " << r.nViolations + << ", max backward jump: " << r.maxBackwardJump << "\n"; + + // Print a few examples of (prev, curr) causing violation + if (!r.samples.empty()) { + std::cout << " sample backward steps (entry: prev -> curr):\n"; + for (auto &s : r.samples) { + std::cout << " " << s.first << ": " << s.second.first + << " -> " << s.second.second << "\n"; + } + } + } + } + } + + std::cout << "\n==================== SUMMARY ====================\n"; + std::cout << "Trees visited: " << totalTreesChecked << "\n"; + std::cout << "Trees with fIndexBCs: " << totalWithBranch << "\n"; + std::cout << "Trees NOT monotonic: " << totalViolations << "\n"; + std::cout << "=================================================\n"; + + f->Close(); +} From 6983ae6fce527ab69672f354d4ddb1d3db565fb2 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 22 Aug 2025 02:15:33 +0200 Subject: [PATCH 052/362] Improvements for MCProdInfo; MCProdInfo harvester tool A tool which can extract MCProdInfo from logs on the GRID. Can be used to push MCProdInfo info retroactively to the CCDB. Slight extension of MCProdInfo to contain software tags used. --- MC/bin/o2dpg_sim_workflow_anchored.py | 10 +- MC/prodinfo/mcprodinfo_ccdb_upload.py | 11 ++ MC/prodinfo/mcprodinfo_harvester.py | 189 ++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 9 deletions(-) create mode 100755 MC/prodinfo/mcprodinfo_harvester.py diff --git a/MC/bin/o2dpg_sim_workflow_anchored.py b/MC/bin/o2dpg_sim_workflow_anchored.py index 33471114a..5d60450f3 100755 --- a/MC/bin/o2dpg_sim_workflow_anchored.py +++ b/MC/bin/o2dpg_sim_workflow_anchored.py @@ -23,7 +23,7 @@ raise EnvironmentError("O2DPG_ROOT is not set in the environment.") mc_prodinfo_path = os.path.abspath(os.path.join(o2dpg_root, "MC", "prodinfo")) sys.path.append(mc_prodinfo_path) -from mcprodinfo_ccdb_upload import MCProdInfo, upload_mcprodinfo_meta, query_mcprodinfo +from mcprodinfo_ccdb_upload import MCProdInfo, publish_MCProdInfo import dataclasses # Creates a time anchored MC workflow; positioned within a given run-number (as function of production size etc) @@ -450,14 +450,6 @@ def parse_file(filename): print(f"This run as globally {total_excluded_fraction} of it's data marked to be exluded") return excluded -def publish_MCProdInfo(mc_prod_info, ccdb_url = "https://alice-ccdb.cern.ch", username = "aliprod", include_meta_into_aod=False): - print("Publishing MCProdInfo") - - # see if this already has meta-data uploaded, otherwise do nothing - mc_prod_info_q = query_mcprodinfo(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag) - if mc_prod_info_q == None: - # could make this depend on hash values in future - upload_mcprodinfo_meta(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag, dataclasses.asdict(mc_prod_info)) def main(): diff --git a/MC/prodinfo/mcprodinfo_ccdb_upload.py b/MC/prodinfo/mcprodinfo_ccdb_upload.py index 34b104fc0..c56bf9827 100644 --- a/MC/prodinfo/mcprodinfo_ccdb_upload.py +++ b/MC/prodinfo/mcprodinfo_ccdb_upload.py @@ -20,6 +20,8 @@ class MCProdInfo: OrbitsPerTF: int # max_events_per_tf: Optional[int] = -1 Comment: Optional[str] = None + McTag: Optional[str] = None # main software tag used + RecoTag: Optional[str] = None # RecoTag (if any) Hash: Optional[str] = field(default=None) def __post_init__(self): @@ -142,3 +144,12 @@ def upload_mcprodinfo_meta(base_url, user, run_number, lpm_prod_tag, keys, cert_ os.remove(empty_file) return response + +def publish_MCProdInfo(mc_prod_info, ccdb_url = "https://alice-ccdb.cern.ch", username = "aliprod", include_meta_into_aod=False): + print("Publishing MCProdInfo") + + # see if this already has meta-data uploaded, otherwise do nothing + mc_prod_info_q = query_mcprodinfo(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag) + if mc_prod_info_q == None: + # could make this depend on hash values in future + upload_mcprodinfo_meta(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag, dataclasses.asdict(mc_prod_info)) diff --git a/MC/prodinfo/mcprodinfo_harvester.py b/MC/prodinfo/mcprodinfo_harvester.py new file mode 100755 index 000000000..352c89e79 --- /dev/null +++ b/MC/prodinfo/mcprodinfo_harvester.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 + +# A python tool, that fills CCDB MCProdInfo by +# harvesting the data from production log files from the GRID. +# This is useful, when the information was not directly filled +# by the MC job itself. + +import json +import subprocess +import sys +from collections import defaultdict +from zipfile import ZipFile +import re +import os +import argparse + +from mcprodinfo_ccdb_upload import MCProdInfo, publish_MCProdInfo + + +def alien_find(path, pattern="*"): + cmd = ["alien.py", "find", path, pattern] + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + return [line.strip() for line in result.stdout.splitlines() if line.strip()] + + +def alien_cp(alien_path, local_path): + cmd = ["alien.py", "cp", f"alien://{alien_path}", f"file://{local_path}"] + subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) + + +def parse_workflow_path(path, prod_tag): + parts = path.strip("/").split("/") + try: + idx = parts.index(prod_tag) + except ValueError: + return None + + after = parts[idx + 1 :] + if len(after) < 2: + return None + + if after[0].isdigit() and len(after[0]) == 1: + cycle = int(after[0]) + run_number = int(after[1]) + split = after[2] + else: + cycle = None + run_number = int(after[0]) + split = after[1] + + return cycle, run_number, split + + +def extract_from_zip(local_zip_path): + """Extract workflow.json and stdout from log_archive.zip.""" + wf_data = None + env_vars = {} + try: + with ZipFile(local_zip_path, "r") as zf: + # workflow.json + if "workflow.json" in zf.namelist(): + with zf.open("workflow.json") as wf_file: + wf_data = json.load(wf_file) + + # stdout (could be named stdout or stdout.log) + candidates = [n for n in zf.namelist() if n.startswith("stdout")] + if candidates: + with zf.open(candidates[0]) as so: + text = so.read().decode(errors="ignore") + for key in [ + "ALIEN_JDL_PACKAGES", + "ALIEN_JDL_O2DPG_ASYNC_RECO_TAG", + "ALIEN_MASTERJOB", + ]: + m = re.search(rf"{key}=(.*)", text) + if m: + env_vars[key] = m.group(1).strip() + except Exception as e: + print(f"⚠️ Failed to extract from {local_zip_path}: {e}") + return wf_data, env_vars + + +def build_info(prod_tag, run_number, wf_data, env_vars): + meta=wf_data.get("meta") + if meta != None: + int_rate = meta.get("interactionRate") + col_system = meta.get("col") + orbits_per_tf = meta.get("orbitsPerTF") + + return MCProdInfo( + LPMProductionTag=prod_tag, + Col=col_system, + IntRate=int_rate, + RunNumber=run_number, + OrbitsPerTF=orbits_per_tf, + McTag=env_vars.get("ALIEN_JDL_PACKAGES"), + RecoTag=env_vars.get("ALIEN_JDL_O2DPG_ASYNC_RECO_TAG") + ) + + +def pick_split(prod_tag, run_number, candidates, ascending=True): + """Pick the first valid split (min if ascending, max if not).""" + def split_key(entry): + _, split, _ = entry + try: + return int(split) + except ValueError: + return float("inf") + + candidates_sorted = sorted(candidates, key=split_key, reverse=not ascending) + + for cycle, split, zip_path in candidates_sorted: + print (f"Trying to analyse {zip_path}") + local_zip = f"/tmp/log_archive_{run_number}_{cycle or 0}_{split}.zip" + try: + alien_cp(zip_path, local_zip) + except subprocess.CalledProcessError: + continue + + wf_data, env_vars = extract_from_zip(local_zip) + + try: + os.remove(local_zip) # cleanup downloaded file + except OSError: + pass + + if wf_data: + info = build_info(prod_tag, run_number, wf_data, env_vars) + return info, cycle, split, zip_path + print (f"Failed") + + return None, None, None, None + + +def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None): + base_path = f"/alice/sim/{year}/{prod_tag}" + + # Step 1: find all log_archive.zip files + print (f"Querying AliEn for all directories with zip files") + zip_files = alien_find(base_path, "log_archive.zip") + + # exclude some unnecessary paths + zip_files = [ + zf for zf in zip_files + if "/AOD/" not in zf and "/QC/" not in zf and "/TimeseriesTPCmerging/" not in zf and "/Stage" not in zf + ] + + # Step 2: group by run_number + runs = defaultdict(list) + for zf in zip_files: + parsed = parse_workflow_path(zf, prod_tag) + if parsed is None: + continue + cycle, run_number, split = parsed + runs[run_number].append((cycle, split, zf)) + + print(f"Found {len(runs)} run numbers") + + # Step 3: for each run_number, handle smallest and largest valid split + for run_number, candidates in sorted(runs.items()): + print (f"Analysing run {run_number}") + info_min, cycle_min, split_min, _ = pick_split(prod_tag, run_number, candidates, ascending=True) + info_max, cycle_max, split_max, _ = pick_split(prod_tag, run_number, candidates, ascending=False) + + # some consistency checks + if info_min and info_max: + if info_min.Col != info_max.Col: + print(f"❌ ColSystem mismatch for run {run_number}") + if info_min.OrbitsPerTF != info_max.OrbitsPerTF: + print(f"❌ OrbitsPerTF mismatch for run {run_number}") + + publish_MCProdInfo(info_min, username=username, ccdb_url=ccdb_url) + print (info_min) + + +def main(): + parser = argparse.ArgumentParser( + description="Harvest MC production metadata from AlienGRID and publish to CCDB" + ) + parser.add_argument("--prod_tag", required=True, help="Production tag (e.g. prod2025a)") + parser.add_argument("--ccdb", required=False, default="https://alice-ccdb.cern.ch", help="CCDB server URL") + parser.add_argument("--username", required=False, help="GRID username (needs appropriate AliEn token initialized)") + parser.add_argument("--year", default="2025", help="Production year (default: 2025)") + args = parser.parse_args() + + process_prod_tag(args.prod_tag, year=args.year, ccdb_url=args.ccdb, username=args.username) + +if __name__ == "__main__": + main() From 78d79332c37cc4024769805a301dc153cef70427 Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Fri, 29 Aug 2025 11:39:26 +0200 Subject: [PATCH 053/362] [PWGDQ] Adding configuration for light nuclei (#2107) * Adding configuration for light nuclei * Adding test config --------- Co-authored-by: Lucamicheletti93 --- ...dPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini | 7 ++ ...tedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C | 85 +++++++++++++++++++ .../pythia8_inel_triggerGap_OO5TeV.cfg | 17 ++++ 3 files changed, 109 insertions(+) create mode 100755 MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C create mode 100644 MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini new file mode 100755 index 000000000..bbf6ae745 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg new file mode 100644 index 000000000..dc5602cfc --- /dev/null +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg @@ -0,0 +1,17 @@ +### beams +Beams:idA 1000080160 # oxygen +Beams:idB 1000080160 # oxygen +Beams:eCM 5360. # GeV +Beams:frameType = 1 + +### processes +SoftQCD:inelastic on # all inelastic processes +CharmoniumShower:all = on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +#### Heavy ion settings +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 +HeavyIon:SigFitDefPar = 17.24,2.15,0.33,0.0,0.0,0.0,0.0,0.0 \ No newline at end of file From 1ee4f3018c568b4b7f845c8d16c378dd61e01a65 Mon Sep 17 00:00:00 2001 From: Jonghan Park <40240384+jpxrk@users.noreply.github.com> Date: Sat, 30 Aug 2025 07:03:09 +0900 Subject: [PATCH 054/362] [PWGHF] new files for production of electrons from heavy-flavour hadron decays (#2106) * [PWGHF] new files for production of electrons from heavy-flavour hadron decays * Modify decay chains --- ...eratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini | 8 ++ ...eneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C | 128 ++++++++++++++++++ .../pythia8/generator/pythia8_HFe_Mode2.cfg | 104 ++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini new file mode 100644 index 000000000..957daf1e8 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C new file mode 100644 index 000000000..fb9df800e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C @@ -0,0 +1,128 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgDecayElectron = 11; + int checkPdgQuarkOne = 4; + int checkPdgQuarkTwo = 5; + float ratioTrigger = 1. / 5; // one event triggered out of 5 + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}; + int nElectrons{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } // if event header + + int nelectronsev = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayElectron) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4 || + int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nElectrons++; + nelectronsev++; + } // gmpdg + } // pdgdecay + } // loop track + // std::cout << "#electrons per event: " << nelectronsev << "\n"; + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) + << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) + << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne + << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo + << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne + << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo + << " different than expected\n"; + return 1; + } + if (nQuarksOne < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne + << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo + << " lower than expected\n"; + return 1; + } + std::cout << "#electrons: " << nElectrons << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg new file mode 100644 index 000000000..fd44ab1e8 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg @@ -0,0 +1,104 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Grazia Luparello (Grazia.Luparello@cern.ch) +### Antonio Palasciano (antonio.palasciano@cern.ch) +### Jonghan Park (jonghan@cern.ch) +### electrons from heavy-flavour hadrons and from light neutral mesons +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + + +### switch off all decay channels +111:onMode = off +221:onMode = off + +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4132:onMode = off +4232:onMode = off +4332:onMode = off + +511:onMode = off +521:onMode = off +531:onMode = off +5122:onMode = off +5132:onMode = off +5232:onMode = off +5332:onMode = off + +###Semimuonic decays of charm + +### pi0 -> e +111:onIfAny = 11 -11 +111:onIfAny = 22 11 -11 +### eta -> e +221:onIfAny = 11 -11 +221:onIfAny = 22 11 -11 + +### D+/- -> e + X +411:onIfAny = -11 12 +### D0 -> e + X +421:onIfAny = -11 12 +### D_s -> e + X +431:onIfAny = -11 12 +### Lambda_c -> e + X +4122:onIfAny = -11 12 +### Xsi0_c -> e + X +4132:onIfAny = -11 12 +### Xsi+_c -> e + X +4232:onIfAny = -11 12 +### Omega_c -> e + X +4332:onIfAny = -11 12 + +### B0 -> e + X +511:onIfAny = -11 12 +### B+/- -> e + X +521:onIfAny = -11 12 +### B_s -> e + X +531:onIfAny = -11 12 +### Lambda_b -> e + X +5122:onIfAny = -11 12 +### Xsi_b -> e + X +5132:onIfAny = -11 12 +### Xsi0_b -> e + X +5232:onIfAny = -11 12 +### Omega_b -> e + X +5332:onIfAny = -11 12 From 407e642f65f51b1f4c36d69aeae72873c929692c Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 17 Jul 2025 22:28:43 +0200 Subject: [PATCH 055/362] Simplify multiplicity settings in async reco scripts --- .../configurations/asyncReco/async_pass.sh | 75 +++++++------------ .../configurations/asyncReco/setenv_extra.sh | 9 --- DATA/production/workflow-multiplicities.sh | 55 ++++++++++---- 3 files changed, 68 insertions(+), 71 deletions(-) diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index c83c65c83..d2665a647 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -412,67 +412,46 @@ fi echo "SETTING_ROOT_OUTPUT = $SETTING_ROOT_OUTPUT" # Enabling GPUs -if [[ -n "$ALIEN_JDL_USEGPUS" && $ALIEN_JDL_USEGPUS != 0 ]] ; then - echo "Enabling GPUS" - [[ -z ${GPUTYPE:-} ]] && export GPUTYPE="HIP" - [[ -z ${GPUMEMSIZE:-} ]] && export GPUMEMSIZE=$((25 << 30)) - if [[ "0$ASYNC_PASS_NO_OPTIMIZED_DEFAULTS" != "01" ]]; then +if [[ $ASYNC_PASS_NO_OPTIMIZED_DEFAULTS != 1 ]]; then + export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + if [[ $ALIEN_JDL_USEGPUS == 1 ]] ; then + echo "Enabling GPUS" + if [[ -z $ALIEN_JDL_SITEARCH ]]; then echo "ERROR: Must set ALIEN_JDL_SITEARCH to define GPU architecture!"; exit 1; fi + if [[ $ALIEN_JDL_SITEARCH == "NERSC" ]]; then # Disable mlock / ulimit / gpu memory registration - has performance impact, but doesn't work at NERSC for now + export SETENV_NO_ULIMIT=1 + export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_proc.noGPUMemoryRegistration=1;" + fi + ALIEN_JDL_SITEARCH_TMP=$ALIEN_JDL_SITEARCH + if [[ $ALIEN_JDL_SITEARCH == "EPN_MI100" ]]; then + ALIEN_JDL_SITEARCH_TMP=EPN + export EPN_NODE_MI100=1 + elif [[ $ALIEN_JDL_SITEARCH == "EPN_MI50" ]]; then + ALIEN_JDL_SITEARCH_TMP=EPN + fi if [[ "ALIEN_JDL_USEFULLNUMADOMAIN" == 0 ]]; then if [[ $keep -eq 0 ]]; then if [[ $ALIEN_JDL_UNOPTIMIZEDGPUSETTINGS != 1 ]]; then - export OPTIMIZED_PARALLEL_ASYNC=pp_1gpu # sets the multiplicities to optimized defaults for this configuration (1 job with 1 gpu on EPNs) - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + export OPTIMIZED_PARALLEL_ASYNC=pp_1gpu_${ALIEN_JDL_SITEARCH_TMP} # (16 cores, 1 gpu per job, pp) else - # forcing multiplicities to be 1 - export MULTIPLICITY_PROCESS_tof_matcher=1 - export MULTIPLICITY_PROCESS_mch_cluster_finder=1 - export MULTIPLICITY_PROCESS_tpc_entropy_decoder=1 - export MULTIPLICITY_PROCESS_itstpc_track_matcher=1 - export MULTIPLICITY_PROCESS_its_tracker=1 - export OMP_NUM_THREADS=4 - export TIMEFRAME_RATE_LIMIT=8 - export SHMSIZE=30000000000 + export OPTIMIZED_PARALLEL_ASYNC=pp_1gpu_${ALIEN_JDL_SITEARCH_TMP}_unoptimized # (16 cores, 1 gpu per job, pp, low CPU multiplicities) fi else - export TIMEFRAME_RATE_LIMIT=4 - export SHMSIZE=30000000000 + export OPTIMIZED_PARALLEL_ASYNC=keep_root fi else if [[ $BEAMTYPE == "pp" ]]; then - export OPTIMIZED_PARALLEL_ASYNC=pp_4gpu # sets the multiplicities to optimized defaults for this configuration (1 Numa, pp) - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + export OPTIMIZED_PARALLEL_ASYNC=pp_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA, 4 gpu per job, pp) else # PbPb - export OPTIMIZED_PARALLEL_ASYNC=PbPb_4gpu # sets the multiplicities to optimized defaults for this configuration (1 Numa, PbPb) - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + export OPTIMIZED_PARALLEL_ASYNC=PbPb_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA 4 gpu per job, PbPb) fi fi - fi -else - # David, Oct 13th - # the optimized settings for the 8 core GRID queue without GPU are - # (overwriting the values above) - # - if [[ "0$ASYNC_PASS_NO_OPTIMIZED_DEFAULTS" != "01" ]]; then - if [[ "$ALIEN_JDL_EPNFULLNUMACPUONLY" != 1 ]]; then - if [[ $BEAMTYPE == "pp" ]]; then - if (( $(echo "$RUN_IR > 800000" | bc -l) )); then - export TIMEFRAME_RATE_LIMIT=1 - elif (( $(echo "$RUN_IR < 50000" | bc -l) )); then - export TIMEFRAME_RATE_LIMIT=6 - else - export TIMEFRAME_RATE_LIMIT=3 - fi - export OPTIMIZED_PARALLEL_ASYNC=pp_8cpu # sets the multiplicities to optimized defaults for this configuration (grid) - export SHMSIZE=16000000000 - else # PbPb - export TIMEFRAME_RATE_LIMIT=2 - export OPTIMIZED_PARALLEL_ASYNC=pp_8cpu - export SHMSIZE=16000000000 - export SVERTEX_THREADS=5 - fi + else + export SETENV_NO_ULIMIT=1 + export DPL_DEFAULT_PIPELINE_LENGTH=16 # to avoid memory issues - affects performance, so don't do with GPUs + if [[ $ALIEN_JDL_EPNFULLNUMACPUONLY != 1 ]]; then + export OPTIMIZED_PARALLEL_ASYNC=8cpu # (8 cores per job, grid) else - export OPTIMIZED_PARALLEL_ASYNC=pp_64cpu # to use EPNs with full NUMA domain but without GPUs - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + export OPTIMIZED_PARALLEL_ASYNC=pp_64cpu # (64 cores per job, 1 NUMA, EPN) fi fi fi diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index fb74d36f3..c9a822550 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -3,15 +3,6 @@ # process flags passed to the script -if [[ -z "$ALIEN_JDL_USEGPUS" || $ALIEN_JDL_USEGPUS != 1 ]]; then - export SETENV_NO_ULIMIT=1 -fi - -# to avoid memory issues - we don't do this on the EPNs, since it can affect the performance -if [[ $ALIEN_JDL_USEGPUS != 1 ]]; then - export DPL_DEFAULT_PIPELINE_LENGTH=16 -fi - # check if this is a production on skimmed data if grep -q /skimmed/ wn.xml ; then export ON_SKIMMED_DATA=1; diff --git a/DATA/production/workflow-multiplicities.sh b/DATA/production/workflow-multiplicities.sh index 3929e0456..76679ade9 100644 --- a/DATA/production/workflow-multiplicities.sh +++ b/DATA/production/workflow-multiplicities.sh @@ -53,11 +53,23 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then [[ ! -z ${TIMEFRAME_RATE_LIMIT:-} ]] && unset TIMEFRAME_RATE_LIMIT [[ ! -z ${SHMSIZE:-} ]] && unset SHMSIZE fi - if [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_8cpu" ]]; then + if [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=3 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=16000000000 NGPURECOTHREADS=5 - elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_16cpu" ]]; then + if [[ $BEAMTYPE == "pp" ]]; then + if (( $(echo "$RUN_IR > 800000" | bc -l) )); then + TIMEFRAME_RATE_LIMIT=1 + elif (( $(echo "$RUN_IR < 50000" | bc -l) )); then + TIMEFRAME_RATE_LIMIT=6 + else + TIMEFRAME_RATE_LIMIT=3 + fi + else # PbPb + TIMEFRAME_RATE_LIMIT=2 + SVERTEX_THREADS=5 + fi + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "16cpu" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=8 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=22000000000 NGPURECOTHREADS=9 @@ -78,20 +90,28 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then N_MCHCL=3 N_TOFMATCH=2 N_TPCENTDEC=3 - elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu" ]]; then + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu_EPN" || $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu_EPN_unoptimized" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=8 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=30000000000 - N_TOFMATCH=2 - N_MCHCL=3 - N_TPCENTDEC=2 - N_TPCITS=3 + NGPUS=1 + GPUTYPE=HIP + GPUMEMSIZE=$((25 << 30)) N_MCHTRK=2 - N_ITSTRK=3 - NGPURECOTHREADS=8 + N_TPCTRK=$NGPUS + if [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu_EPN" ]]; then + N_TOFMATCH=2 + N_MCHCL=3 + N_TPCENTDEC=2 + N_TPCITS=3 + N_ITSTRK=3 + NGPURECOTHREADS=8 + else + NGPURECOTHREADS=4 + fi NTRDTRKTHREADS=3 ITSTRK_THREADS=2 ITSTPC_THREADS=2 - elif [[ $OPTIMIZED_PARALLEL_ASYNC =~ ^pp_4gpu(_|$) ]]; then + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_gpu_NERSC" || $OPTIMIZED_PARALLEL_ASYNC == "pp_4gpu_EPN" ]]; then if [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]]; then if [[ ! -z ${ALIEN_JDL_LPMANCHORYEAR} && ${ALIEN_JDL_LPMANCHORYEAR} -lt 2023 ]]; then TIMEFRAME_RATE_LIMIT=45 @@ -100,19 +120,21 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then fi fi [[ -z ${SHMSIZE:-} ]] && SHMSIZE=100000000000 - if [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_4gpu_NERSC" ]]; then + if [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_gpu_NERSC" ]]; then NGPUS=1 GPUTYPE=CUDA else NGPUS=4 + GPUTYPE=HIP fi + GPUMEMSIZE=$((25 << 30)) NGPURECOTHREADS=8 NTRDTRKTHREADS=2 ITSTRK_THREADS=2 ITSTPC_THREADS=2 SVERTEX_THREADS=4 TPCTIMESERIES_THREADS=2 - N_TPCTRK=4 + N_TPCTRK=$NGPUS N_FWDMATCH=2 N_PRIMVTXMATCH=1 N_PRIMVTX=1 @@ -128,16 +150,18 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then N_ITSTRK=12 N_ITSCL=2 export DPL_SMOOTH_RATE_LIMITING=1 - elif [[ $OPTIMIZED_PARALLEL_ASYNC =~ ^PbPb_4gpu(_|$) ]]; then + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "PbPb_gpu_NERSC" || $OPTIMIZED_PARALLEL_ASYNC == "PbPb_4gpu_EPN" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=35 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=100000000000 # SHM_LIMIT 3/4 [[ -z ${TIMEFRAME_SHM_LIMIT:-} ]] && TIMEFRAME_SHM_LIMIT=$(($SHMSIZE / 3)) - if [[ $OPTIMIZED_PARALLEL_ASYNC == "PbPb_4gpu_NERSC" ]]; then + if [[ $OPTIMIZED_PARALLEL_ASYNC == "PbPb_gpu_NERSC" ]]; then NGPUS=1 GPUTYPE=CUDA else NGPUS=4 + GPUTYPE=HIP fi + GPUMEMSIZE=$((25 << 30)) NGPURECOTHREADS=8 NTRDTRKTHREADS=8 ITSTRK_THREADS=5 @@ -172,6 +196,9 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then N_MCHTRK=1 N_TOFMATCH=9 N_TPCTRK=6 + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "keep_root" ]]; then + TIMEFRAME_RATE_LIMIT=4 + SHMSIZE=30000000000 else echo "Invalid optimized setting '$OPTIMIZED_PARALLEL_ASYNC'" 1>&2 exit 1 From 532a4d864bcd11d275f0cad1f00a3bb1db155b8e Mon Sep 17 00:00:00 2001 From: shahoian Date: Sun, 31 Aug 2025 17:24:35 +0200 Subject: [PATCH 056/362] MC picks up the FIT-related options used in o2-tof-matcher --- MC/bin/o2dpg_sim_workflow.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index ee6de3209..fe00abce5 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1322,6 +1322,7 @@ def getDigiTaskName(det): #<--------- TOF-TPC(-ITS) global track matcher workflow toftpcmatchneeds = [TOFRECOtask['name'], TPCRECOtask['name'], ITSTPCMATCHtask['name'], TRDTRACKINGtask2['name']] toftracksrcdefault = dpl_option_from_config(anchorConfig, 'o2-tof-matcher-workflow', 'track-sources', default_value='TPC,ITS-TPC,TPC-TRD,ITS-TPC-TRD') + tofusefit = option_if_available('o2-tof-matcher-workflow', '--use-fit', envfile=async_envfile) TOFTPCMATCHERtask = createTask(name='toftpcmatch_'+str(tf), needs=toftpcmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') tofmatcher_cmd_parts = [ '${O2_ROOT}/bin/o2-tof-matcher-workflow', @@ -1332,9 +1333,11 @@ def getDigiTaskName(det): 'ITSCATrackerParam', 'MFTClustererParam', 'GPU_rec_tpc', + 'ft0tag', 'trackTuneParams'], tpcLocalCFreco), ' --track-sources ' + toftracksrcdefault, (' --combine-devices','')[args.no_combine_dpl_devices], + tofusefit, tpc_corr_scaling_options, tpc_corr_options_mc ] From e7780bd76e7ca4dca1a7aa2cc11a9204fd34fba2 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 26 Aug 2025 14:39:28 +0200 Subject: [PATCH 057/362] workflow-multiplicities.sh: use two mch-data-decoder instances by default in synchronous pp and PbPb processing --- DATA/production/workflow-multiplicities.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DATA/production/workflow-multiplicities.sh b/DATA/production/workflow-multiplicities.sh index 76679ade9..66879db68 100644 --- a/DATA/production/workflow-multiplicities.sh +++ b/DATA/production/workflow-multiplicities.sh @@ -219,6 +219,7 @@ elif [[ $EPNPIPELINES != 0 ]]; then if [[ "${GEN_TOPO_AUTOSCALE_PROCESSES:-}" == "1" && $RUNTYPE == "PHYSICS" ]]; then N_MCHCL=$(math_max $((6 * 100 / $RECO_NUM_NODES_WORKFLOW_CMP)) 1) fi + N_MCHRAWDEC=2 if [[ "$HIGH_RATE_PP" == "1" ]]; then N_TPCITS=$(math_max $((5 * $EPNPIPELINES * $NGPUS / 4)) 1) N_TPCENT=$(math_max $((4 * $EPNPIPELINES * $NGPUS / 4)) 1) @@ -235,6 +236,7 @@ elif [[ $EPNPIPELINES != 0 ]]; then else if [[ $BEAMTYPE == "PbPb" ]]; then N_ITSTRK=$(math_max $((2 * $EPNPIPELINES * $NGPUS / 4)) 1) + N_MCHRAWDEC=2 elif [[ $BEAMTYPE == "cosmic" ]]; then N_ITSTRK=$(math_max $((4 * $EPNPIPELINES * $NGPUS / 4)) 1) fi From 18377a4e8fc9b8e7efc4707814594462af603c5b Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 2 Sep 2025 14:29:08 +0200 Subject: [PATCH 058/362] gen_topo_o2dpg.sh: force update of local tags in case an existing one was updated on the remote --- DATA/tools/epn/gen_topo_o2dpg.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/tools/epn/gen_topo_o2dpg.sh b/DATA/tools/epn/gen_topo_o2dpg.sh index 22f77cba8..d67b7381a 100755 --- a/DATA/tools/epn/gen_topo_o2dpg.sh +++ b/DATA/tools/epn/gen_topo_o2dpg.sh @@ -94,7 +94,7 @@ while true; do done git checkout $GEN_TOPO_SOURCE &> /dev/null if [[ $? != 0 ]]; then - git fetch --tags origin 1>&2 || { echo Repository update failed 1>&2; exit 1; } + git fetch -f --tags origin 1>&2 || { echo Repository update failed 1>&2; exit 1; } git checkout $GEN_TOPO_SOURCE &> /dev/null || { echo commit does not exist 1>&2; exit 1; } fi # At a tag, or a detached non-dirty commit, but not on a branch From ddbd7a1cc845bf01bdb0bb074dc2f99cb8eddb07 Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Thu, 4 Sep 2025 02:24:20 +0200 Subject: [PATCH 059/362] removing useless process from pythia config (#2110) Co-authored-by: Lucamicheletti93 --- .../PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg index dc5602cfc..ff4c5ae6f 100644 --- a/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg @@ -6,7 +6,6 @@ Beams:frameType = 1 ### processes SoftQCD:inelastic on # all inelastic processes -CharmoniumShower:all = on ### decays ParticleDecays:limitTau0 on From a81c61faebc4d8d4500513d58a969feda5fffda4 Mon Sep 17 00:00:00 2001 From: shreyasiacharya <34233706+shreyasiacharya@users.noreply.github.com> Date: Thu, 4 Sep 2025 07:24:01 +0200 Subject: [PATCH 060/362] For light ions at mid rapidity (#2111) * For light ions at mid rapidity * For light ions at mid rapidity * For light ions at mid rapidity --- .../generator/GeneratorPromptCharmonia.C | 168 ++++++++++++++++++ ...ithInjectedPromptSignals_gaptriggered_dq.C | 3 + ...dPromptCharmoniaMidy_TriggerGap_OO5TeV.ini | 7 + 3 files changed, 178 insertions(+) create mode 100644 MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index 29891fe74..9bcd0bc52 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -168,6 +168,149 @@ class O2_GeneratorParamPsiMidY : public GeneratorTGenerator GeneratorParam* paramPsi = nullptr; }; +class O2_GeneratorParamJpsiMidY_5TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsiMidY_5TeV() : GeneratorTGenerator("paramJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp5TeV, YJPsipp5TeV, V2JPsipp5TeV, IpJPsipp5TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0., 1000.); + paramJpsi->SetYRange(-1.0, 1.0); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); // Pythia + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsiMidY_5TeV() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // JPSi pt at 5.02 TeV: https: // www.hepdata.net/record/ins1735351 + // + const Double_t kC = 1774.9; + const Double_t kpt0 = 3.38452; + const Double_t kn = 2.77889; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken the same as: jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp5TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsiMidY_5TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsiMidY_5TeV() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp5TeV, YPsipp5TeV, V2Psipp5TeV, IpPsipp5TeV); + paramPsi->SetMomentumRange(0., 1.e6); // Momentum range added from me + paramPsi->SetPtRange(0., 1000.); // transverse of momentum range + paramPsi->SetYRange(-1.0, 1.0); // rapidity range + paramPsi->SetPhiRange(0., 360.); // phi range + paramPsi->SetDecayer(new TPythia6Decayer()); // Pythia decayer + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramPsi); // Setting parameters to ParamPsi for Psi(2S) + }; + + ~O2_GeneratorParamPsiMidY_5TeV() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // Same as JPsi at 5.02 TeV since ratio is almost flat in pT: https: // www.hepdata.net/record/ins1735351 + // + const Double_t kC = 1774.9; + const Double_t kpt0 = 3.38452; + const Double_t kn = 2.77889; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken same as jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp5TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; + class O2_GeneratorParamJpsiFwdY : public GeneratorTGenerator { @@ -982,6 +1125,31 @@ FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV() return genCocktailEvtGen; } +FairGenerator* GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsiMidY_5TeV; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsiMidY_5TeV; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiElectron); + + return genCocktailEvtGen; +} FairGenerator* GeneratorParamPromptPsiToJpsiPiPiEvtGen_pp13TeV(TString pdgs = "100443") diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C index 6d51e5c85..e58f655e9 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C @@ -57,6 +57,9 @@ public: case 11: // generate cocktail of prompt X_1(3872) and psi2S to Jpsi pi pi at midrapidity mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV(); break; + case 12: // generate prompt charmonia cocktail at mid rapidity at 5TeV + mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV(); + break; } mGeneratorParam->Init(); } diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini new file mode 100644 index 000000000..2c1117580 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,12) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg From 02227c5dcc04709665b9d3f78b9a1a63d5203355 Mon Sep 17 00:00:00 2001 From: Jonghan Park <40240384+jpxrk@users.noreply.github.com> Date: Fri, 5 Sep 2025 06:35:47 +0900 Subject: [PATCH 061/362] modify decay chains (#2112) --- .../pythia8/generator/pythia8_HFe_Mode2.cfg | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg index fd44ab1e8..4f4dcb7bf 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg @@ -66,39 +66,32 @@ BeamRemnants:saturation 5 ###Semimuonic decays of charm -### pi0 -> e -111:onIfAny = 11 -11 -111:onIfAny = 22 11 -11 -### eta -> e -221:onIfAny = 11 -11 -221:onIfAny = 22 11 -11 - ### D+/- -> e + X -411:onIfAny = -11 12 +411:onIfAny = 11 ### D0 -> e + X -421:onIfAny = -11 12 +421:onIfAny = 11 ### D_s -> e + X -431:onIfAny = -11 12 +431:onIfAny = 11 ### Lambda_c -> e + X -4122:onIfAny = -11 12 +4122:onIfAny = 11 ### Xsi0_c -> e + X -4132:onIfAny = -11 12 +4132:onIfAny = 11 ### Xsi+_c -> e + X -4232:onIfAny = -11 12 +4232:onIfAny = 11 ### Omega_c -> e + X -4332:onIfAny = -11 12 +4332:onIfAny = 11 ### B0 -> e + X -511:onIfAny = -11 12 +511:onIfAny = 11 ### B+/- -> e + X -521:onIfAny = -11 12 +521:onIfAny = 11 ### B_s -> e + X -531:onIfAny = -11 12 +531:onIfAny = 11 ### Lambda_b -> e + X -5122:onIfAny = -11 12 +5122:onIfAny = 11 ### Xsi_b -> e + X -5132:onIfAny = -11 12 +5132:onIfAny = 11 ### Xsi0_b -> e + X -5232:onIfAny = -11 12 +5232:onIfAny = 11 ### Omega_b -> e + X -5332:onIfAny = -11 12 +5332:onIfAny = 11 From 7cf24e70406da5a454e75726c7612625dd30c2b0 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 5 Sep 2025 13:08:13 +0200 Subject: [PATCH 062/362] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 4b8e4fd2e..5cc844348 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -17,7 +17,7 @@ /DATA/testing/detectors/TRD /DATA/testing/detectors/ZDC -/MC @sawenzel @chiarazampolli @jackal1-66 +/MC @sawenzel @jackal1-66 # PWG experts /MC/*/ALICE3 @njacazio From 5af618d81a29bdaddc4b957a9e27f4cb57b5d9a5 Mon Sep 17 00:00:00 2001 From: iravasen Date: Fri, 22 Aug 2025 13:59:16 +0200 Subject: [PATCH 063/362] adapt scripts for new digital scan run type --- DATA/production/calib/its-threshold-aggregator.sh | 4 ++-- DATA/production/calib/its-threshold-processing.sh | 8 ++++++-- DATA/production/standalone-calibration.desc | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/DATA/production/calib/its-threshold-aggregator.sh b/DATA/production/calib/its-threshold-aggregator.sh index 4540bcb3e..b0449e1fb 100755 --- a/DATA/production/calib/its-threshold-aggregator.sh +++ b/DATA/production/calib/its-threshold-aggregator.sh @@ -10,7 +10,7 @@ PROXY_INSPEC="tunestring:ITS/TSTR;runtype:ITS/RUNT;fittype:ITS/FITT;scantype:ITS CCDBPATH1="" CCDBPATH2="" -if [ $RUNTYPE_ITS == "tuning" ] || [ $RUNTYPE_ITS == "digital" ] || [ $RUNTYPE_ITS == "tuningbb" ]; then +if [[ $RUNTYPE_ITS == "tuning" ]] || [[ $RUNTYPE_ITS == *digital* ]] || [[ $RUNTYPE_ITS == "tuningbb" ]]; then CCDBPATH1="$DCSCCDBSERVER_PERS" CCDBPATH2="http://o2-ccdb.internal" else @@ -26,7 +26,7 @@ WORKFLOW= add_W o2-dpl-raw-proxy "--exit-transition-timeout 20 --proxy-name its-thr-input-proxy --dataspec \"$PROXY_INSPEC\" --network-interface ib0 --channel-config \"name=its-thr-input-proxy,method=bind,type=pull,rateLogging=0,transport=zeromq\"" "" 0 add_W o2-its-threshold-aggregator-workflow "-b" "" 0 add_W o2-calibration-ccdb-populator-workflow "--ccdb-path=\"$CCDBPATH1\" --sspec-min 0 --sspec-max 0 --name-extention dcs" -if [ $RUNTYPE_ITS == "digital" ]; then +if [[ $RUNTYPE_ITS == *digital* ]]; then add_W o2-calibration-ccdb-populator-workflow "--ccdb-path=\"$CCDBPATH2\" --sspec-min 1 --sspec-max 1" fi diff --git a/DATA/production/calib/its-threshold-processing.sh b/DATA/production/calib/its-threshold-processing.sh index dc4079b4b..0859a7270 100755 --- a/DATA/production/calib/its-threshold-processing.sh +++ b/DATA/production/calib/its-threshold-processing.sh @@ -14,15 +14,19 @@ PROXY_OUTSPEC="tunestring:ITS/TSTR;runtype:ITS/RUNT;fittype:ITS/FITT;scantype:IT CHIPMODBASE=5 NDECODERS=6 +ADDITIONAL_OPTIONS_DEC="" +ADDITIONAL_OPTIONS_CAL="" if [ $RUNTYPE_ITS == "digital" ]; then CHIPMODBASE=10 fi +if [ $RUNTYPE_ITS == "digitalnomask" ]; then + CHIPMODBASE=10 + ADDITIONAL_OPTIONS_CAL="--ninj 5" +fi if [ $RUNTYPE_ITS == "thrfull" ]; then CHIPMODBASE=20 NDECODERS=10 fi -ADDITIONAL_OPTIONS_DEC="" -ADDITIONAL_OPTIONS_CAL="" if [ $RUNTYPE_ITS == "tuningbb" ]; then ADDITIONAL_OPTIONS_CAL="--min-vcasn 30 --max-vcasn 130" fi diff --git a/DATA/production/standalone-calibration.desc b/DATA/production/standalone-calibration.desc index 2c8bf7c7a..13ff741bc 100644 --- a/DATA/production/standalone-calibration.desc +++ b/DATA/production/standalone-calibration.desc @@ -18,6 +18,8 @@ ITS-thr-full: "O2PDPSuite" reco,80,80,"RUNTYPE_ITS=thrfull production/calib/its- ITS-digital: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=digital production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=digital production/calib/its-threshold-aggregator.sh" +ITS-digital-no-mask: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=digitalnomask production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=digitalnomask production/calib/its-threshold-aggregator.sh" + ITS-pulselength: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=pulselength production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=pulselength production/calib/its-threshold-aggregator.sh" ITS-tot-1row: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=tot1row production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=tot1row production/calib/its-threshold-aggregator.sh" From 04b9d6b06bbc4366b82d48cdca9f5970d4186db4 Mon Sep 17 00:00:00 2001 From: swenzel Date: Mon, 8 Sep 2025 15:35:37 +0200 Subject: [PATCH 064/362] New config for analysis task - reduce verbosity --- .../json/dpl/o2-analysistutorial-mc-histograms.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysistutorial-mc-histograms.json diff --git a/MC/config/analysis_testing/json/dpl/o2-analysistutorial-mc-histograms.json b/MC/config/analysis_testing/json/dpl/o2-analysistutorial-mc-histograms.json new file mode 100644 index 000000000..d60d3166b --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysistutorial-mc-histograms.json @@ -0,0 +1,11 @@ +{ + "access-mc-data": { + "reduce-output" : 2 + }, + "access-mc-truth": { + "reduce-output" : 2 + }, + "loop-over-mc-matched": { + "reduce-output" : 2 + } +} From c2f0bca2d838e1780b5221e834cbc6027e3a3354 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 5 Sep 2025 10:52:29 +0200 Subject: [PATCH 065/362] Take out CPV, PHS, ZDC from workflow when they are not in the run This commit removes CPV, PHS and ZDC from the simulation workflow when these detectors are not part of the data taking. Fixes https://its.cern.ch/jira/browse/O2-6145 Previusly we treated this scenario with zero-hit propagation, but this could still lead to noise-digits leading to some spurios AOD entries. --- MC/bin/o2dpg_sim_workflow.py | 71 ++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index fe00abce5..795545199 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -276,6 +276,18 @@ def load_external_config(configfile): for det in activeDetectors: activate_detector(det) +# function to finalize detector source lists based on activeDetectors +# detector source lists are comma separated lists of DET1, DET2, DET1-DET2, ... +def cleanDetectorInputList(inputlist): + sources_list = inputlist.split(",") + # Filter the sources + filtered_sources = [ + src for src in sources_list + if all(isActive(part) for part in src.split("-")) + ] + # Recompose into a comma-separated string + return ",".join(filtered_sources) + if not args.with_ZDC: # deactivate to be able to use isActive consistently for ZDC deactivate_detector('ZDC') @@ -1071,6 +1083,7 @@ def createRestDigiTask(name, det='ALLSMALLER'): t['cmd'] = ('','ln -nfs ../bkg_Hits*.root . ;')[doembedding] detlist = '' detlist = ','.join(smallsensorlist) + detlist = cleanDetectorInputList(detlist) t['cmd'] += commondigicmd + ' --onlyDet ' + detlist t['cmd'] += ' --ccdb-tof-sa --forceSelectedDets ' t['cmd'] += (' --combine-devices ','')[args.no_combine_dpl_devices] @@ -1292,7 +1305,7 @@ def getDigiTaskName(det): #<--------- TRD global tracking # FIXME This is so far a workaround to avoud a race condition for trdcalibratedtracklets.root TRDTRACKINGtask2 = createTask(name='trdreco2_'+str(tf), needs=[TRDTRACKINGtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem='2000') - trd_track_sources = dpl_option_from_config(anchorConfig, 'o2-trd-global-tracking', 'track-sources', default_value='TPC,ITS-TPC') + trd_track_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-trd-global-tracking', 'track-sources', default_value='TPC,ITS-TPC')) TRDTRACKINGtask2['cmd'] = task_finalizer([ '${O2_ROOT}/bin/o2-trd-global-tracking', getDPL_global_options(bigshm=True), @@ -1445,7 +1458,8 @@ def getDigiTaskName(det): getDPL_global_options(), putConfigValues(), ('',' --disable-mc')[args.no_mc_labels]]) - workflow['stages'].append(PHSRECOtask) + if isActive("PHS"): + workflow['stages'].append(PHSRECOtask) #<--------- CPV reco workflow CPVRECOtask = createTask(name='cpvreco_'+str(tf), needs=[getDigiTaskName("CPV")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') @@ -1454,7 +1468,8 @@ def getDigiTaskName(det): getDPL_global_options(), putConfigValues(), ('',' --disable-mc')[args.no_mc_labels]]) - workflow['stages'].append(CPVRECOtask) + if isActive("CPV"): + workflow['stages'].append(CPVRECOtask) #<--------- ZDC reco workflow ZDCRECOtask = createTask(name='zdcreco_'+str(tf), needs=[getDigiTaskName("ZDC")], tf=tf, cwd=timeframeworkdir, lab=["RECO", "ZDC"]) @@ -1463,7 +1478,8 @@ def getDigiTaskName(det): getDPL_global_options(), putConfigValues(), ('',' --disable-mc')[args.no_mc_labels]]) - workflow['stages'].append(ZDCRECOtask) + if isActive("ZDC"): + workflow['stages'].append(ZDCRECOtask) ## forward matching #<--------- MCH-MID forward matching @@ -1509,7 +1525,7 @@ def getDigiTaskName(det): #<--------- HMP forward matching hmpmatchneeds = [HMPRECOtask['name'], ITSTPCMATCHtask['name'], TOFTPCMATCHERtask['name'], TRDTRACKINGtask2['name']] - hmp_match_sources = dpl_option_from_config(anchorConfig, 'o2-hmpid-matcher-workflow', 'track-sources', default_value='ITS-TPC,ITS-TPC-TRD,TPC-TRD') + hmp_match_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-hmpid-matcher-workflow', 'track-sources', default_value='ITS-TPC,ITS-TPC-TRD,TPC-TRD')) HMPMATCHtask = createTask(name='hmpmatch_'+str(tf), needs=hmpmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') HMPMATCHtask['cmd'] = task_finalizer( ['${O2_ROOT}/bin/o2-hmpid-matcher-workflow', @@ -1524,24 +1540,29 @@ def getDigiTaskName(det): 'o2-primary-vertexing-workflow', 'vertexing-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') + pvfinder_sources = cleanDetectorInputList(pvfinder_sources) + pvfinder_matching_sources = dpl_option_from_config(anchorConfig, 'o2-primary-vertexing-workflow', 'vertex-track-matching-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') - pvfinderneeds = [TRDTRACKINGtask2['name'], - FT0RECOtask['name'], - FV0RECOtask['name'], - EMCRECOtask['name'], - PHSRECOtask['name'], - CPVRECOtask['name'], - FDDRECOtask['name'], - ZDCRECOtask['name'], - HMPMATCHtask['name'], - HMPMATCHtask['name'], - ITSTPCMATCHtask['name'], - TOFTPCMATCHERtask['name'], - MFTMCHMATCHtask['name'], + pvfinder_matching_sources = cleanDetectorInputList(pvfinder_matching_sources) + + pvfinderneeds = [TRDTRACKINGtask2['name'], + FT0RECOtask['name'], + FV0RECOtask['name'], + EMCRECOtask['name'], + PHSRECOtask['name'] if isActive("PHS") else None, + CPVRECOtask['name'] if isActive("CPV") else None, + FDDRECOtask['name'], + ZDCRECOtask['name'] if isActive("ZDC") else None, + HMPMATCHtask['name'], + HMPMATCHtask['name'], + ITSTPCMATCHtask['name'], + TOFTPCMATCHERtask['name'], + MFTMCHMATCHtask['name'], MCHMIDMATCHtask['name']] + pvfinderneeds = [ p for p in pvfinderneeds if p != None ] PVFINDERtask = createTask(name='pvfinder_'+str(tf), needs=pvfinderneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=NWORKERS_TF, mem='4000') PVFINDERtask['cmd'] = task_finalizer( @@ -1572,6 +1593,7 @@ def getDigiTaskName(det): 'o2-primary-vertexing-workflow', 'vertex-track-matching-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP') + svfinder_sources = cleanDetectorInputList(svfinder_sources) SVFINDERtask = createTask(name='svfinder_'+str(tf), needs=[PVFINDERtask['name'], FT0FV0EMCCTPDIGItask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=svfinder_cpu, mem='5000') SVFINDERtask['cmd'] = task_finalizer( [ '${O2_ROOT}/bin/o2-secondary-vertexing-workflow', @@ -1591,6 +1613,7 @@ def getDigiTaskName(det): # TODO This needs further refinement, sources and dependencies should be constructed dynamically aod_info_souces_default = 'ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP' aodinfosources = dpl_option_from_config(anchorConfig, 'o2-aod-producer-workflow', 'info-sources', default_value=aod_info_souces_default) + aodinfosources = cleanDetectorInputList(aodinfosources) aodneeds = [PVFINDERtask['name'], SVFINDERtask['name']] if usebkgcache: @@ -1644,20 +1667,20 @@ def getDigiTaskName(det): print ("Adding TPC residuals extraction and aggregation") #<------------- TPC residuals extraction - scdcalib_vertex_sources = dpl_option_from_config(anchorConfig, + scdcalib_vertex_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tpc-scdcalib-interpolation-workflow', 'vtx-sources', - default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP')) - scdcalib_track_sources = dpl_option_from_config(anchorConfig, + scdcalib_track_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tpc-scdcalib-interpolation-workflow', 'tracking-sources', - default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP')) - scdcalib_track_extraction = dpl_option_from_config(anchorConfig, + scdcalib_track_extraction = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tpc-scdcalib-interpolation-workflow', 'tracking-sources-map-extraction', - default_value='ITS-TPC') + default_value='ITS-TPC')) SCDCALIBtask = createTask(name='scdcalib_'+str(tf), needs=[PVFINDERtask['name']], tf=tf, cwd=timeframeworkdir, lab=["CALIB"], mem='4000') SCDCALIBtask['cmd'] = task_finalizer( From 865fc3a9f6891a42064912e4ff2d9435d8cd37c5 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 9 Sep 2025 14:35:14 +0200 Subject: [PATCH 066/362] Remove default workflow detector list from anchorMC --- MC/run/ANCHOR/anchorMC.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 7e14faabe..70ac64a87 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -52,7 +52,7 @@ print_help() echo "ALIEN_JDL_CPULIMIT or CPULIMIT, set the CPU limit of the workflow runner, default: 8," echo "NWORKERS, set the number of workers during detector transport, default: 8," echo "ALIEN_JDL_SIMENGINE or SIMENGINE, choose the transport engine, default: TGeant4," - echo "ALIEN_JDL_WORKFLOWDETECTORS, set detectors to be taken into account, default: ITS,TPC,TOF,FV0,FT0,FDD,MID,MFT,MCH,TRD,EMC,PHS,CPV,HMP,CTP," + echo "ALIEN_JDL_WORKFLOWDETECTORS, set detectors to be taken into account, default: not-used (take the ones from async-reco)" echo "ALIEN_JDL_ANCHOR_SIM_OPTIONS, additional options that are passed to the workflow creation, default: -gen pythia8," echo "ALIEN_JDL_ADDTIMESERIESINMC, run TPC time series. Default: 1, switch off by setting to 0," echo "ALIEN_JDL_MC_ORBITS_PER_TF=N, enforce some orbits per timeframe, instead of determining from CCDB" @@ -103,7 +103,6 @@ alien-token-info >/dev/null 2>&1 # the only four where there is a real default for export ALIEN_JDL_CPULIMIT=${ALIEN_JDL_CPULIMIT:-${CPULIMIT:-8}} export ALIEN_JDL_SIMENGINE=${ALIEN_JDL_SIMENGINE:-${SIMENGINE:-TGeant4}} -export ALIEN_JDL_WORKFLOWDETECTORS=${ALIEN_JDL_WORKFLOWDETECTORS:-ITS,TPC,TOF,FV0,FT0,FDD,MID,MFT,MCH,TRD,EMC,PHS,CPV,HMP,CTP} # can be passed to contain additional options that will be passed to o2dpg_sim_workflow_anchored.py and eventually to o2dpg_sim_workflow.py export ALIEN_JDL_ANCHOR_SIM_OPTIONS=${ALIEN_JDL_ANCHOR_SIM_OPTIONS:--gen pythia8} # all others MUST be set by the user/on the outside From 0b2c11464f22eceecbc3913e21d56a0eaa618ed2 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Thu, 11 Sep 2025 19:36:32 +0200 Subject: [PATCH 067/362] MC/PWGEM: add DY->ll config (#2117) --- .../Generator_pythia8_GapTriggered_DYLL.C | 151 ++++++++++++++++++ ...eratorDYee_GapTriggered_Gap5_OO5360GeV.ini | 7 + ...atorDYee_GapTriggered_Gap5_PbPb5360GeV.ini | 7 + ...ratorDYee_GapTriggered_Gap5_pp13600GeV.ini | 7 + ...eratorDYee_GapTriggered_Gap5_pp5360GeV.ini | 7 + ...atorDYmumu_GapTriggered_Gap5_OO5360GeV.ini | 7 + ...orDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini | 7 + ...torDYmumu_GapTriggered_Gap5_pp13600GeV.ini | 7 + ...atorDYmumu_GapTriggered_Gap5_pp5360GeV.ini | 7 + .../PWGEM/pythia8/generator/pythia8_DY.cfg | 15 ++ 10 files changed, 222 insertions(+) create mode 100644 MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYLL.C create mode 100644 MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.ini create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYLL.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYLL.C new file mode 100644 index 000000000..3a1ff8df1 --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYLL.C @@ -0,0 +1,151 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TString.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include + +using namespace Pythia8; + +class GeneratorPythia8GapTriggeredDY : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapTriggeredDY() = default; + + /// constructor + GeneratorPythia8GapTriggeredDY(TString configsignal, int leptonPdg = 11, int lInputTriggerRatio = 5, int lInputExternalID = 1, int idA = 2212, int idB = 2212, float eCM = 13600.0) + { + lGeneratedEvents = 0; + lInverseTriggerRatio = lInputTriggerRatio; + lExternalID = lInputExternalID; + mLeptonPdg = leptonPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(lInverseTriggerRatio)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_MB_gapevent.cfg"); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + // overwrite basic configration + pythiaObjectMinimumBias.readString(Form("Beams:idA %d", idA)); + pythiaObjectMinimumBias.readString(Form("Beams:idB %d", idB)); + pythiaObjectMinimumBias.readString(Form("Beams:eCM %f", eCM)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.readString(Form("23:onIfMatch %d %d", -mLeptonPdg, mLeptonPdg)); + // overwrite basic configration + pythiaObjectSignal.readString(Form("Beams:idA %d", idA)); + pythiaObjectSignal.readString(Form("Beams:idB %d", idB)); + pythiaObjectSignal.readString(Form("Beams:eCM %f", eCM)); + + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + addSubGenerator(0, "default generator"); + addSubGenerator(lExternalID, "Drell-Yan"); + } + + /// Destructor + ~GeneratorPythia8GapTriggeredDY() = default; + + void setZRapidity(float yMin, float yMax) + { + mZRapidityMin = yMin; + mZRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Simple straightforward check to alternate generators + if (lGeneratedEvents % lInverseTriggerRatio == 0) { + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + } else { + // Generate minimum-bias event + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + notifySubGenerator(0); + } + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + for (size_t iPart = 0; iPart < event.size(); ++iPart) { + if (event[iPart].id() == 23 && event[iPart].daughterList().size() == 2 && (mZRapidityMin < event[iPart].y() && event[iPart].y() < mZRapidityMax) + && std::abs(event[event[iPart].daughter1()].id()) == mLeptonPdg && std::abs(event[event[iPart].daughter2()].id()) == mLeptonPdg && event[event[iPart].daughter1()].id() * event[event[iPart].daughter2()].id() < 0) { // Z/gamma* -> l+l- + printf("Z/gamma* is found. rapidity = %f, event[iPart].daughterList().size() = %zu\n", event[iPart].y(), event[iPart].daughterList().size()); + printf("event[event[iPart].daughter1()].id() = %d\n", event[event[iPart].daughter1()].id()); + printf("event[event[iPart].daughter2()].id() = %d\n", event[event[iPart].daughter2()].id()); + return true; + } + } // end of particle loop + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mLeptonPdg; + float mZRapidityMin; + float mZRapidityMax; + + // Control gap-triggering + Long64_t lGeneratedEvents; + int lInverseTriggerRatio; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectMinimumBias; ///Minimum bias collision generator + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +FairGenerator* GeneratorPythia8GapTriggeredDYll(int inputTriggerRatio, int inputExternalID, int pdgLepton = 11, float yMin = -1.5, float yMax = 1.5, int idA = 2212, int idB = 2212, float eCM = 13600.0) +{ + auto myGen = new GeneratorPythia8GapTriggeredDY("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg", pdgLepton, inputTriggerRatio, inputExternalID, idA, idB, eCM); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setZRapidity(yMin, yMax); + return myGen; +} + diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini new file mode 100644 index 000000000..f07e285dd --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 1000080160, 1000080160, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini new file mode 100644 index 000000000..8cc7c0ff6 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 1000822080, 1000822080, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini new file mode 100644 index 000000000..7ecf763cf --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 2212, 2212, 13600.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..70e802dec --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 2212, 2212, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.ini new file mode 100644 index 000000000..67001defd --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 1000080160, 1000080160, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini new file mode 100644 index 000000000..de8cefbe8 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 1000822080, 1000822080, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini new file mode 100644 index 000000000..e9a7c06da --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 2212, 2212, 13600.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..82c45f3fd --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 2212, 2212, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg new file mode 100644 index 000000000..4919e698d --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg @@ -0,0 +1,15 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV #user can change eCM from command line. + +### processes +WeakSingleBoson:ffbar2ffbar(s:gmZ) on # ffbar -> Z/gamma* -> ffbar +PhaseSpace:mHatMin 0 +PhaseSpace:mHatMax -1 +PhaseSpace:pTHatMinDiverge 0.5 # this allows for mll > 1 GeV/c2 +23:onMode off # switch off all Z0 decay channels. # User must switch back on Z0 going to l+ l- in C or ini. gamma* is tread as 23, too. + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. From 58146a16da1d355053d163d9589a029e772a127d Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:30:24 +0200 Subject: [PATCH 068/362] Fix light ion generator (#2118) Co-authored-by: Lucamicheletti93 --- ...cktailPromptCharmoniaToMuonEvtGen_pp5TeV.C | 10 ++- .../generator/GeneratorPromptCharmonia.C | 10 ++- ...dPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini | 2 +- ...dPromptCharmoniaMidy_TriggerGap_OO5TeV.ini | 2 +- ...tedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C | 85 +++++++++++++++++++ ...tedPromptCharmoniaMidy_TriggerGap_OO5TeV.C | 84 ++++++++++++++++++ 6 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.C diff --git a/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C b/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C index e7121a97a..63174d4b4 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C +++ b/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C @@ -133,11 +133,17 @@ class O2_GeneratorParamPsi : public GeneratorTGenerator static Double_t YPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) { // psi2s y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + // WARNING! The shape extracted from data provide wired rapidity shape (low stat.), the J/psi one is used Double_t y = *py; Float_t p0, p1, p2; + // Extracted from Psi(2S) Run 2 data + //p0 = 1; + //p1 = -17.4857; + //p2 = 2.98887; + // Same parametrization as J/psi p0 = 1; - p1 = -17.4857; - p2 = 2.98887; + p1 = 0.0338222; + p2 = 2.96748; return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); } diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index 9bcd0bc52..69deba3fa 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -756,11 +756,17 @@ class O2_GeneratorParamPsipp5TeV : public GeneratorTGenerator static Double_t YPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) { // psi2s y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + // WARNING! The shape extracted from data provide wired rapidity shape (low stat.), the J/psi one is used Double_t y = *py; Float_t p0, p1, p2; + // Extracted from Psi(2S) Run 2 data + //p0 = 1; + //p1 = -17.4857; + //p2 = 2.98887; + // Same parametrization as J/psi p0 = 1; - p1 = -17.4857; - p2 = 2.98887; + p1 = 0.0338222; + p2 = 2.96748; return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); } diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini index bbf6ae745..112685838 100755 --- a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini @@ -4,4 +4,4 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_py funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,11) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini index 2c1117580..c8c6d2ee4 100644 --- a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini @@ -4,4 +4,4 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_py funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,12) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From 80c2339acda691a184055d60769edee5f3e26739 Mon Sep 17 00:00:00 2001 From: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:23:50 +0200 Subject: [PATCH 069/362] Charmonium generator for pO (#2120) --- .../generator/GeneratorPromptCharmonia.C | 174 ++++++++++++++++++ ...ithInjectedPromptSignals_gaptriggered_dq.C | 5 +- ...PromptCharmoniaFwdy_TriggerGap_pO96TeV.ini | 7 + ...edPromptCharmoniaFwdy_TriggerGap_pO96TeV.C | 85 +++++++++ 4 files changed, 270 insertions(+), 1 deletion(-) create mode 100755 MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.C diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index 69deba3fa..614c9f3d1 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -787,6 +787,153 @@ class O2_GeneratorParamPsipp5TeV : public GeneratorTGenerator GeneratorParam* paramPsi = nullptr; }; +class O2_GeneratorParamJpsipp96TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsipp96TeV() : GeneratorTGenerator("ParamJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp96TeV, YJPsipp96TeV, V2JPsipp96TeV, IpJPsipp96TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0, 999.); + paramJpsi->SetYRange(-4.2, -2.3); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // (from AliGenParam) -> check this + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsipp96TeV() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // Parameters extrapolated linearly between 5 TeV and 13 TeV as a function of log(sqrt(s)) + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.61097; + p2 = 1.7333; + p3 = 4.45508; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Parameters extrapolated linearly between 5 TeV and 13 TeV as a function of log(sqrt(s)) + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 1; + p1 = 0.0107769; + p2 = 2.98205; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp96TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsipp96TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsipp96TeV() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp96TeV, YPsipp96TeV, V2Psipp96TeV, IpPsipp96TeV); + paramPsi->SetMomentumRange(0., 1.e6); + paramPsi->SetPtRange(0, 999.); + paramPsi->SetYRange(-4.2, -2.3); + paramPsi->SetPhiRange(0., 360.); + paramPsi->SetDecayer(new TPythia6Decayer()); + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // check this + setTGenerator(paramPsi); + }; + + ~O2_GeneratorParamPsipp96TeV() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // Taking same parameters as Psi(2S) at 13 TeV + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.75208; + p2 = 1.69247; + p3 = 4.49224; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taking same parameters as Psi(2S) at 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 1; + p1 = 0; + p2 = 2.98887; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp96TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; + + class O2_GeneratorParamJpsiPbPb5TeV : public GeneratorTGenerator { @@ -1131,6 +1278,33 @@ FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV() return genCocktailEvtGen; } +FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp96TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsipp96TeV; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsipp96TeV; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiMuon); + + return genCocktailEvtGen; +} + + FairGenerator* GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV() { diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C index e58f655e9..20f763b1e 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C @@ -54,12 +54,15 @@ public: case 10: // generate cocktail of prompt X_1(3872) and psi2S to Jpsi pi pi at midrapidity mGeneratorParam = (Generator*)GeneratorCocktailX3872AndPsi2StoJpsi_pp13TeV(); break; - case 11: // generate cocktail of prompt X_1(3872) and psi2S to Jpsi pi pi at midrapidity + case 11: // generate prompt charmonium at forward rapidity at 5TeV mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV(); break; case 12: // generate prompt charmonia cocktail at mid rapidity at 5TeV mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV(); break; + case 13: // generate prompt charmonia cocktail at mid rapidity at 9.6TeV + mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp96TeV(); + break; } mGeneratorParam->Init(); } diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.ini new file mode 100755 index 000000000..b4822ef37 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,13) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From 79cf6dfcc1fa3ad06d0b0bf2707b3a3a7bc61e63 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Sun, 14 Sep 2025 10:02:05 +0200 Subject: [PATCH 070/362] Set ITS options on gpu workflow if included If ITS is running on GPU as part of an asynchronous pass we need to give the gpu-reco-wfx all options from its-reco-wfx. Instead of setting these individually, I think it is better to just summarily set all options. --- DATA/production/configurations/asyncReco/setenv_extra.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index c9a822550..beeab8eee 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -565,6 +565,9 @@ fi # ad-hoc options for GPU reco workflow export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";GPU_global.dEdxDisableResidualGainMap=1;$TRACKTUNETPC;$VDRIFTPARAMOPTION;" +# if ITS is running on GPU we need to give the workflow most options from ITS reco +has_detector_gpu ITS && export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";$CONFIG_EXTRA_PROCESS_o2_its_reco_workflow;" + [[ ! -z $TPCCLUSTERTIMESHIFT ]] && [[ $ALIEN_JDL_LPMPRODUCTIONTYPE != "MC" ]] && export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";GPU_rec_tpc.clustersShiftTimebins=$TPCCLUSTERTIMESHIFT;" # ad-hoc settings for TOF reco From b2a9dccf71be7b969fc68459481914e7f7ae97c8 Mon Sep 17 00:00:00 2001 From: shreyasiacharya <34233706+shreyasiacharya@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:25:58 +0200 Subject: [PATCH 071/362] pronmpt onia at 9.6 TeV extrapolated (#2123) * Merged Charmonium generator for pO for midy * Update GeneratorPromptCharmonia.C, correct pt spectra midY at 5 TeV Jpsi * Update generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C, MidY 9.6 TeV spectra prompt charmonia * Update GeneratorPromptCharmonia.C, prompt onia at 9.6 TeV exptrapolated * Update Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini --- .../generator/GeneratorPromptCharmonia.C | 187 +++++++++++++++++- ...ithInjectedPromptSignals_gaptriggered_dq.C | 5 +- ...PromptCharmoniaMidy_TriggerGap_pO96TeV.ini | 7 + 3 files changed, 190 insertions(+), 9 deletions(-) create mode 100644 MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index 614c9f3d1..141211d58 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -201,11 +201,11 @@ class O2_GeneratorParamJpsiMidY_5TeV : public GeneratorTGenerator //-------------------------------------------------------------------------// static Double_t PtJPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) { - // JPSi pt at 5.02 TeV: https: // www.hepdata.net/record/ins1735351 + // JPSi pt at 5.02 TeV: https: // https://www.hepdata.net/record/ins1899703 (2108.02523) // - const Double_t kC = 1774.9; - const Double_t kpt0 = 3.38452; - const Double_t kn = 2.77889; + const Double_t kC = 1.10642; + const Double_t kpt0 = 4.5504; + const Double_t kn = 3.58669; Double_t pt = px[0]; return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); @@ -272,11 +272,11 @@ class O2_GeneratorParamPsiMidY_5TeV : public GeneratorTGenerator //-------------------------------------------------------------------------// static Double_t PtPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) { - // Same as JPsi at 5.02 TeV since ratio is almost flat in pT: https: // www.hepdata.net/record/ins1735351 + // Same as JPsi at 5.02 TeV since ratio is almost flat in pT // - const Double_t kC = 1774.9; - const Double_t kpt0 = 3.38452; - const Double_t kn = 2.77889; + const Double_t kC = 1.10642; + const Double_t kpt0 = 4.55041; + const Double_t kn = 3.58669; Double_t pt = px[0]; return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); @@ -311,6 +311,151 @@ class O2_GeneratorParamPsiMidY_5TeV : public GeneratorTGenerator GeneratorParam* paramPsi = nullptr; }; +//==================================================================================================== +class O2_GeneratorParamJpsiMidY_96TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsiMidY_96TeV() : GeneratorTGenerator("paramJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp96TeV, YJPsipp96TeV, V2JPsipp96TeV, IpJPsipp96TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0., 1000.); + paramJpsi->SetYRange(-1.0, 1.0); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); // Pythia + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsiMidY_96TeV() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // JPSi pt extrapolated at 9.6 TeV: https: // https://www.hepdata.net/record/ins1899703 (2108.02523) + // + const Double_t kC = 1.48862; + const Double_t kpt0 = 4.64005 + const Double_t kn = 3.57353; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken the same as: jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp96TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsiMidY_96TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsiMidY_96TeV() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp96TeV, YPsipp96TeV, V2Psipp96TeV, IpPsipp96TeV); + paramPsi->SetMomentumRange(0., 1.e6); // Momentum range added from me + paramPsi->SetPtRange(0., 1000.); // transverse of momentum range + paramPsi->SetYRange(-1.0, 1.0); // rapidity range + paramPsi->SetPhiRange(0., 360.); // phi range + paramPsi->SetDecayer(new TPythia6Decayer()); // Pythia decayer + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramPsi); // Setting parameters to ParamPsi for Psi(2S) + }; + + ~O2_GeneratorParamPsiMidY_96TeV() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // Same as JPsi at JPSi pt extrapolated at 9.6 TeV (since ratio is almost flat in pT) + // + // + const Double_t kC = 1.48862; + const Double_t kpt0 = 4.64005 + const Double_t kn = 3.57353; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken same as jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp96TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; +//==================================================================================================== class O2_GeneratorParamJpsiFwdY : public GeneratorTGenerator { @@ -1331,6 +1476,32 @@ FairGenerator* GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV() return genCocktailEvtGen; } +FairGenerator* GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp96TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsiMidY_96TeV; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsiMidY_96TeV; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiElectron); + + return genCocktailEvtGen; +} + FairGenerator* GeneratorParamPromptPsiToJpsiPiPiEvtGen_pp13TeV(TString pdgs = "100443") { diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C index 20f763b1e..896bb7ed5 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C @@ -60,9 +60,12 @@ public: case 12: // generate prompt charmonia cocktail at mid rapidity at 5TeV mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV(); break; - case 13: // generate prompt charmonia cocktail at mid rapidity at 9.6TeV + case 13: // generate prompt charmonia cocktail at fwd rapidity at 9.6TeV mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp96TeV(); break; + case 14: // generate prompt charmonia cocktail at mid rapidity at 9.6TeV + mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp96TeV(); + break; } mGeneratorParam->Init(); } diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini new file mode 100644 index 000000000..0f184d019 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,14) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg From 3a0c8129080918ba3edd649881d20aeeab34922c Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 18 Sep 2025 12:53:06 +0200 Subject: [PATCH 072/362] Restrict search space in MCProd harvester tool --- MC/prodinfo/mcprodinfo_harvester.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/MC/prodinfo/mcprodinfo_harvester.py b/MC/prodinfo/mcprodinfo_harvester.py index 352c89e79..40c431a25 100755 --- a/MC/prodinfo/mcprodinfo_harvester.py +++ b/MC/prodinfo/mcprodinfo_harvester.py @@ -135,6 +135,16 @@ def split_key(entry): def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None): base_path = f"/alice/sim/{year}/{prod_tag}" + workflow_files = alien_find(base_path, "workflow.json") + # exclude some unnecessary paths + workflow_files = [ + zf for zf in workflow_files + if "/AOD/" not in zf and "/QC/" not in zf and "/TimeseriesTPCmerging/" not in zf and "/Stage" not in zf + ] + # directories containing workflow.json + workflow_dirs = {os.path.dirname(wf) for wf in workflow_files} + print (f"Found {len(workflow_dirs)} workflow dirs") + # Step 1: find all log_archive.zip files print (f"Querying AliEn for all directories with zip files") zip_files = alien_find(base_path, "log_archive.zip") @@ -144,10 +154,15 @@ def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None): zf for zf in zip_files if "/AOD/" not in zf and "/QC/" not in zf and "/TimeseriesTPCmerging/" not in zf and "/Stage" not in zf ] + zip_files_dirs = {os.path.dirname(zf) for zf in zip_files} + print (f"Found {len(zip_files_dirs)} zip dirs") + + # keep only zips in dirs where workflow.json also exists + relevant_zips = [zf for zf in zip_files if os.path.dirname(zf) in workflow_dirs] # Step 2: group by run_number runs = defaultdict(list) - for zf in zip_files: + for zf in relevant_zips: parsed = parse_workflow_path(zf, prod_tag) if parsed is None: continue From 07ed1d34b1575877642af1adc977a52a737bca84 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 19 Sep 2025 08:05:45 +0200 Subject: [PATCH 073/362] improvements and alternative version for fileaccess monitoring --- UTILS/FileIOGraph/monitor_fileaccess.cpp | 12 +- UTILS/FileIOGraph/monitor_fileaccess_v2.cpp | 210 ++++++++++++++++++++ 2 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 UTILS/FileIOGraph/monitor_fileaccess_v2.cpp diff --git a/UTILS/FileIOGraph/monitor_fileaccess.cpp b/UTILS/FileIOGraph/monitor_fileaccess.cpp index 50567e593..9c7519c6b 100644 --- a/UTILS/FileIOGraph/monitor_fileaccess.cpp +++ b/UTILS/FileIOGraph/monitor_fileaccess.cpp @@ -64,7 +64,7 @@ std::string getcmd(pid_t pid) fclose(file); for (int byte = 0; byte < bytesRead; ++byte) { if (buffer[byte] == '\0') { - buffer[byte] == '@'; + buffer[byte] = '@'; } } return std::string(buffer); @@ -98,7 +98,7 @@ int main(int argc, char** argv) { int fan; char buf[4096]; - char fdpath[32]; + char fdpath[64]; char path[PATH_MAX + 1]; ssize_t buflen, linklen; struct fanotify_event_metadata* metadata; @@ -114,11 +114,11 @@ int main(int argc, char** argv) auto MAX_MOTHER_PID_ENV = getenv("MAXMOTHERPID"); int max_mother_pid = 1; // everything if (MAX_MOTHER_PID_ENV != nullptr) { - std::cerr << "found env variablen"; + std::cerr << "found env variable MAX_MOTHER_PID_ENV"; max_mother_pid = std::atoi(MAX_MOTHER_PID_ENV); std::cerr << "Setting topmost mother process to " << max_mother_pid << "\n"; } else { - std::cerr << "No environment given\n"; + std::cerr << "No environment given. Monitoring globally.\n"; } auto thispid = getpid(); @@ -174,10 +174,10 @@ int main(int argc, char** argv) } if (metadata->mask & FAN_CLOSE_WRITE) { - printf("%s,write,%s\n", path, parentspid->c_str()); + printf("\"%s\",write,%s\n", path, parentspid->c_str()); } if (metadata->mask & FAN_CLOSE_NOWRITE) { - printf("%s,read,%s\n", path, parentspid->c_str()); + printf("\"%s\",read,%s\n", path, parentspid->c_str()); } } diff --git a/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp new file mode 100644 index 000000000..d5420491c --- /dev/null +++ b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHK(expr, errcode) \ + if ((expr) == errcode) \ + { \ + perror(#expr); \ + exit(EXIT_FAILURE); \ + } + +#define MAXBUF (BUFSIZ * 2) + +int getppid_safe(int pid) +{ + int ppid = 0; + char buf[MAXBUF]; + char procname[64]; // big enough for /proc//status + FILE *fp; + + snprintf(procname, sizeof(procname), "/proc/%d/status", pid); + fp = fopen(procname, "r"); + if (fp != NULL) + { + size_t ret = fread(buf, sizeof(char), MAXBUF - 1, fp); + if (ret > 0) + buf[ret] = '\0'; + fclose(fp); + } + char *ppid_loc = strstr(buf, "\nPPid:"); + if (ppid_loc) + { + if (sscanf(ppid_loc, "\nPPid:%d", &ppid) != 1) + return 0; + return ppid; + } + return 0; +} + +std::string getcmd(pid_t pid) +{ + if (pid == 0 || pid == 1) + return std::string(""); + + char path[64]; + snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); + + FILE *file = fopen(path, "r"); + if (file) + { + char buffer[1024]; // max 1k command line + size_t bytesRead = fread(buffer, 1, sizeof(buffer), file); + fclose(file); + for (size_t i = 0; i < bytesRead; ++i) + { + if (buffer[i] == '\0') + buffer[i] = '@'; + } + return std::string(buffer, bytesRead); + } + return std::string(""); +} + +std::unordered_map good_pid_cache; +std::unordered_map pid_to_parents; +std::unordered_map pid_to_command; + +bool is_good_pid(int pid, int maxparent) +{ + auto iter = good_pid_cache.find(pid); + if (iter != good_pid_cache.end()) + return iter->second; + + if (pid == maxparent) + return good_pid_cache[pid] = true; + if (pid == 0) + return good_pid_cache[pid] = false; + + return good_pid_cache[pid] = is_good_pid(getppid_safe(pid), maxparent); +} + +std::string build_parent_chain(int pid, int maxparent) +{ + auto iter = pid_to_parents.find(pid); + if (iter != pid_to_parents.end()) + return iter->second; + + std::stringstream str; + int current = pid; + str << current; + while (current != maxparent && current != 0) + { + if (pid_to_command.find(current) == pid_to_command.end()) + { + std::string cmd = getcmd(current); + pid_to_command[current] = cmd; + fprintf(stdout, "pid-to-command:%i:%s\n", current, cmd.c_str()); + } + int next = getppid_safe(current); + current = next; + str << ";" << current; + } + pid_to_parents[pid] = str.str(); + return str.str(); +} + +int main(int argc, char **argv) +{ + int fan; + char buf[8192]; + char fdpath[64]; + char path[PATH_MAX + 1]; + ssize_t buflen, linklen; + struct fanotify_event_metadata *metadata; + + // init fanotify + CHK(fan = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY), -1); + CHK(fanotify_mark(fan, FAN_MARK_ADD | FAN_MARK_MOUNT, + FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE | FAN_EVENT_ON_CHILD, + AT_FDCWD, "/"), + -1); + + // read env for filtering + auto MAX_MOTHER_PID_ENV = getenv("MAXMOTHERPID"); + int max_mother_pid = 1; // default: allow everything + if (MAX_MOTHER_PID_ENV != nullptr) + { + max_mother_pid = std::atoi(MAX_MOTHER_PID_ENV); + std::cerr << "Setting topmost mother process to " << max_mother_pid << "\n"; + } + else + { + std::cerr << "No MAXMOTHERPID environment given\n"; + } + + auto thispid = getpid(); + + struct pollfd fds[1]; + fds[0].fd = fan; + fds[0].events = POLLIN; + + for (;;) + { + int pollres = poll(fds, 1, -1); // wait indefinitely + if (pollres == -1) + { + perror("poll"); + continue; + } + + if (fds[0].revents & POLLIN) + { + buflen = read(fan, buf, sizeof(buf)); + if (buflen == -1) + { + perror("read"); + continue; + } + metadata = (struct fanotify_event_metadata *)&buf; + while (FAN_EVENT_OK(metadata, buflen)) + { + if (metadata->mask & FAN_Q_OVERFLOW) + { + fprintf(stderr, "Queue overflow!\n"); + continue; + } + snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", metadata->fd); + linklen = readlink(fdpath, path, sizeof(path) - 1); + if (linklen >= 0) + { + path[linklen] = '\0'; + int pid = metadata->pid; + + bool record = true; + record = record && pid != thispid; + record = record && (metadata->mask & (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)); + record = record && is_good_pid(pid, max_mother_pid); + + if (record) + { + std::string parent_chain = build_parent_chain(pid, max_mother_pid); + + if (metadata->mask & FAN_CLOSE_WRITE) + { + printf("\"%s\",write,%s\n", path, parent_chain.c_str()); + fflush(stdout); + } + if (metadata->mask & FAN_CLOSE_NOWRITE) + { + printf("\"%s\",read,%s\n", path, parent_chain.c_str()); + fflush(stdout); + } + } + } + close(metadata->fd); + metadata = FAN_EVENT_NEXT(metadata, buflen); + } + } + } +} From 3a567c0a259410b873140d99b987a14c552b4800 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 19 Sep 2025 10:32:55 +0200 Subject: [PATCH 074/362] adjustments to runGRIDContainerized --- GRID/utils/runGRIDContainerized.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/GRID/utils/runGRIDContainerized.sh b/GRID/utils/runGRIDContainerized.sh index 75bacc182..c66c941cb 100755 --- a/GRID/utils/runGRIDContainerized.sh +++ b/GRID/utils/runGRIDContainerized.sh @@ -15,11 +15,8 @@ else echo "Invalid architecture ${ARCH} detected. Exiting" exit 1 fi -if [ "$ARCH" == "aarch64" ]; then - ISAARCH64="1" -fi # we just use the default singularity container (if not already set) -APPTAINER_CONTAINER=${APPTAINER_CONTAINER:-/cvmfs/alice.cern.ch/containers/fs/singularity/default${ISAARCH64+"-aarch64"}} +APPTAINER_CONTAINER=${APPTAINER_CONTAINER:-/cvmfs/alice.cern.ch/containers/fs/apptainer/compat_el9-${ARCH}} # create workdir if not specified externally if [ ! "${WORK_DIR}" ]; then @@ -49,5 +46,6 @@ echo "JALIEN_TOKEN_CERT=/workdir/usercert.pem" > ${WORK_DIR}/envfile echo "JALIEN_TOKEN_KEY=/workdir/userkey.pem" >> ${WORK_DIR}/envfile # launch job = script inside the container in the workdir -/cvmfs/alice.cern.ch/containers/bin/apptainer/current${ISAARCH64+"-aarch64"}/bin/apptainer exec -C -B /cvmfs:/cvmfs,${WORK_DIR}:/workdir \ - --pwd /workdir --env-file ${WORK_DIR}/envfile ${APPTAINER_CONTAINER} /workdir/job.sh +APPTAINER_EXEC="/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer" +${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${WORK_DIR}:/workdir \ + --pwd /workdir --env-file ${WORK_DIR}/envfile ${APPTAINER_CONTAINER} /workdir/job.sh From 5a52d241fe8f9fc87243def1ef25ba2973b2f36c Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 19 Sep 2025 13:57:39 +0200 Subject: [PATCH 075/362] filemonitor improvements --- UTILS/FileIOGraph/monitor_fileaccess_v2.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp index d5420491c..e12e3c6b9 100644 --- a/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp +++ b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp @@ -124,10 +124,19 @@ int main(int argc, char **argv) struct fanotify_event_metadata *metadata; // init fanotify + + // with this we can observe specific root directories + auto ROOT_PATH_ENV = getenv("FILEACCESS_MON_ROOTPATH"); + std::string root_path = "/"; + if (ROOT_PATH_ENV) { + std::cerr << "Observing file access below " << root_path << "\n"; + root_path = std::string(ROOT_PATH_ENV); + } + CHK(fan = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY), -1); CHK(fanotify_mark(fan, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE | FAN_EVENT_ON_CHILD, - AT_FDCWD, "/"), + AT_FDCWD, root_path.c_str()), -1); // read env for filtering From ec128f33094ca62d8bbe4bdad191dc83650d5119 Mon Sep 17 00:00:00 2001 From: Jonghan Park <40240384+jpxrk@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:12:32 +0900 Subject: [PATCH 076/362] change eta gap (#2125) --- .../PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini index 957daf1e8..45433e588 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini @@ -1,7 +1,7 @@ ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C -funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5) +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1., 1.) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg From 9d0149b1e9a54a62193ebc3c1780a99540c92e3b Mon Sep 17 00:00:00 2001 From: Jonghan Park <40240384+jpxrk@users.noreply.github.com> Date: Tue, 23 Sep 2025 16:10:47 +0900 Subject: [PATCH 077/362] change configuration (#2127) --- .../PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini index 45433e588..9f7191c80 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini @@ -1,7 +1,7 @@ ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C -funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1., 1.) +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.0, 1.0, {11}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg From 8eb8228a76f63803f31664161e896de549bd8372 Mon Sep 17 00:00:00 2001 From: swenzel Date: Mon, 22 Sep 2025 15:02:58 +0200 Subject: [PATCH 078/362] O2DPG workflow: Integration of fileaccess reporting * improvements to analyse_FileIO.py * o2dpg_workflow_runner.py: Integrated option to produce fileaccess reports --- MC/bin/o2_dpg_workflow_runner.py | 48 +++++++++++++++++++-- UTILS/FileIOGraph/analyse_FileIO.py | 12 +++++- UTILS/FileIOGraph/monitor_fileaccess_v2.cpp | 2 +- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index 14cc866ff..02d25588f 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -85,7 +85,8 @@ def setup_logger(name, log_file, level=logging.INFO): return logger # first file logger -actionlogger = setup_logger('pipeline_action_logger', ('pipeline_action_' + str(os.getpid()) + '.log', args.action_logfile)[args.action_logfile!=None], level=logging.DEBUG) +actionlogger_file = ('pipeline_action_' + str(os.getpid()) + '.log', args.action_logfile)[args.action_logfile!=None] +actionlogger = setup_logger('pipeline_action_logger', actionlogger_file, level=logging.DEBUG) # second file logger metriclogger = setup_logger('pipeline_metric_logger', ('pipeline_metric_' + str(os.getpid()) + '.log', args.action_logfile)[args.action_logfile!=None]) @@ -1808,5 +1809,46 @@ def speedup_ROOT_Init(): exit(code) actionlogger.info("Running in cgroup") -executor=WorkflowExecutor(args.workflowfile,jmax=int(args.maxjobs),args=args) -exit (executor.execute()) + +# This starts the fanotify fileaccess monitoring process +# if asked for +o2dpg_filegraph_exec = os.getenv("O2DPG_PRODUCE_FILEGRAPH") # switches filegraph monitoring on and contains the executable name +if o2dpg_filegraph_exec: + env = os.environ.copy() + env["FILEACCESS_MON_ROOTPATH"] = os.getcwd() + env["MAXMOTHERPID"] = f"{os.getpid()}" + + fileaccess_log_file_name = f"pipeline_fileaccess_{os.getpid()}.log" + fileaccess_log_file = open(fileaccess_log_file_name, "w") + fileaccess_monitor_proc = subprocess.Popen( + [o2dpg_filegraph_exec], + stdout=fileaccess_log_file, + stderr=subprocess.STDOUT, + env=env) +else: + fileaccess_monitor_proc = None + +try: + # This is core workflow runner invocation + executor=WorkflowExecutor(args.workflowfile,jmax=int(args.maxjobs),args=args) + rc = executor.execute() +finally: + if fileaccess_monitor_proc: + fileaccess_monitor_proc.terminate() # sends SIGTERM + try: + fileaccess_monitor_proc.wait(timeout=5) + except subprocess.TimeoutExpired: + fileaccess_monitor_proc.kill() # force kill if not stopping + # now produce the final filegraph output + o2dpg_root = os.getenv("O2DPG_ROOT") + analyse_cmd = [ + sys.executable, # runs with same Python interpreter + f"{o2dpg_root}/UTILS/FileIOGraph/analyse_FileIO.py", + "--actionFile", actionlogger_file, + "--monitorFile", fileaccess_log_file_name, + "-o", f"pipeline_fileaccess_report_{os.getpid()}.json", + "--basedir", os.getcwd() ] + print (f"Producing FileIOGraph with command {analyse_cmd}") + subprocess.run(analyse_cmd, check=True) + +sys.exit(rc) \ No newline at end of file diff --git a/UTILS/FileIOGraph/analyse_FileIO.py b/UTILS/FileIOGraph/analyse_FileIO.py index 5ad4523f9..f2e35c736 100755 --- a/UTILS/FileIOGraph/analyse_FileIO.py +++ b/UTILS/FileIOGraph/analyse_FileIO.py @@ -22,7 +22,7 @@ # the run-number of data taking or default if unanchored parser.add_argument('--actionFile', type=str, help="O2DPG pipeline runner action file") parser.add_argument('--monitorFile', type=str, help="monitoring file provided by fanotify tool. See O2DPG/UTILS/FileIOGraph.") -parser.add_argument('--basedir', type=str, help="O2DPG workflow dir") +parser.add_argument('--basedir', default="/", type=str, help="O2DPG workflow dir") parser.add_argument('--file-filters', nargs='+', default=[r'.*'], help="Filters (regular expressions) to select files (default all = '.*')") parser.add_argument('--graphviz', type=str, help="Produce a graphviz plot") parser.add_argument('-o','--output', type=str, help="Output JSON report") @@ -60,7 +60,8 @@ file_written_task = {} file_consumed_task = {} -pattern = re.compile(args.basedir + r'([^,]+),((?:read|write)),(.*)') +pattern = re.compile(r'"?([^"]+)"?,((?:read|write)),(.*)') +basedir_pattern = re.compile("^" + args.basedir) # neglecting some framework file names file_exclude_filter = re.compile(r'(.*)\.log(.*)|(ccdb/log)|(.*)dpl-config\.json') @@ -76,6 +77,13 @@ mode = match.group(2) pids = match.group(3).split(";") + # see if matches the workdir + if not basedir_pattern.match(file_name): + continue + + # remove basedir from file_name + file_name = file_name.replace(args.basedir + '/', "./", 1) + # implement file name filter if file_exclude_filter.match(file_name): continue diff --git a/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp index e12e3c6b9..2f3750bc6 100644 --- a/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp +++ b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp @@ -129,8 +129,8 @@ int main(int argc, char **argv) auto ROOT_PATH_ENV = getenv("FILEACCESS_MON_ROOTPATH"); std::string root_path = "/"; if (ROOT_PATH_ENV) { - std::cerr << "Observing file access below " << root_path << "\n"; root_path = std::string(ROOT_PATH_ENV); + std::cerr << "Observing file access below " << root_path << "\n"; } CHK(fan = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY), -1); From 420dc041bbe4c2060a2bfb9b08a406c4b82bd927 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 23 Sep 2025 14:11:25 +0200 Subject: [PATCH 079/362] improvements for runGRIDContainerized * allows injection of CVMFS software package via env variable * allow executing apptainer under sudo - useful for certain payloads --- GRID/utils/runGRIDContainerized.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/GRID/utils/runGRIDContainerized.sh b/GRID/utils/runGRIDContainerized.sh index c66c941cb..e583b1b97 100755 --- a/GRID/utils/runGRIDContainerized.sh +++ b/GRID/utils/runGRIDContainerized.sh @@ -44,8 +44,21 @@ cp ${ALIEN_KEYFILE} ${WORK_DIR}/userkey.pem echo "JALIEN_TOKEN_CERT=/workdir/usercert.pem" > ${WORK_DIR}/envfile echo "JALIEN_TOKEN_KEY=/workdir/userkey.pem" >> ${WORK_DIR}/envfile +if [ "${GRID_CVMFS_PACKAGE}" ]; then + echo "GRID_CVMFS_PACKAGE=${GRID_CVMFS_PACKAGE}" >> ${WORK_DIR}/envfile +fi + +# load a CVMFS package if we are asked to do so -- but do it as part of the job +LOADER='if [ "${GRID_CVMFS_PACKAGE}" ]; then + /cvmfs/alice.cern.ch/bin/alienv printenv ${GRID_CVMFS_PACKAGE} > cvmfs_env + source cvmfs_env +fi' +# Inject the block after the first line (shebang) +JOBSCRIPT=${WORK_DIR}/job.sh +awk -v block="$LOADER" 'NR==1 {print; print block; next} 1' "$JOBSCRIPT" > tmpfile && mv tmpfile "$JOBSCRIPT" +chmod +x "${JOBSCRIPT}" # launch job = script inside the container in the workdir -APPTAINER_EXEC="/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer" -${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${WORK_DIR}:/workdir \ +APPTAINER_EXEC=${APPTAINER_EXEC:-"/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer"} +${APPTAINER_SUDO:+sudo} ${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${WORK_DIR}:/workdir \ --pwd /workdir --env-file ${WORK_DIR}/envfile ${APPTAINER_CONTAINER} /workdir/job.sh From 17810b670cde7a83da68aacfc7d784e6c9b1e14a Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 24 Sep 2025 13:10:26 +0200 Subject: [PATCH 080/362] exec under bash --- GRID/utils/runGRIDContainerized.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GRID/utils/runGRIDContainerized.sh b/GRID/utils/runGRIDContainerized.sh index e583b1b97..3fc2380a4 100755 --- a/GRID/utils/runGRIDContainerized.sh +++ b/GRID/utils/runGRIDContainerized.sh @@ -61,4 +61,4 @@ chmod +x "${JOBSCRIPT}" # launch job = script inside the container in the workdir APPTAINER_EXEC=${APPTAINER_EXEC:-"/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer"} ${APPTAINER_SUDO:+sudo} ${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${WORK_DIR}:/workdir \ - --pwd /workdir --env-file ${WORK_DIR}/envfile ${APPTAINER_CONTAINER} /workdir/job.sh + --pwd /workdir --env-file ${WORK_DIR}/envfile ${APPTAINER_CONTAINER} bash /workdir/job.sh From f535c06a03360e46f0f2c132dddf3253a6703d29 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Wed, 10 Sep 2025 15:04:21 +0200 Subject: [PATCH 081/362] UTILS: add helper script to create raw files from rawtf files for REPLAY datasets --- UTILS/rawTF2raw/README.md | 40 +++++++++ UTILS/rawTF2raw/generate_rawtf_indices.sh | 98 +++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 UTILS/rawTF2raw/README.md create mode 100644 UTILS/rawTF2raw/generate_rawtf_indices.sh diff --git a/UTILS/rawTF2raw/README.md b/UTILS/rawTF2raw/README.md new file mode 100644 index 000000000..4ed14be48 --- /dev/null +++ b/UTILS/rawTF2raw/README.md @@ -0,0 +1,40 @@ + The script `generate_rawtf_indices.sh` provides functions to extract a list of consecutive TFs form a list of `*rawtf*.tf` files and create the corresponding `*.raw` files, e.g. for REPLAY datasets at P2. + +Input parameters for sourcing the script: +- param1: list with input `*rawtf*.tf` files; expected file name (for extraction of period and run number): rawtflist__.txt, e.g. rawtflist_LHC25ab_563041.txt +- param2: directory to store output `*.raw` files +- param3: number of TFs to store as `*.raw` files +- param4: tfCounter id of first TF to process, e.g. at least 3500 to skip ITS ROF rate ramp up +- param5: number of input Blocks to be expected per TF to select only TFs with all inputs / detectors present + - if number of inputs is irrelevant, it can be set to 0 to be ignored + +Available functions by sourcing the script: +- `check_tfs_per_file` + - print the average number of TFs per file from a small subset of rawtf files from the input file list +- `sort_tfs` + - sort the TFs from the input file list in continuous order and save the corresponding timeslice ids in the order they appear in the input file list + - if nBlocks (parameter 5) is not 0, then there is an additional check on the number of requested inputs defined by nBlocks + - outputs: + - tf-reader_*.log: full log output from o2-raw-tf-reader-workflow which is used to grep for the timeslice and tfCounter ids + - tfids_*.txt: list with timeslice and tfCounter ids, sorted by tfCounter + - timeslices_*.txt: sorted list of \$nTFs timeslice indices to be used for raw data creation +- `create_raw_files` + - use sorted list of timeslice ids created with sort_tfs as input to create *.raw files for those timeslices + - the final command (for reference) and the full log output is written to \$outputDir.log + +Example usage: +``` +# source functions and set input / output parameters +# in this case: process 125 TFs, start at tfCounter id 3500, check `*rawtf*.tf` files for number of inputs and only use TFs with (in this case) 14 inputs to ensure all detectors from this run are present +source $O2DPG_ROOT/UTILS/rawTF2raw/generate_rawtf_indices.sh rawtflist_LHC25ab_563041.txt 2025-05-19-pp-750khz-replay-LHC25ab-563041 125 3500 14 + +# create input list of timeslice IDs to be processed for `*.raw` file creation (`timeslices_*.txt`) +# timeslice IDs from this list correspond to \$nTFs consecutive tfCounter ids +# intermediate outputs from o2-raw-tf-reader-workflow and the sorted list of all tfCounter ids will also be stored (`reader_*.log` and `tfids_*.txt`) +sort_tfs + +# create `*.raw` files for timeslices in `timeslices_*.txt` created in the previous step +create_raw_files +``` + + diff --git a/UTILS/rawTF2raw/generate_rawtf_indices.sh b/UTILS/rawTF2raw/generate_rawtf_indices.sh new file mode 100644 index 000000000..e68a9ffb3 --- /dev/null +++ b/UTILS/rawTF2raw/generate_rawtf_indices.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# source $O2DPG_ROOT/UTILS/rawTF2raw/generate_rawtf_indices.sh + +print_help() { + cat < ${tfreader_log} + if [ "0$nBlocks" -eq "00" ]; then + grep 'tf-reader.*Done processing' ${tfreader_log} | sed 's/,//g' | awk '{print $5,$6,$7,$9}' | sort -t ':' -k 3 -h >${tfs_sorted} + else + grep 'tf-reader' ${tfreader_log} | grep -v -e 'Executing sh' -e 'Resuming reading' -e 'Processing file' | grep "Block:${nBlocks}" -A 6 | grep 'Done processing' | sed 's/,//g' | awk '{print $5,$6,$7,$9}' | sort -t ':' -k 3 -h >${tfs_sorted} + fi + firstTFtmp=${firstTF} + while true; do + firstLine=$(grep -nr tfCounter:${firstTFtmp} ${tfs_sorted} | awk -F ':' '{print $1}') + [[ ! -z ${firstLine} ]] && break + firstTFtmp=$((firstTFtmp+1)) + done + tail -n +${firstLine} ${tfs_sorted} | head -n ${nTFs} | awk '{print $1}' | sort -V | sed -z -e 's/timeslice://g ; s/\n/,/g ; s/,$//g' >${timeslices_sorted} +} + +# creation of raw data +create_raw_files() { + mkdir -p ${outputDir} + echo "LID=\"$(cat ${timeslices_sorted})\"" | tee ${outputDir}.log + LID=$(cat ${timeslices_sorted}) + echo "o2-raw-tf-reader-workflow --raw-only-det all --shm-segment-size 16000000000 --input-data ${rawtfFileList} --select-tf-ids " '$LID' " | o2-raw-data-dump-workflow --tof-input-uncompressed --shm-segment-size 16000000000 --fatal-on-deadbeef --output-directory ${outputDir} --dump-verbosity 1 --run | tee -a ${outputDir}.log" | tee -a ${outputDir}.log + o2-raw-tf-reader-workflow --raw-only-det all --shm-segment-size 16000000000 --input-data ${rawtfFileList} --select-tf-ids "$LID" | o2-raw-data-dump-workflow --tof-input-uncompressed --shm-segment-size 16000000000 --fatal-on-deadbeef --output-directory ${outputDir} --dump-verbosity 1 --run | tee -a ${outputDir}.log +} From 6e0114686b1835f66c2d4120118f1a31ea3624b3 Mon Sep 17 00:00:00 2001 From: Sebastian Scheid Date: Wed, 24 Sep 2025 16:57:34 +0200 Subject: [PATCH 082/362] add param for dielectron OO cocktail based on pythia (#2124) * add param for OO based on pythia * add ini for OO LMee cocktail * Add test for OO cocktail * BR with max 6 digits after decimal point --- .../PWGEM/decaytables/decaytable_LMee.dat | 108 +++++++++--------- .../PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini | 6 + .../ini/tests/GeneratorEMCocktail_Run3_OO.C | 64 +++++++++++ .../parametrizations/OO_536TeV_param.json | 10 ++ 4 files changed, 134 insertions(+), 54 deletions(-) create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_Run3_OO.C create mode 100644 MC/config/PWGEM/parametrizations/OO_536TeV_param.json diff --git a/MC/config/PWGEM/decaytables/decaytable_LMee.dat b/MC/config/PWGEM/decaytables/decaytable_LMee.dat index 5b3953b6f..03f88f65a 100644 --- a/MC/config/PWGEM/decaytables/decaytable_LMee.dat +++ b/MC/config/PWGEM/decaytables/decaytable_LMee.dat @@ -280,74 +280,74 @@ 1 0 0.000000 -11 11 -11 11 0 1 0 0.000000 -11 11 0 0 0 221 eta 0 0 0 0.54786 0.001308 0.00000 1.50886E-07 0 1 - 1 0 0.3935878 22 22 0 0 0 - 1 0 0.3256175 111 111 111 0 0 - 1 0 0.0002554 111 22 22 0 0 - 1 0 0.2301877 211 -211 111 0 0 - 1 0 0.0427689 22 211 -211 0 0 - 1 2 0.0070044 22 11 -11 0 0 - 1 0 0.0003101 22 13 -13 0 0 - 1 0 0.0000058 -13 13 0 0 0 - 1 0 0.0000007 -11 11 0 0 0 - 1 0 0.0000000 -11 11 -11 11 0 - 1 0 0.0000000 211 -211 11 -11 0 + 1 0 0.393588 22 22 0 0 0 + 1 0 0.325618 111 111 111 0 0 + 1 0 0.000255 111 22 22 0 0 + 1 0 0.230188 211 -211 111 0 0 + 1 0 0.042769 22 211 -211 0 0 + 1 2 0.007004 22 11 -11 0 0 + 1 0 0.000310 22 13 -13 0 0 + 1 0 0.000006 -13 13 0 0 0 + 1 0 0.000001 -11 11 0 0 0 + 1 0 0.000000 -11 11 -11 11 0 + 1 0 0.000000 211 -211 11 -11 0 331 eta' 0 0 0 0.95778 0.000188 0.002 1.00336E-09 0 1 - 1 0 0.4246864 211 -211 221 0 0 - 1 0 0.2948085 22 113 0 0 0 - 1 0 0.2237140 111 111 221 0 0 - 1 0 0.0251900 22 223 0 0 0 - 1 0 0.0001970 223 -11 11 0 0 - 1 0 0.0230680 22 22 0 0 0 - 1 0 0.0024994 111 111 111 0 0 - 1 0 0.0001130 22 -13 13 0 0 - 1 0 0.0036058 211 -211 111 0 0 - 1 0 0.0000010 211 -211 211 -211 0 - 1 0 0.0001800 211 -211 111 111 0 - 1 0 0.0000000 211 -211 -11 11 0 - 1 2 0.0004803 22 11 -11 0 0 - 1 0 0.0000000 -11 11 -11 11 0 + 1 0 0.424687 211 -211 221 0 0 + 1 0 0.294809 22 113 0 0 0 + 1 0 0.223714 111 111 221 0 0 + 1 0 0.025190 22 223 0 0 0 + 1 0 0.000197 223 -11 11 0 0 + 1 0 0.023068 22 22 0 0 0 + 1 0 0.002499 111 111 111 0 0 + 1 0 0.000113 22 -13 13 0 0 + 1 0 0.003606 211 -211 111 0 0 + 1 0 0.000001 211 -211 211 -211 0 + 1 0 0.000180 211 -211 111 111 0 + 1 0 0.000000 211 -211 -11 11 0 + 1 2 0.000480 22 11 -11 0 0 + 1 0 0.000000 -11 11 -11 11 0 113 rho0 0 0 0 0.77526 0.14739 0.40000 1.33000E-12 0 1 1 3 0.988927 211 -211 0 0 0 1 0 0.009900 211 -211 22 0 0 - 1 0 0.0004669 111 22 0 0 0 - 1 0 0.0002997 221 22 0 0 0 - 1 0 0.0000445 111 111 22 0 0 - 1 0 0.0000472 11 -11 0 0 0 - 1 0 0.0000455 13 -13 0 0 0 + 1 0 0.000467 111 22 0 0 0 + 1 0 0.000300 221 22 0 0 0 + 1 0 0.000045 111 111 22 0 0 + 1 0 0.000047 11 -11 0 0 0 + 1 0 0.000046 13 -13 0 0 0 1 0 0.000101 211 -211 111 0 0 1 0 0.000018 -211 211 -211 211 0 1 0 0.000016 -211 211 111 111 0 223 omega 0 0 0 0.78266 0.00868 0.10000 2.33000E-11 0 1 - 1 1 0.8924576 211 -211 111 0 0 - 1 0 0.0832642 22 111 0 0 0 - 1 3 0.0153487 211 -211 0 0 0 - 1 0 0.0004478 221 22 0 0 0 - 1 0 0.0001336 111 13 -13 0 0 - 1 0 0.0007673 111 11 -11 0 0 - 1 0 0.0000741 11 -11 0 0 0 - 1 0 0.0000666 111 111 22 0 0 - 1 0 0.0000740 13 -13 0 0 0 + 1 1 0.892458 211 -211 111 0 0 + 1 0 0.083264 22 111 0 0 0 + 1 3 0.015349 211 -211 0 0 0 + 1 0 0.000448 221 22 0 0 0 + 1 0 0.000134 111 13 -13 0 0 + 1 0 0.000767 111 11 -11 0 0 + 1 0 0.000074 11 -11 0 0 0 + 1 0 0.000067 111 111 22 0 0 + 1 0 0.000074 13 -13 0 0 0 333 phi 0 0 0 1.01946 0.004249 0.01500 4.63000E-11 0 1 - 1 3 0.4988842 321 -321 0 0 0 - 1 3 0.3364070 130 310 0 0 0 + 1 3 0.498884 321 -321 0 0 0 + 1 3 0.336407 130 310 0 0 0 1 0 0.042259 213 -211 0 0 0 1 0 0.042259 -213 211 0 0 0 1 0 0.042259 113 111 0 0 0 1 1 0.026534 211 -211 111 0 0 - 1 0 0.0130621 221 22 0 0 0 - 1 0 0.0013280 111 22 0 0 0 - 1 0 0.0002963 11 -11 0 0 0 - 1 0 0.0002862 13 -13 0 0 0 - 1 0 0.0001084 221 -11 11 0 0 - 1 0 0.0000950 211 -211 0 0 0 - 1 0 0.0000473 223 111 0 0 0 - 1 0 0.0000410 -211 211 22 0 0 - 1 0 0.0001126 111 111 22 0 0 - 1 0 0.0000039 -211 211 -211 211 0 - 1 0 0.0000133 111 -11 11 0 0 - 1 0 0.0000726 111 221 22 0 0 + 1 0 0.013062 221 22 0 0 0 + 1 0 0.001328 111 22 0 0 0 + 1 0 0.000296 11 -11 0 0 0 + 1 0 0.000286 13 -13 0 0 0 + 1 0 0.000108 221 -11 11 0 0 + 1 0 0.000095 211 -211 0 0 0 + 1 0 0.000047 223 111 0 0 0 + 1 0 0.000041 -211 211 22 0 0 + 1 0 0.000113 111 111 22 0 0 + 1 0 0.000004 -211 211 -211 211 0 + 1 0 0.000013 111 -11 11 0 0 + 1 0 0.000073 111 221 22 0 0 1 0 0.000063 331 22 0 0 0 - 1 0 0.0000143 -13 13 22 0 0 + 1 0 0.000014 -13 13 22 0 0 443 J/Psi 0 0 0 3.09690 0.000093 0.00000 2.13000E-09 0 1 1 12 0.881200 82 -82 0 0 0 1 0 0.059710 11 -11 0 0 0 diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini new file mode 100644 index 000000000..83898beae --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(200,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/OO_536TeV_param.json","536TeV_MB_pythia",200,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_Run3_OO.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_Run3_OO.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_Run3_OO.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/parametrizations/OO_536TeV_param.json b/MC/config/PWGEM/parametrizations/OO_536TeV_param.json new file mode 100644 index 000000000..bad021d49 --- /dev/null +++ b/MC/config/PWGEM/parametrizations/OO_536TeV_param.json @@ -0,0 +1,10 @@ +{ + "536TeV_MB_pythia": { + "111_pt": "56.6336*x*pow(1+(sqrt(x*x+0.138918*0.138918)-0.138918)/(6.8304*0.139501),-6.8304)", + "221_pt": "1939.44*x*pow(1+(sqrt(x*x+-0.424653*-0.424653)--0.424653)/(6.84504*0.0745758),-6.84504)", + "331_pt": "2.89402*x*pow(1+(sqrt(x*x+-0.322689*-0.322689)--0.322689)/(8.32826*0.211736),-8.32826)", + "113_pt": "75.4035*x*pow(1+(sqrt(x*x+-0.360389*-0.360389)--0.360389)/(7.74615*0.16301),-7.74615)", + "223_pt": "2.29*x*pow(1+(sqrt(x*x+0.405007*0.405007)-0.405007)/(7.61366*0.243978),-7.61366)", + "333_pt": "0.646087*x*pow(1+(sqrt(x*x+-0.257169*-0.257169)--0.257169)/(8.17199*0.261382),-8.17199)" + } +} \ No newline at end of file From 248c287e3ae57d66ef8cf09d9146ad84991eb9cc Mon Sep 17 00:00:00 2001 From: sgaretti <129837066+sgaretti@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:35:29 +0200 Subject: [PATCH 083/362] Update Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini (#2130) * Update pythia8_hi.cfg * Update Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini * Update pythia8_hi.cfg Revert changes to pythia8_hi.cfg --- ...nerator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini index a7415ccf8..c007f85a6 100644 --- a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini @@ -4,4 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_py funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,7) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg \ No newline at end of file +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hi.cfg From bcb042c25ac5d04ab1c395f82a210f82e2c58df8 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 25 Sep 2025 09:44:59 +0200 Subject: [PATCH 084/362] fix compile error in PWGDQ/GeneratorPromptCharmonia.C --- MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index 141211d58..bfca9acca 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -348,7 +348,7 @@ class O2_GeneratorParamJpsiMidY_96TeV : public GeneratorTGenerator // JPSi pt extrapolated at 9.6 TeV: https: // https://www.hepdata.net/record/ins1899703 (2108.02523) // const Double_t kC = 1.48862; - const Double_t kpt0 = 4.64005 + const Double_t kpt0 = 4.64005; const Double_t kn = 3.57353; Double_t pt = px[0]; @@ -420,7 +420,7 @@ class O2_GeneratorParamPsiMidY_96TeV : public GeneratorTGenerator // // const Double_t kC = 1.48862; - const Double_t kpt0 = 4.64005 + const Double_t kpt0 = 4.64005; const Double_t kn = 3.57353; Double_t pt = px[0]; From 3742aa688485a2fad976714f9af7dcb5dd205267 Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Wed, 24 Sep 2025 10:28:11 +0200 Subject: [PATCH 085/362] Add Dzero meson in QC --- .../json/analyses_config.json | 22 + ...-analysis-hf-candidate-creator-2prong.json | 96 ++ .../o2-analysis-hf-candidate-selector-d0.json | 706 ++++++++++++++ .../json/dpl/o2-analysis-hf-task-d0.json | 161 ++++ ...-analysis-hf-track-index-skim-creator.json | 895 ++++++++++++++++++ ...nalysis-track-to-collision-associator.json | 13 + 6 files changed, 1893 insertions(+) create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-selector-d0.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-hf-task-d0.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-track-to-collision-associator.json diff --git a/MC/config/analysis_testing/json/analyses_config.json b/MC/config/analysis_testing/json/analyses_config.json index fc03de9eb..aae4212da 100644 --- a/MC/config/analysis_testing/json/analyses_config.json +++ b/MC/config/analysis_testing/json/analyses_config.json @@ -170,6 +170,28 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, + "tasks": ["o2-analysis-hf-task-d0", + "o2-analysis-hf-candidate-selector-d0", + "o2-analysis-hf-candidate-creator-2prong", + "o2-analysis-hf-track-index-skim-creator", + "o2-analysis-track-to-collision-associator", + "o2-analysis-hf-pid-creator", + "o2-analysis-trackselection", + "o2-analysis-multiplicity-table", + "o2-analysis-event-selection", + "o2-analysis-track-propagation", + "o2-analysis-pid-tpc", + "o2-analysis-pid-tpc-base", + "o2-analysis-pid-tof-full", + "o2-analysis-pid-tof-base", + "o2-analysis-ft0-corrected-table"] + }, + { + "name": "HFDzeroQA", + "enabled": true, + "expected_output": ["AnalysisResults.root"], + "valid_mc": true, + "valid_data": true, "tasks": ["o2-analysis-timestamp", "o2-analysis-track-propagation", "o2-analysis-trackselection", diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json new file mode 100644 index 000000000..b49600077 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json @@ -0,0 +1,96 @@ +{ + "hf-candidate-creator-2prong": { + "constrainKfToPv": "false", + "propagateToPCA": "true", + "useAbsDCA": "false", + "useWeightedFinalPCA": "false", + "maxR": "200", + "maxDZIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "fillHistograms": "true", + "isRun2": "false", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "hfEvSel": { + "centralityMin": "0", + "centralityMax": "100", + "useSel8Trigger": "true", + "triggerClass": "-1", + "useTvxTrigger": "false", + "useTimeFrameBorderCut": "false", + "useItsRofBorderCut": "false", + "useIsGoodZvtxFT0vsPV": "true", + "useNoSameBunchPileup": "true", + "useOccupancyCut": "false", + "occEstimator": "1", + "occupancyMin": "0", + "occupancyMax": "1000000", + "nPvContributorsMin": "0", + "chi2PvMax": "-1", + "zPvPosMin": "-10", + "zPvPosMax": "10", + "useNoCollInTimeRangeNarrow": "false", + "useNoCollInTimeRangeStandard": "false", + "useNoCollInRofStandard": "false", + "softwareTrigger": "", + "bcMarginForSoftwareTrigger": "100", + "ccdbPathSoftwareTrigger": "Users\/m\/mpuccio\/EventFiltering\/OTS\/", + "th2ConfigAxisCent": { + "values": [ + "100", + "0", + "100" + ] + }, + "th2ConfigAxisOccupancy": { + "values": [ + "24", + "0", + "24000" + ] + }, + "requireGoodRct": "true", + "rctLabel": "CBT_hadronPID", + "rctCheckZDC": "false", + "rctTreatLimitedAcceptanceAsBad": "false" + }, + "axisMass": { + "values": [ + "500", + "1.6", + "2.1" + ] + }, + "processPvRefitWithDCAFitterN": "false", + "processNoPvRefitWithDCAFitterN": "false", + "processPvRefitWithKFParticle": "false", + "processNoPvRefitWithKFParticle": "false", + "processPvRefitWithDCAFitterNCentFT0C": "false", + "processNoPvRefitWithDCAFitterNCentFT0C": "true", + "processPvRefitWithKFParticleCentFT0C": "false", + "processNoPvRefitWithKFParticleCentFT0C": "false", + "processPvRefitWithDCAFitterNCentFT0M": "false", + "processNoPvRefitWithDCAFitterNCentFT0M": "false", + "processPvRefitWithKFParticleCentFT0M": "false", + "processNoPvRefitWithKFParticleCentFT0M": "false", + "processPvRefitWithDCAFitterNUpc": "false", + "processNoPvRefitWithDCAFitterNUpc": "false", + "processPvRefitWithKFParticleUpc": "false", + "processNoPvRefitWithKFParticleUpc": "false", + "processCollisions": "false", + "processCollisionsCentFT0C": "true", + "processCollisionsCentFT0M": "false", + "processCollisionsUpc": "false" + }, + "hf-candidate-creator-2prong-expressions": { + "rejectBackground": "false", + "matchKinkedDecayTopology": "false", + "matchInteractionsWithMaterial": "false", + "matchCorrelatedBackground": "false", + "processMc": "false", + "processMcCentFT0C": "false", + "processMcCentFT0M": "false" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-selector-d0.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-selector-d0.json new file mode 100644 index 000000000..008b1676c --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-selector-d0.json @@ -0,0 +1,706 @@ +{ + "hf-candidate-selector-d0": { + "ptCandMin": "0", + "ptCandMax": "50", + "usePid": "true", + "ptPidTpcMin": "0.40000000000000002", + "ptPidTpcMax": "50", + "nSigmaTpcMax": "3", + "nSigmaTpcCombinedMax": "3", + "usePidTpcOnly": "false", + "ptPidTofMin": "0.40000000000000002", + "ptPidTofMax": "50", + "nSigmaTofMax": "3", + "nSigmaTofCombinedMax": "3", + "usePidTpcAndTof": "true", + "itsNClustersFoundMin": "0", + "itsChi2PerClusterMax": "1e+10", + "tpcNClustersFoundMin": "70", + "tpcNCrossedRowsMin": "80", + "tpcNCrossedRowsOverFindableClustersMin": "0.800000012", + "tpcChi2PerClusterMax": "1e+10", + "keepOnlySidebandCandidates": "false", + "distanceFromD0MassForSidebands": "0.14999999999999999", + "binsPt": { + "values": [ + "0", + "1", + "2", + "3", + "4", + "6", + "8", + "12", + "24", + "50", + "100" + ] + }, + "cuts": { + "labels_rows": [ + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9", + "pT bin 10", + "pT bin 11", + "pT bin 12", + "pT bin 13", + "pT bin 14", + "pT bin 15", + "pT bin 16", + "pT bin 17", + "pT bin 18", + "pT bin 19", + "pT bin 20", + "pT bin 21", + "pT bin 22", + "pT bin 23", + "pT bin 24" + ], + "labels_cols": [ + "m", + "DCA", + "cos theta*", + "pT K", + "pT Pi", + "d0K", + "d0pi", + "d0d0", + "cos pointing angle", + "cos pointing angle xy", + "min norm decay length XY", + "max decay length", + "max decay length XY", + "min decay length", + "norm dauImpPar XY" + ], + "values": [ + [ + "0.20000000000000001", + "0.040000000000000001", + "0.80000000000000004", + "0.5", + "0.5", + "1", + "1", + "1", + "0.97999999999999998", + "0.98499999999999999", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.040000000000000001", + "0.80000000000000004", + "0.5", + "0.5", + "1", + "1", + "1", + "0.98999999999999999", + "0.995", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.5", + "0.5", + "1", + "1", + "1", + "0.97999999999999998", + "0.98499999999999999", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.59999999999999998", + "0.59999999999999998", + "1", + "1", + "1", + "0.96999999999999997", + "0.97499999999999998", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.59999999999999998", + "0.59999999999999998", + "1", + "1", + "1", + "0.95999999999999996", + "0.96499999999999997", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.59999999999999998", + "0.59999999999999998", + "1", + "1", + "1", + "0.94999999999999996", + "0.95499999999999996", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.93999999999999995", + "0.94499999999999995", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.92000000000000004", + "0.92500000000000004", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.91000000000000003", + "0.91500000000000004", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.90000000000000002", + "0.90500000000000003", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "1", + "1", + "1", + "0.90000000000000002", + "0.90000000000000002", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "1", + "1", + "1", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "1", + "1", + "1", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.035000000000000003", + "1", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "0", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "0", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "0", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "-5.0000000000000002e-05", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "-5.0000000000000002e-05", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "-5.0000000000000002e-05", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0001", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.035000000000000003", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.035000000000000003", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.030000000000000002", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.030000000000000002", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.030000000000000002", + "1", + "0.59999999999999998", + "0.59999999999999998", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ] + ] + }, + "applyMl": "true", + "binsPtMl": { + "values": [ + "0", + "1", + "2", + "3", + "4", + "6", + "8", + "12", + "24", + "50", + "100" + ] + }, + "cutDirMl": { + "values": [ + "0", + "1", + "1" + ] + }, + "cutsMl": { + "labels_rows": [ + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9", + "pT bin 10", + "pT bin 11" + ], + "labels_cols": [ + "score class 1", + "score class 2", + "score class 3" + ], + "values": [ + [ + "0.0025", + "0", + "0" + ], + [ + "0.005", + "0", + "0" + ], + [ + "0.006", + "0", + "0" + ], + [ + "0.008", + "0", + "0" + ], + [ + "0.01", + "0", + "0" + ], + [ + "0.1", + "0", + "0" + ], + [ + "0.2", + "0", + "0" + ], + [ + "0.4", + "0", + "0" + ], + [ + "1", + "0", + "0" + ], + [ + "1", + "0", + "0" + ], + [ + "1", + "0", + "0" + ], + [ + "1", + "0", + "0" + ] + ] + }, + "nClassesMl": "3", + "enableDebugMl": "true", + "namesInputFeatures": { + "values": [ + "impactParameterXY0", + "impactParameterXY1", + "chi2PCA", + "cpa", + "cpaXY", + "decayLengthXY", + "decayLength", + "impactParameterProduct", + "nSigTpcTofPiExpPi", + "nSigTpcTofKaExpKa", + "nSigTpcPiExpPi", + "nSigTpcKaExpPi", + "nSigTpcTofKaExpPi", + "nSigTpcPiExpKa", + "nSigTpcKaExpKa", + "nSigTpcTofPiExpKa" + ] + }, + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "modelPathsCCDB": { + "values": [ + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt0_1", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt1_2", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt2_3", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt3_4", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt4_6", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt6_8", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt8_12", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt12_24", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt24_50", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt24_50" + ] + }, + "onnxFileNames": { + "values": [ + "ModelHandler_pT_0_1.onnx", + "ModelHandler_pT_1_2.onnx", + "ModelHandler_pT_2_3.onnx", + "ModelHandler_pT_3_4.onnx", + "ModelHandler_pT_4_6.onnx", + "ModelHandler_pT_6_8.onnx", + "ModelHandler_pT_8_12.onnx", + "ModelHandler_pT_12_24.onnx", + "ModelHandler_pT_24_50.onnx", + "ModelHandler_pT_24_50.onnx" + ] + }, + "timestampCCDB": "-1", + "loadModelsFromCCDB": "true", + "useTriggerMassCut": "false", + "hfTrigger2ProngCuts": { + "nSigmaMax": "2", + "ptDeltaMassMax": "10", + "ptMassCutMax": "9999", + "deltaMassPars": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear" + ], + "values": [ + [ + "-0.00249999994", + "9.99999975e-05" + ] + ] + }, + "sigmaPars": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear" + ], + "values": [ + [ + "0.0142400004", + "0.00178000005" + ] + ] + } + }, + "processWithDCAFitterN": "true", + "processWithKFParticle": "false" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-task-d0.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-task-d0.json new file mode 100644 index 000000000..ae1a0be18 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-task-d0.json @@ -0,0 +1,161 @@ +{ + "hf-task-d0": { + "selectionFlagD0": "1", + "selectionFlagD0bar": "1", + "yCandGenMax": "0.5", + "yCandRecoMax": "0.80000000000000004", + "selectionFlagHf": "1", + "selectionTopol": "1", + "selectionCand": "1", + "selectionPid": "1", + "binsPt": { + "values": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "10", + "12", + "16", + "24", + "36", + "50" + ] + }, + "centEstimator": "2", + "occEstimator": "1", + "storeCentrality": "true", + "storeOccupancy": "true", + "storeTrackQuality": "false", + "applyMl": "true", + "thnConfigAxisBkgScore": { + "values": [ + "5000", + "0", + "0.5" + ] + }, + "thnConfigAxisNonPromptScore": { + "values": [ + "100", + "0", + "1" + ] + }, + "thnConfigAxisPromptScore": { + "values": [ + "100", + "0", + "1" + ] + }, + "thnConfigAxisMass": { + "values": [ + "120", + "1.5848", + "2.1848" + ] + }, + "thnConfigAxisPtB": { + "values": [ + "1000", + "0", + "100" + ] + }, + "thnConfigAxisPt": { + "values": [ + "500", + "0", + "50" + ] + }, + "thnConfigAxisY": { + "values": [ + "20", + "-1", + "1" + ] + }, + "thnConfigAxisOrigin": { + "values": [ + "3", + "-0.5", + "2.5" + ] + }, + "thnConfigAxisCandType": { + "values": [ + "6", + "-0.5", + "5.5" + ] + }, + "thnConfigAxisGenPtD": { + "values": [ + "500", + "0", + "50" + ] + }, + "thnConfigAxisGenPtB": { + "values": [ + "1000", + "0", + "100" + ] + }, + "thnConfigAxisNumPvContr": { + "values": [ + "800", + "-0.5", + "7999.5" + ] + }, + "thnConfigAxisCent": { + "values": [ + "110", + "0", + "110" + ] + }, + "thnConfigAxisOccupancy": { + "values": [ + "24", + "0", + "24000" + ] + }, + "thnConfigAxisMinItsNCls": { + "values": [ + "5", + "3", + "8" + ] + }, + "thnConfigAxisMinTpcNCrossedRows": { + "values": [ + "10", + "70", + "180" + ] + }, + "processDataWithDCAFitterN": "false", + "processDataWithDCAFitterNCent": "false", + "processDataWithKFParticle": "false", + "processDataWithDCAFitterNMl": "false", + "processDataWithDCAFitterNMlCent": "true", + "processDataWithKFParticleMl": "false", + "processMcWithDCAFitterN": "false", + "processMcWithDCAFitterNCent": "false", + "processMcWithKFParticle": "false", + "processMcWithDCAFitterNMl": "false", + "processMcWithDCAFitterNMlCent": "false", + "processMcWithKFParticleMl": "false" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json new file mode 100644 index 000000000..9bfa2f5d9 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json @@ -0,0 +1,895 @@ +{ + "hf-track-index-skim-creator-tag-sel-collisions": { + "fillHistograms": "true", + "triggerClassName": "", + "hfEvSel": { + "centralityMin": "0", + "centralityMax": "100", + "useSel8Trigger": "true", + "triggerClass": "-1", + "useTvxTrigger": "false", + "useTimeFrameBorderCut": "false", + "useItsRofBorderCut": "false", + "useIsGoodZvtxFT0vsPV": "false", + "useNoSameBunchPileup": "false", + "useOccupancyCut": "false", + "occEstimator": "1", + "occupancyMin": "0", + "occupancyMax": "1000000", + "nPvContributorsMin": "0", + "chi2PvMax": "-1", + "zPvPosMin": "-10", + "zPvPosMax": "10", + "useNoCollInTimeRangeNarrow": "false", + "useNoCollInTimeRangeStandard": "false", + "useNoCollInRofStandard": "false", + "softwareTrigger": "", + "bcMarginForSoftwareTrigger": "100", + "ccdbPathSoftwareTrigger": "Users\/m\/mpuccio\/EventFiltering\/OTS\/Chunked\/", + "th2ConfigAxisCent": { + "values": [ + "100", + "0", + "100" + ] + }, + "th2ConfigAxisOccupancy": { + "values": [ + "14", + "0", + "14000" + ] + }, + "requireGoodRct": "false", + "rctLabel": "CBT_hadronPID", + "rctCheckZDC": "false", + "rctTreatLimitedAcceptanceAsBad": "false" + }, + "processTrigAndCentFT0ASel": "false", + "processTrigAndCentFT0CSel": "true", + "processTrigAndCentFT0MSel": "false", + "processTrigAndCentFV0ASel": "false", + "processTrigSel": "false", + "processNoTrigSel": "false", + "processUpcSel": "false" + }, + "hf-pid-creator": { + "processDummy": "false", + "processFullEl": "false", + "processTinyEl": "false", + "processFullMu": "false", + "processTinyMu": "false", + "processFullPi": "true", + "processTinyPi": "false", + "processFullKa": "true", + "processTinyKa": "false", + "processFullPr": "false", + "processTinyPr": "false" + }, + "hf-track-index-skim-creator-tag-sel-tracks": { + "isRun2": "false", + "doPvRefit": "false", + "fillHistograms": "true", + "debugPvRefit": "false", + "doCutQuality": "true", + "useIsGlobalTrack": "false", + "useIsGlobalTrackWoDCA": "true", + "tpcNClsFoundMin": "70", + "binsPtTrack": { + "values": [ + "0", + "0.5", + "1", + "1.5", + "2", + "3", + "1000" + ] + }, + "ptMinTrack2Prong": "0.40000000000000002", + "cutsTrack2Prong": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrack2Prong": "-0.80000000000000004", + "etaMaxTrack2Prong": "0.80000000000000004", + "ptMinTrack3Prong": "0.59999999999999998", + "cutsTrack3Prong": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrack3Prong": "-0.80000000000000004", + "etaMaxTrack3Prong": "0.80000000000000004", + "ptMinTrackBach": "0", + "cutsTrackBach": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrackBach": "-0.80000000000000004", + "etaMaxTrackBach": "0.80000000000000004", + "ptMinTrackBachLfCasc": "0.10000000000000001", + "cutsTrackBachLfCasc": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrackBachLfCasc": "-99999", + "etaMaxTrackBachLfCasc": "1.1000000000000001", + "useIsGlobalTrackForBachLfCasc": "false", + "useIsGlobalTrackWoDCAForBachLfCasc": "false", + "useIsQualityTrackITSForBachLfCasc": "true", + "ptMinSoftPionForDstar": "0.10000000000000001", + "etaMinSoftPionForDstar": "-0.80000000000000004", + "etaMaxSoftPionForDstar": "0.80000000000000004", + "cutsTrackDstar": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ] + ] + }, + "useIsGlobalTrackForSoftPion": "false", + "useIsGlobalTrackWoDCAForSoftPion": "true", + "useIsQualityTrackITSForSoftPion": "false", + "selectionsPid": { + "labels_rows": [ + "ProtonInLcToPKPi", + "ProtonInXicToPKPi", + "ProtonInLcToPK0S", + "KaonIn3Prongs" + ], + "labels_cols": [ + "minPtTpc", + "maxPtTpc", + "nSigmaMaxTpc", + "minPtTof", + "maxPtTof", + "nSigmaMaxTof" + ], + "values": [ + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ], + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ], + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ], + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ] + ] + }, + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "axisPvRefitDeltaX": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaY": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaZ": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "processNoPid": "false", + "processProtonPidTpc": "true", + "processProtonPidTof": "false", + "processProtonPidTpcOrTof": "false", + "processProtonPidTpcAndTof": "false" + }, + "hf-track-index-skim-creator": { + "isRun2": "false", + "do3Prong": "true", + "doDstar": "true", + "debug": "false", + "debugPvRefit": "false", + "fillHistograms": "true", + "ptTolerance": "0.10000000000000001", + "minTwoTrackDecayLengthFor3Prongs": "0.01", + "maxTwoTrackChi2PcaFor3Prongs": "10000000000", + "propagateToPCA": "true", + "useAbsDCA": "false", + "useWeightedFinalPCA": "false", + "maxR": "200", + "maxDZIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "binsPtD0ToPiK": { + "values": [ + "0", + "5", + "1000" + ] + }, + "cutsD0ToPiK": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "d0d0" + ], + "values": [ + [ + "1.6499999999999999", + "2.1000000000000001", + "0.90000000000000002", + "0" + ], + [ + "1.6499999999999999", + "2.25", + "0.90000000000000002", + "0" + ] + ] + }, + "binsPtJpsiToEE": { + "values": [ + "0", + "5", + "1000" + ] + }, + "cutsJpsiToEE": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "d0d0" + ], + "values": [ + [ + "0", + "0", + "2", + "0" + ], + [ + "0", + "0", + "2", + "0" + ] + ] + }, + "binsPtJpsiToMuMu": { + "values": [ + "0", + "5", + "1000" + ] + }, + "cutsJpsiToMuMu": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "d0d0" + ], + "values": [ + [ + "0", + "0", + "2", + "0" + ], + [ + "0", + "0", + "2", + "0" + ] + ] + }, + "binsPtDplusToPiKPi": { + "values": [ + "1", + "5", + "1000" + ] + }, + "cutsDplusToPiKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL" + ], + "values": [ + [ + "1.7", + "2.0499999999999998", + "0.95999999999999996", + "0.050000000000000003" + ], + [ + "1.6499999999999999", + "2.2000000000000002", + "0.94999999999999996", + "0.050000000000000003" + ] + ] + }, + "binsPtDsToKKPi": { + "values": [ + "1", + "5", + "1000" + ] + }, + "cutsDsToKKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL", + "deltaMassKK" + ], + "values": [ + [ + "1.7", + "2.1499999999999999", + "0.93999999999999995", + "0.02", + "0.02" + ], + [ + "1.6499999999999999", + "2.25", + "0.92000000000000004", + "0.02", + "0.02" + ] + ] + }, + "binsPtLcToPKPi": { + "values": [ + "2", + "8", + "1000" + ] + }, + "cutsLcToPKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL" + ], + "values": [ + [ + "2.1000000000000001", + "2.5", + "0.92000000000000004", + "0.01" + ], + [ + "2", + "2.6000000000000001", + "0.90000000000000002", + "0.02" + ] + ] + }, + "binsPtXicToPKPi": { + "values": [ + "2", + "8", + "1000" + ] + }, + "cutsXicToPKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL" + ], + "values": [ + [ + "2.1000000000000001", + "2.6499999999999999", + "0.93999999999999995", + "0.02" + ], + [ + "2", + "2.7000000000000002", + "0.92000000000000004", + "0.02" + ] + ] + }, + "binsPtDstarToD0Pi": { + "values": [ + "2", + "5", + "1000" + ] + }, + "cutsDstarToD0Pi": { + "labels_rows": "", + "labels_cols": [ + "deltaMassMax", + "deltaMassD0" + ], + "values": [ + [ + "0.17000000000000001", + "0.070000000000000007" + ], + [ + "0.17000000000000001", + "0.10000000000000001" + ] + ] + }, + "applyProtonPidForLcToPKPi": "true", + "applyProtonPidForXicToPKPi": "true", + "applyKaonPidIn3Prongs": "true", + "applyMlForHfFilters": "false", + "mlModelPathCCDB": "EventFiltering\/PWGHF\/BDTSmeared", + "timestampCcdbForHfFilters": "1657032422771", + "loadMlModelsFromCCDB": "true", + "onnxFileNames": { + "labels_rows": [ + "D0", + "Dplus", + "Lc", + "Ds", + "Xic" + ], + "labels_cols": [ + "Model path" + ], + "values": [ + [ + "ModelHandler_onnx_D0ToKPi.onnx" + ], + [ + "ModelHandler_onnx_DplusToPiKPi.onnx" + ], + [ + "ModelHandler_onnx_LcToPKPi.onnx" + ], + [ + "ModelHandler_onnx_DsToKKPi.onnx" + ], + [ + "" + ] + ] + }, + "thresholdMlScoreD0ToKPi": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreDplusToPiKPi": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreDsToPiKK": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreLcToPiKP": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreXicToPiKP": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "axisPvRefitDeltaX": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaY": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaZ": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "processNo2And3Prongs": "false", + "process2And3ProngsWithPvRefit": "false", + "process2And3ProngsNoPvRefit": "true", + "process2And3ProngsWithPvRefitWithPidForHfFiltersBdt": "false", + "process2And3ProngsNoPvRefitWithPidForHfFiltersBdt": "false" + }, + "hf-track-index-skim-creator-lf-cascades": { + "fillHistograms": "true", + "do3Prong": "true", + "rejDiffCollTrack": "true", + "ptTolerance": "0.10000000000000001", + "massXiPiMin": "2.1000000000000001", + "massXiPiMax": "3", + "massOmegaCharmBachelorMin": "2.3999999999999999", + "massOmegaCharmBachelorMax": "3", + "massXiPiPiMin": "2.1000000000000001", + "massXiPiPiMax": "2.7999999999999998", + "propagateToPCA": "true", + "useAbsDCA": "true", + "useWeightedFinalPCA": "true", + "maxR": "200", + "maxDZIni": "4", + "maxDXYIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "maxChi2": "100", + "refitWithMatCorr": "true", + "ptMinOmegacZeroToOmegaPiLfCasc": "0", + "ptMinOmegaczeroToOmegaKaLfCasc": "0", + "ptMinXicZeroOmegacZeroToXiPiLfCasc": "0", + "ptMinXicplusLfCasc": "0", + "v0TransvRadius": "1", + "cascTransvRadius": "0.400000006", + "decayLengthXicMin": "-1", + "dcaBachToPv": "0.0500000007", + "dcaV0ToPv": "0.0500000007", + "v0CosPA": "0.94999999999999996", + "cascCosPA": "0.94999999999999996", + "xicCosPA": "0.94999999999999996", + "dcaV0Dau": "2", + "dcaCascDau": "1", + "dcaNegToPv": "0.0500000007", + "dcaPosToPv": "0.0500000007", + "v0MassWindow": "0.00800000038", + "cascadeMassWindow": "0.00999999978", + "isRun2": "false", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "processNoLfCascades": "true", + "processLfCascades": "false" + }, + "hf-track-index-skim-creator-cascades": { + "isRun2": "false", + "fillHistograms": "true", + "useDCAFitter": "true", + "propagateToPCA": "true", + "maxR": "200", + "maxDZIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "useAbsDCA": "true", + "useWeightedFinalPCA": "true", + "etaMinV0Daugh": "-99999", + "etaMaxV0Daugh": "1.1000000000000001", + "ptMinV0Daugh": "0.050000000000000003", + "cpaV0Min": "0.995", + "cutInvMassV0": "0.050000000000000003", + "ptCascCandMin": "-1", + "cutInvMassCascLc": "1", + "applyProtonPid": "false", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "processNoCascades": "true", + "processCascades": "false" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-track-to-collision-associator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-track-to-collision-associator.json new file mode 100644 index 000000000..5a796328a --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-track-to-collision-associator.json @@ -0,0 +1,13 @@ +{ + "track-to-collision-association": { + "nSigmaForTimeCompat": "4", + "timeMargin": "500", + "setTrackSelections": "1", + "usePVAssociation": "true", + "includeUnassigned": "true", + "fillTableOfCollIdsPerTrack": "false", + "bcWindowForOneSigma": "60", + "processAssocWithTime": "true", + "processStandardAssoc": "false" + } +} From 1df608916e67b180bec82b35bc924e9ab6112fee Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Wed, 24 Sep 2025 10:32:58 +0200 Subject: [PATCH 086/362] Fix typo --- .../json/analyses_config.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/MC/config/analysis_testing/json/analyses_config.json b/MC/config/analysis_testing/json/analyses_config.json index aae4212da..26d4e743a 100644 --- a/MC/config/analysis_testing/json/analyses_config.json +++ b/MC/config/analysis_testing/json/analyses_config.json @@ -170,6 +170,20 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, + "tasks": ["o2-analysis-timestamp", + "o2-analysis-track-propagation", + "o2-analysis-trackselection", + "o2-analysis-event-selection", + "o2-analysis-multiplicity-table", + "o2-analysis-ft0-corrected-table", + "o2-analysis-ft0-qa"] + }, + { + "name": "HFDzeroQA", + "enabled": true, + "expected_output": ["AnalysisResults.root"], + "valid_mc": true, + "valid_data": true, "tasks": ["o2-analysis-hf-task-d0", "o2-analysis-hf-candidate-selector-d0", "o2-analysis-hf-candidate-creator-2prong", @@ -185,20 +199,6 @@ "o2-analysis-pid-tof-full", "o2-analysis-pid-tof-base", "o2-analysis-ft0-corrected-table"] - }, - { - "name": "HFDzeroQA", - "enabled": true, - "expected_output": ["AnalysisResults.root"], - "valid_mc": true, - "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", - "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", - "o2-analysis-ft0-corrected-table", - "o2-analysis-ft0-qa"] } ] } From 05d33f6b391ede850216b2c25b90df93d0d9734e Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Wed, 24 Sep 2025 10:59:57 +0200 Subject: [PATCH 087/362] Add missing configuration --- .../json/dpl/o2-analysis-hf-pid-creator.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-hf-pid-creator.json diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-pid-creator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-pid-creator.json new file mode 100644 index 000000000..dfb171a57 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-pid-creator.json @@ -0,0 +1,15 @@ +{ + "hf-pid-creator": { + "processDummy": "false", + "processFullEl": "false", + "processTinyEl": "false", + "processFullMu": "false", + "processTinyMu": "false", + "processFullPi": "true", + "processTinyPi": "false", + "processFullKa": "true", + "processTinyKa": "false", + "processFullPr": "false", + "processTinyPr": "false" + } +} \ No newline at end of file From 2872bb436b339b0ded8e39cc2878fa07f319a3e7 Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Wed, 24 Sep 2025 17:11:48 +0200 Subject: [PATCH 088/362] Add missing dependency --- MC/config/analysis_testing/json/analyses_config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/MC/config/analysis_testing/json/analyses_config.json b/MC/config/analysis_testing/json/analyses_config.json index 26d4e743a..3858b107a 100644 --- a/MC/config/analysis_testing/json/analyses_config.json +++ b/MC/config/analysis_testing/json/analyses_config.json @@ -194,6 +194,7 @@ "o2-analysis-multiplicity-table", "o2-analysis-event-selection", "o2-analysis-track-propagation", + "o2-analysis-timestamp", "o2-analysis-pid-tpc", "o2-analysis-pid-tpc-base", "o2-analysis-pid-tof-full", From f8f369a91cc6cc05fd1052558dfac111fec037ff Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Wed, 24 Sep 2025 22:10:13 +0200 Subject: [PATCH 089/362] Add dependence to centrality task --- .../json/analyses_config.json | 1 + .../dpl/o2-analysis-centrality-table.json | 460 ++++++++++++++++++ 2 files changed, 461 insertions(+) create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-centrality-table.json diff --git a/MC/config/analysis_testing/json/analyses_config.json b/MC/config/analysis_testing/json/analyses_config.json index 3858b107a..c06fbb864 100644 --- a/MC/config/analysis_testing/json/analyses_config.json +++ b/MC/config/analysis_testing/json/analyses_config.json @@ -192,6 +192,7 @@ "o2-analysis-hf-pid-creator", "o2-analysis-trackselection", "o2-analysis-multiplicity-table", + "o2-analysis-centrality-table", "o2-analysis-event-selection", "o2-analysis-track-propagation", "o2-analysis-timestamp", diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-centrality-table.json b/MC/config/analysis_testing/json/dpl/o2-analysis-centrality-table.json new file mode 100644 index 000000000..dd342777e --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-centrality-table.json @@ -0,0 +1,460 @@ +{ + "centrality-table": { + "processRun2": "false", + "processRun3": "true", + "processRun3Complete": "false", + "processRun3FT0": "false", + "embedINELgtZEROselection": "false", + "produceHistograms": "0", + "ccdbUrl": "http://alice-ccdb.cern.ch", + "ccdbPath": "Centrality/Estimators", + "genName": "", + "doNotCrashOnNull": "1", + "reconstructionPass": "", + "binsPercentile": { + "values": [ + 0, + 0, + 0.001, + 0.002, + 0.003, + 0.004, + 0.005, + 0.006, + 0.007, + 0.008, + 0.009, + 0.01, + 0.011, + 0.012, + 0.013, + 0.014, + 0.015, + 0.016, + 0.017, + 0.018, + 0.019, + 0.02, + 0.021, + 0.022, + 0.023, + 0.024, + 0.025, + 0.026, + 0.027, + 0.028, + 0.029, + 0.03, + 0.031, + 0.032, + 0.033, + 0.034, + 0.035, + 0.036, + 0.037, + 0.038, + 0.039, + 0.04, + 0.041, + 0.042, + 0.043, + 0.044, + 0.045, + 0.046, + 0.047, + 0.048, + 0.049, + 0.05, + 0.051, + 0.052, + 0.053, + 0.054, + 0.055, + 0.056, + 0.057, + 0.058, + 0.059, + 0.06, + 0.061, + 0.062, + 0.063, + 0.064, + 0.065, + 0.066, + 0.067, + 0.068, + 0.069, + 0.07, + 0.071, + 0.072, + 0.073, + 0.074, + 0.075, + 0.076, + 0.077, + 0.078, + 0.079, + 0.08, + 0.081, + 0.082, + 0.083, + 0.084, + 0.085, + 0.086, + 0.087, + 0.088, + 0.089, + 0.09, + 0.091, + 0.092, + 0.093, + 0.094, + 0.095, + 0.096, + 0.097, + 0.098, + 0.099, + 0.1, + 0.11, + 0.12, + 0.13, + 0.14, + 0.15, + 0.16, + 0.17, + 0.18, + 0.19, + 0.2, + 0.21, + 0.22, + 0.23, + 0.24, + 0.25, + 0.26, + 0.27, + 0.28, + 0.29, + 0.3, + 0.31, + 0.32, + 0.33, + 0.34, + 0.35, + 0.36, + 0.37, + 0.38, + 0.39, + 0.4, + 0.41, + 0.42, + 0.43, + 0.44, + 0.45, + 0.46, + 0.47, + 0.48, + 0.49, + 0.5, + 0.51, + 0.52, + 0.53, + 0.54, + 0.55, + 0.56, + 0.57, + 0.58, + 0.59, + 0.6, + 0.61, + 0.62, + 0.63, + 0.64, + 0.65, + 0.66, + 0.67, + 0.68, + 0.69, + 0.7, + 0.71, + 0.72, + 0.73, + 0.74, + 0.75, + 0.76, + 0.77, + 0.78, + 0.79, + 0.8, + 0.81, + 0.82, + 0.83, + 0.84, + 0.85, + 0.86, + 0.87, + 0.88, + 0.89, + 0.9, + 0.91, + 0.92, + 0.93, + 0.94, + 0.95, + 0.96, + 0.97, + 0.98, + 0.99, + 1, + 1.1, + 1.2, + 1.3, + 1.4, + 1.5, + 1.6, + 1.7, + 1.8, + 1.9, + 2, + 2.1, + 2.2, + 2.3, + 2.4, + 2.5, + 2.6, + 2.7, + 2.8, + 2.9, + 3, + 3.1, + 3.2, + 3.3, + 3.4, + 3.5, + 3.6, + 3.7, + 3.8, + 3.9, + 4, + 4.1, + 4.2, + 4.3, + 4.4, + 4.5, + 4.6, + 4.7, + 4.8, + 4.9, + 5, + 5.1, + 5.2, + 5.3, + 5.4, + 5.5, + 5.6, + 5.7, + 5.8, + 5.9, + 6, + 6.1, + 6.2, + 6.3, + 6.4, + 6.5, + 6.6, + 6.7, + 6.8, + 6.9, + 7, + 7.1, + 7.2, + 7.3, + 7.4, + 7.5, + 7.6, + 7.7, + 7.8, + 7.9, + 8, + 8.1, + 8.2, + 8.3, + 8.4, + 8.5, + 8.6, + 8.7, + 8.8, + 8.9, + 9, + 9.1, + 9.2, + 9.3, + 9.4, + 9.5, + 9.6, + 9.7, + 9.8, + 9.9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 + ] + }, + "enabledTables": { + "labels_rows": [ + "CentRun2V0Ms", + "CentRun2V0As", + "CentRun2SPDTrks", + "CentRun2SPDClss", + "CentRun2CL0s", + "CentRun2CL1s", + "CentFV0As", + "CentFT0Ms", + "CentFT0As", + "CentFT0Cs", + "CentFT0CVariant1s", + "CentFDDMs", + "CentNTPVs", + "CentNGlobals", + "CentMFTs" + ], + "labels_cols": [ + "Enable" + ], + "values": [ + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ] + ] + } + } +} From f83b870847219b966319baec0d9732162c3bcde0 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 26 Sep 2025 09:06:49 +0200 Subject: [PATCH 090/362] MCProdInfo-CCDB: Possibility to force overwrite --- MC/prodinfo/mcprodinfo_ccdb_upload.py | 5 +++-- MC/prodinfo/mcprodinfo_harvester.py | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/MC/prodinfo/mcprodinfo_ccdb_upload.py b/MC/prodinfo/mcprodinfo_ccdb_upload.py index c56bf9827..4a6ed75f3 100644 --- a/MC/prodinfo/mcprodinfo_ccdb_upload.py +++ b/MC/prodinfo/mcprodinfo_ccdb_upload.py @@ -145,11 +145,12 @@ def upload_mcprodinfo_meta(base_url, user, run_number, lpm_prod_tag, keys, cert_ return response -def publish_MCProdInfo(mc_prod_info, ccdb_url = "https://alice-ccdb.cern.ch", username = "aliprod", include_meta_into_aod=False): +def publish_MCProdInfo(mc_prod_info, ccdb_url = "https://alice-ccdb.cern.ch", username = "aliprod", force_overwrite=False, include_meta_into_aod=False): print("Publishing MCProdInfo") # see if this already has meta-data uploaded, otherwise do nothing mc_prod_info_q = query_mcprodinfo(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag) - if mc_prod_info_q == None: + if mc_prod_info_q == None or force_overwrite == True: # could make this depend on hash values in future upload_mcprodinfo_meta(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag, dataclasses.asdict(mc_prod_info)) + diff --git a/MC/prodinfo/mcprodinfo_harvester.py b/MC/prodinfo/mcprodinfo_harvester.py index 40c431a25..426bdb767 100755 --- a/MC/prodinfo/mcprodinfo_harvester.py +++ b/MC/prodinfo/mcprodinfo_harvester.py @@ -132,7 +132,7 @@ def split_key(entry): return None, None, None, None -def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None): +def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None, overwrite=False): base_path = f"/alice/sim/{year}/{prod_tag}" workflow_files = alien_find(base_path, "workflow.json") @@ -184,7 +184,7 @@ def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None): if info_min.OrbitsPerTF != info_max.OrbitsPerTF: print(f"❌ OrbitsPerTF mismatch for run {run_number}") - publish_MCProdInfo(info_min, username=username, ccdb_url=ccdb_url) + publish_MCProdInfo(info_min, username=username, ccdb_url=ccdb_url, force_overwrite=overwrite) print (info_min) @@ -196,9 +196,10 @@ def main(): parser.add_argument("--ccdb", required=False, default="https://alice-ccdb.cern.ch", help="CCDB server URL") parser.add_argument("--username", required=False, help="GRID username (needs appropriate AliEn token initialized)") parser.add_argument("--year", default="2025", help="Production year (default: 2025)") + parser.add_argument("--overwrite", action="store_true", help="Overwrite existing entries") args = parser.parse_args() - process_prod_tag(args.prod_tag, year=args.year, ccdb_url=args.ccdb, username=args.username) + process_prod_tag(args.prod_tag, year=args.year, ccdb_url=args.ccdb, username=args.username, overwrite=args.overwrite) if __name__ == "__main__": main() From 93ff9d0de6a07896affbecac94244e57f2cb7495 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 25 Sep 2025 16:30:49 +0200 Subject: [PATCH 091/362] O2DPG workflow_runner: New early-file removal feature This implements a major new feature in the O2DPG workflow/pipeline runner. The runner can now auto-delete artefacts from intermediate stages as soon as these artefacts are no longer needed. For example, we can delete TPC hits, as soon as TPC digitization finishes. This allows then to operate on smaller disc spaces or to simulate more timeframes within a job. To use the feature, one needs to provide a "file-access" report with `--remove-files-early access_report.json`. This report is a "learned" structure containing the list of files that are written/consumed in a workflow and by which task. Such report needs to be generated, in a prior pilot job with the same workflow, by a user with sudo rights. See here https://github.com/AliceO2Group/O2DPG/pull/2126. This is primarily useful for productions on the GRID, and the idea would be to (a) for each new MC production, we produce the file-access file in a pilot job or github actions when releasing software (b) we then use this file to optimize the disc space in MC productions on the GRID This development is related to https://its.cern.ch/jira/browse/O2-4365 --- MC/bin/o2_dpg_workflow_runner.py | 107 +++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index 02d25588f..33c875782 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -14,6 +14,7 @@ import traceback import platform import tarfile +from copy import deepcopy try: from graphviz import Digraph havegraphviz=True @@ -65,6 +66,9 @@ parser.add_argument('--retry-on-failure', help=argparse.SUPPRESS, default=0) # number of times a failing task is retried parser.add_argument('--no-rootinit-speedup', help=argparse.SUPPRESS, action='store_true') # disable init of ROOT environment vars to speedup init/startup +parser.add_argument('--remove-files-early', type=str, default="", help="Delete intermediate files early (using the file graph information in the given file)") + + # Logging parser.add_argument('--action-logfile', help='Logfilename for action logs. If none given, pipeline_action_#PID.log will be used') parser.add_argument('--metric-logfile', help='Logfilename for metric logs. If none given, pipeline_metric_#PID.log will be used') @@ -894,6 +898,38 @@ def ok_to_submit_backfill(res, backfill_cpu_factor=1.5, backfill_mem_factor=1.5) break +def filegraph_expand_timeframes(data: dict, timeframes: set) -> dict: + """ + A utility function for the fileaccess logic. Takes a template and duplicates + for the multi-timeframe structure. + """ + tf_entries = [ + entry for entry in data.get("file_report", []) + if re.match(r"^\./tf\d+/", entry["file"]) + ] + + result = {} + for i in timeframes: + if i == -1: + continue + # Deepcopy to avoid modifying original + new_entries = deepcopy(tf_entries) + for entry in new_entries: + # Fix filepath + entry["file"] = re.sub(r"^\./tf\d+/", f"./tf{i}/", entry["file"]) + # Fix written_by and read_by (preserve prefix, change numeric suffix) + entry["written_by"] = [ + re.sub(r"_\d+$", f"_{i}", w) for w in entry["written_by"] + ] + entry["read_by"] = [ + re.sub(r"_\d+$", f"_{i}", r) for r in entry["read_by"] + ] + result[f"timeframe-{i}"] = new_entries + + return result + + + class WorkflowExecutor: # Constructor def __init__(self, workflowfile, args, jmax=100): @@ -929,6 +965,7 @@ def __init__(self, workflowfile, args, jmax=100): # construct task ID <-> task name lookup self.idtotask = [ 0 for _ in self.taskuniverse ] self.tasktoid = {} + self.idtotf = [ l['timeframe'] for l in self.workflowspec['stages'] ] for i, name in enumerate(self.taskuniverse): self.tasktoid[name]=i self.idtotask[i]=name @@ -970,6 +1007,72 @@ def __init__(self, workflowfile, args, jmax=100): # init alternative software environments self.init_alternative_software_environments() + # initialize container to keep track of file-task relationsships + self.file_removal_candidates = {} + self.do_early_file_removal = False + self.timeframeset = set([ task["timeframe"] for task in self.workflowspec['stages'] ]) + if args.remove_files_early != "": + with open(args.remove_files_early) as f: + filegraph_data = json.load(f) + self.do_early_file_removal = True + self.file_removal_candidates = filegraph_expand_timeframes(filegraph_data, self.timeframeset) + + + def perform_early_file_removal(self, taskids): + """ + This function checks which files can be deleted upon completion of task + and optionally does so. + """ + + def remove_if_exists(filepath: str) -> None: + """ + Check if a file exists, and remove it if found. + """ + if os.path.exists(filepath): + fsize = os.path.getsize(filepath) + os.remove(filepath) + actionlogger.info(f"Removing {filepath} since no longer needed. Freeing {fsize/1024.} MB.") + return True + + return False + + def remove_for_task_id(taskname, file_dict, timeframe_id, listofalltimeframes): + marked_for_removal = [] + + timeframestoscan = [ timeframe_id ] + if timeframe_id == -1: + timeframestoscan = [ i for i in listofalltimeframes if i != -1 ] + + # TODO: Note that this traversal of files is not certainly not optimal + # We should (and will) keep an mapping of tasks->potential files and just + # scan these. This is already provided by the FileIOGraph analysis tool. + for tid in timeframestoscan: + for i,file_entry in enumerate(file_dict[f"timeframe-{tid}"]): + filename = file_entry['file'] + read_by = file_entry['read_by'] + written_by = file_entry['written_by'] + if taskname in read_by: + file_entry['read_by'].remove(taskname) + if taskname in written_by: + file_entry['written_by'].remove(taskname) + + # TODO: in principle the written_by criterion might not be needed + if len(file_entry['read_by']) == 0 and len(file_entry['written_by']) == 0: + # the filename mentioned here is no longer needed and we can remove it + # make sure it is there and then delete it + if remove_if_exists(filename): + # also take out the file entry from the dict altogether + marked_for_removal.append(file_entry) + + #for k in marked_for_removal: + # file_dict[f"timeframe-{tid}"].remove(k) + + for tid in taskids: + taskname = self.idtotask[tid] + timeframe_id = self.idtotf[tid] + remove_for_task_id(taskname, self.file_removal_candidates, timeframe_id, self.timeframeset) + + def SIGHandler(self, signum, frame): """ basically forcing shut down of all child processes @@ -1737,6 +1840,10 @@ def speedup_ROOT_Init(): actionlogger.debug("finished now :" + str(finished_from_started)) finishedtasks = finishedtasks + finished + # perform file cleanup + if self.do_early_file_removal: + self.perform_early_file_removal(finished_from_started) + if self.is_productionmode: # we can do some generic cleanup of finished tasks in non-interactive/GRID mode # TODO: this can run asynchronously From 24e0cacd39ff08a556736542d34fddf8f83c37e1 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Fri, 26 Sep 2025 15:52:17 +0200 Subject: [PATCH 092/362] parse script: add env variable to use full MI100 serialization in online --- DATA/tools/parse | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DATA/tools/parse b/DATA/tools/parse index f97c1e6aa..1234f426f 100755 --- a/DATA/tools/parse +++ b/DATA/tools/parse @@ -143,6 +143,8 @@ for line in f: command_preopt += ' EPN_NODE_MI100=1 EPN_GLOBAL_SCALING="3/2"' if os.getenv('DISABLE_MI100_SERIALIZATION', '0') == '1': command_preopt += ' DISABLE_MI100_SERIALIZATION=1' + if os.getenv('FULL_MI100_SERIALIZATION', '0') == '1': + command_preopt += ' FULL_MI100_SERIALIZATION=1' if reco_num_nodes_override == 0: command_preopt += ' RECO_NUM_NODES_WORKFLOW=' + wf[1] if is_calib_workflow: From cf337d149a9c84ab56ceca6151346eca1763c5fe Mon Sep 17 00:00:00 2001 From: Chuntai <48704924+wuctlby@users.noreply.github.com> Date: Mon, 29 Sep 2025 15:54:55 +0200 Subject: [PATCH 093/362] PWGHF: fix the tests for .ini of `corr. bkg` and `ptHardBins` (#2136) * PWGHF: fix the tests for .ini of `corr. bkg` and `ptHardBins` * remove the Xic0(4132) and OmegaC(4332) from the vector `checkPdgHadron`, and correspongding decay channels --- ...ratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C | 110 ++++++++++-------- ...orHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C | 83 ++++++++++--- 2 files changed, 130 insertions(+), 63 deletions(-) diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C index ef17d7a24..4437bf04f 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C @@ -8,57 +8,66 @@ int External() { std::vector checkPdgHadron{411, 421, 431, 4122, 4232}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {411, { - {-321, 211, 211}, // K- π+ π+ (non-resonant) - {-313, 321}, // K*0(892) K+ - {-10311, 321}, // K*0(1430) K+ - {211, 333}, // φ π+ - {-321, 321, 211}, // K- K+ π+ (non-resonant) - {113, 211}, // ρ0 π+ - {225, 211}, // f2(1270) π+ - {-211, 211, 211} // π- π+ π+ (non-resonant) - }}, {421, { - {-321, 211}, // K- π+ (non-resonant) - {-321, 111, 211}, // K- π+ π0 - {213, -321}, // ρ+ K- - {-313, 111}, // antiK*0(892) π0 - {-323, 211}, // K*-(892) π+ - {-211, 211}, // π- π+ - {213, -211}, // ρ+ π- - {-211, 211, 111}, // π- π+ π0 - {-321, 321} // K- K+ - }}, - {431, { - {211, 333}, // φ π+ - {-313, 321}, // antiK*(892) K+ - {333, 213}, // φ ρ - {113, 211}, // ρ π+ - {225, 211}, // f2(1270) π+ - {-211, 211, 211}, // π- π+ π+ (s-wave) - {313, 211}, // K*(892)0 π+ - {10221, 321}, // f0(1370) K+ - {113, 321}, // ρ0 K+ - {-211, 321, 211}, // π- K+ π+ (non-resonant) - {221, 211} // η π+ - }}, - {4122, { - {2212, -321, 211}, // p K- π+ (non-resonant) - {2212, -313}, // p K*0(892) - {2224, -321}, // Δ++ K- - {102134, 211}, // Λ(1520) K- - {2212, -321, 211, 111}, // p K- π+ π0 - {2212, -211, 211}, // p π- π+ - {2212, 333} // p φ - }}, - {4232, { - {-313, 2212}, // antiK*0(892) p - {2212, -321, 211}, // p K- π+ - {2212, 333}, // p φ - {3222, -211, 211} // Σ+ π- π+ - }}, + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, }; - TFile file(path.c_str(), "READ"); if (file.IsZombie()) { @@ -110,7 +119,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -121,6 +130,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C index 112cda1f4..d3f861f24 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C @@ -5,17 +5,77 @@ int External() { int checkPdgQuarkOne{4}; int checkPdgQuarkTwo{5}; float ratioTrigger = 1.; // one event triggered out of 1 - float averagePt = 0.; std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ - {421, {{-321, 211}, {-321, 111, 211}}}, // D0 - {431, {{211, 333}, {-313, 321}}}, // Ds+ - {4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+ - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+ - {4332, {{211, 3334}}} // Omegac+ + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -62,14 +122,13 @@ int External() { } if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal nSignals++; // count signal PDG - averagePt += track.GetPt(); std::vector pdgsDecay{}; std::vector pdgsDecayAntiPart{}; for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -80,6 +139,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; @@ -89,8 +149,6 @@ int External() { } } - averagePt /= nSignals; - std::cout << "--------------------------------\n"; std::cout << "# Events: " << nEvents << "\n"; //std::cout << "# MB events: " << nEventsMB << "\n"; @@ -100,7 +158,6 @@ int External() { std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; std::cout <<"# signal hadrons: " << nSignals << "\n"; std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; - std::cout <<"average pT of signal hadrons: " << averagePt << "\n"; //if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small // std::cerr << "Number of generated MB events different than expected\n"; From 14fd260757a435f3c9a512fa8b3cfd5d341cb5c6 Mon Sep 17 00:00:00 2001 From: Fabrizio Chinu <91954233+fchinu@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:48:34 +0200 Subject: [PATCH 094/362] PWGHF: Smoothen injection function vs impact parameter (#2134) --- MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C index 1fd07e182..423c4509e 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C @@ -111,7 +111,7 @@ public: LOG(info) << "[notifyEmbedding] ----- Collision impact parameter: " << x; /// number of events to be embedded in a background event - mNumSigEvs = std::max(1.,120.*(x<5.)+80.*(1.-x/20.)*(x>5.)*(x<11.)+240.*(1.-x/13.)*(x>11.)); + mNumSigEvs = 5 + 0.886202881*std::pow(std::max(0.0f, 17.5f - x),1.7); LOG(info) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std::endl; }; From fb7c3cd017951cb689067216fba75dbb737d3539 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 30 Sep 2025 13:06:21 +0200 Subject: [PATCH 095/362] Target refactor in anchoredMC; Improvements for early file removal Changes the way we construct targets in anchorMC: Instead of calling different workflows in order (AOD, TPC-time-series, QC), we now execute one single workflow with all necessary targets in one go. This has the advantage that we can apply "early-file-removal" more easily and should also lead to CPU efficiency improvements. Some other improvements in anchoredMC: - allow to create just the workflow.json file - allow to inject additional options for the workflow runner The changes in o2dpg_workflow_runner.py concern mostly improvements for the early-artefact removal. E.g.: - do not remove artefacts when they belong to a final target task --- MC/bin/o2_dpg_workflow_runner.py | 51 ++++++++++++++++++----- MC/bin/o2dpg_qc_finalization_workflow.py | 2 +- MC/bin/o2dpg_sim_workflow.py | 2 +- MC/run/ANCHOR/anchorMC.sh | 52 ++++++++++++++---------- 4 files changed, 73 insertions(+), 34 deletions(-) diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index 33c875782..30f3462fa 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -100,6 +100,7 @@ def setup_logger(name, log_file, level=logging.INFO): meta["cpu_limit"] = args.cpu_limit meta["mem_limit"] = args.mem_limit meta["workflow_file"] = os.path.abspath(args.workflowfile) +args.target_tasks = [f.strip('"').strip("'") for f in args.target_tasks] # strip quotes from the shell meta["target_task"] = args.target_tasks meta["rerun_from"] = args.rerun_from meta["target_labels"] = args.target_labels @@ -321,12 +322,12 @@ def load_json(workflowfile): # filters the original workflowspec according to wanted targets or labels -# returns a new workflowspec +# returns a new workflowspec and the list of "final" workflowtargets def filter_workflow(workflowspec, targets=[], targetlabels=[]): if len(targets)==0: - return workflowspec + return workflowspec, [] if len(targetlabels)==0 and len(targets)==1 and targets[0]=="*": - return workflowspec + return workflowspec, [] transformedworkflowspec = workflowspec @@ -334,7 +335,7 @@ def task_matches(t): for filt in targets: if filt=="*": return True - if re.match(filt, t)!=None: + if re.match(filt, t) != None: return True return False @@ -372,6 +373,8 @@ def canBeDone(t,cache={}): ok = False break cache[t['name']] = ok + if ok == False: + print (f"Disabling target {t['name']} due to unsatisfied requirements") return ok okcache = {} @@ -404,7 +407,7 @@ def needed_by_targets(name): # we finaly copy everything matching the targets as well # as all their requirements transformedworkflowspec['stages']=[ l for l in workflowspec['stages'] if needed_by_targets(l['name']) ] - return transformedworkflowspec + return transformedworkflowspec, full_target_name_list # builds topological orderings (for each timeframe) @@ -898,7 +901,7 @@ def ok_to_submit_backfill(res, backfill_cpu_factor=1.5, backfill_mem_factor=1.5) break -def filegraph_expand_timeframes(data: dict, timeframes: set) -> dict: +def filegraph_expand_timeframes(data: dict, timeframes: set, target_namelist) -> dict: """ A utility function for the fileaccess logic. Takes a template and duplicates for the multi-timeframe structure. @@ -921,6 +924,12 @@ def filegraph_expand_timeframes(data: dict, timeframes: set) -> dict: entry["written_by"] = [ re.sub(r"_\d+$", f"_{i}", w) for w in entry["written_by"] ] + # for now we mark some files as keep if they are written + # by a target in the runner targetlist. TODO: Add other mechanisms + # to ask for file keeping (such as via regex or the like) + for e in entry["written_by"]: + if e in target_namelist: + entry["keep"] = True entry["read_by"] = [ re.sub(r"_\d+$", f"_{i}", r) for r in entry["read_by"] ] @@ -945,7 +954,8 @@ def __init__(self, workflowfile, args, jmax=100): os.environ[e] = str(value) # only keep those tasks that are necessary to be executed based on user's filters - self.workflowspec = filter_workflow(self.workflowspec, args.target_tasks, args.target_labels) + self.full_target_namelist = [] + self.workflowspec, self.full_target_namelist = filter_workflow(self.workflowspec, args.target_tasks, args.target_labels) if not self.workflowspec['stages']: if args.target_tasks: @@ -1015,7 +1025,7 @@ def __init__(self, workflowfile, args, jmax=100): with open(args.remove_files_early) as f: filegraph_data = json.load(f) self.do_early_file_removal = True - self.file_removal_candidates = filegraph_expand_timeframes(filegraph_data, self.timeframeset) + self.file_removal_candidates = filegraph_expand_timeframes(filegraph_data, self.timeframeset, self.full_target_namelist) def perform_early_file_removal(self, taskids): @@ -1031,7 +1041,7 @@ def remove_if_exists(filepath: str) -> None: if os.path.exists(filepath): fsize = os.path.getsize(filepath) os.remove(filepath) - actionlogger.info(f"Removing {filepath} since no longer needed. Freeing {fsize/1024.} MB.") + actionlogger.info(f"Removing {filepath} since no longer needed. Freeing {fsize/1024./1024.} MB.") return True return False @@ -1057,7 +1067,7 @@ def remove_for_task_id(taskname, file_dict, timeframe_id, listofalltimeframes): file_entry['written_by'].remove(taskname) # TODO: in principle the written_by criterion might not be needed - if len(file_entry['read_by']) == 0 and len(file_entry['written_by']) == 0: + if len(file_entry['read_by']) == 0 and len(file_entry['written_by']) == 0 and file_entry.get('keep', False) == False: # the filename mentioned here is no longer needed and we can remove it # make sure it is there and then delete it if remove_if_exists(filename): @@ -1329,6 +1339,17 @@ def monitor(self, process_list): globalPSS=0. resources_per_task = {} + # On a global level, we are interested in total disc space used (not differential in tasks) + # We can call system "du" as the fastest impl + def disk_usage_du(path: str) -> int: + """Use system du to get total size in bytes.""" + out = subprocess.check_output(['du', '-sb', path], text=True) + return int(out.split()[0]) + + disc_usage = -1 + if os.getenv("MONITOR_DISC_USAGE"): + disc_usage = disk_usage_du(os.getcwd()) / 1024. / 1024 # in MB + for tid, proc in process_list: # proc is Popen object @@ -1399,7 +1420,15 @@ def monitor(self, process_list): totalUSS = totalUSS / 1024 / 1024 totalPSS = totalPSS / 1024 / 1024 nice_value = proc.nice() - resources_per_task[tid]={'iter':self.internalmonitorid, 'name':self.idtotask[tid], 'cpu':totalCPU, 'uss':totalUSS, 'pss':totalPSS, 'nice':nice_value, 'swap':totalSWAP, 'label':self.workflowspec['stages'][tid]['labels']} + resources_per_task[tid]={'iter':self.internalmonitorid, + 'name':self.idtotask[tid], + 'cpu':totalCPU, + 'uss':totalUSS, + 'pss':totalPSS, + 'nice':nice_value, + 'swap':totalSWAP, + 'label':self.workflowspec['stages'][tid]['labels'], + 'disc': disc_usage} self.resource_manager.add_monitored_resources(tid, time_delta, totalCPU / 100, totalPSS) if nice_value == self.resource_manager.nice_default: globalCPU += totalCPU diff --git a/MC/bin/o2dpg_qc_finalization_workflow.py b/MC/bin/o2dpg_qc_finalization_workflow.py index 78792b424..e05bf83d1 100755 --- a/MC/bin/o2dpg_qc_finalization_workflow.py +++ b/MC/bin/o2dpg_qc_finalization_workflow.py @@ -46,7 +46,7 @@ def add_QC_finalization(taskName, qcConfigPath, needs=None): if standalone == True: needs = [] elif needs == None: - needs = [taskName + '_local' + str(tf) for tf in range(1, ntimeframes + 1)] + needs = [taskName + '_local_' + str(tf) for tf in range(1, ntimeframes + 1)] task = createTask(name=QC_finalize_name(taskName), needs=needs, cwd=qcdir, lab=["QC"], cpu=1, mem='2000') def remove_json_prefix(path): diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 795545199..6923a50cc 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1726,7 +1726,7 @@ def getDigiTaskName(det): if includeFullQC or includeLocalQC: def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): - task = createTask(name=taskName + '_local' + str(tf), needs=needs, tf=tf, cwd=timeframeworkdir, lab=["QC"], cpu=1, mem='2000') + task = createTask(name=taskName + '_local_' + str(tf), needs=needs, tf=tf, cwd=timeframeworkdir, lab=["QC"], cpu=1, mem='2000') objectsFile = objectsFile if len(objectsFile) > 0 else taskName + '.root' def remove_json_prefix(path): diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 70ac64a87..77fb37af3 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -338,6 +338,10 @@ fi TIMESTAMP=`grep "Determined timestamp to be" ${anchoringLogFile} | awk '//{print $6}'` echo_info "TIMESTAMP IS ${TIMESTAMP}" +if [ "${ONLY_WORKFLOW_CREATION}" ]; then + exit 0 +fi + # check if this job is exluded because it falls inside a bad data-taking period ISEXCLUDED=$(grep "TIMESTAMP IS EXCLUDED IN RUN" ${anchoringLogFile}) if [ "${ISEXCLUDED}" ]; then @@ -383,30 +387,36 @@ export FAIRMQ_IPC_PREFIX=./ echo_info "Ready to start main workflow" -${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt ${ALIEN_JDL_O2DPGWORKFLOWTARGET:-aod} --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} --dynamic-resources -MCRC=$? # <--- we'll report back this code -if [[ "${MCRC}" == "0" && "${ALIEN_JDL_ADDTIMESERIESINMC}" != "0" ]]; then - # Default value is 1 so this is run by default. - echo_info "Running TPC time series" - ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt tpctimes - # Note: We could maybe avoid this if-else by including `tpctimes` directly in the workflow-targets above -fi - -if [[ "${MCRC}" == "0" && "${ALIEN_JDL_DOTPCRESIDUALEXTRACTION}" = "1" ]]; then - echo_info "Running TPC residuals extraction, aggregation and merging" - ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt tpcresidmerge +# Let us construct the workflow targets +targetString="" +if [ "${ALIEN_JDL_O2DPGWORKFLOWTARGET}" ]; then + # The user gave ${ALIEN_JDL_O2DPGWORKFLOWTARGET}. This is an expert mode not used in production. + # In this case, we will build just that. No QC, no TPC timeseries, ... + targetString=${ALIEN_JDL_O2DPGWORKFLOWTARGET} +else + targetString="'aodmerge.*'" + # Now add more targets depending on options + # -) The TPC timeseries targets + if [[ "${ALIEN_JDL_ADDTIMESERIESINMC}" == "1" ]]; then + targetString="${targetString} 'tpctimes.*'" + fi + # -) TPC residual calibration + if [ "${ALIEN_JDL_DOTPCRESIDUALSEXTRACTION}" ]; then + targetString="${targetString} 'tpcresidmerge.*'" + fi + # -) QC tasks + if [[ -z "${DISABLE_QC}" && "${remainingargs}" == *"--include-local-qc"* ]]; then + targetString="${targetString} '^.*QC.*'" # QC tasks should have QC in the name + fi fi +echo_info "Workflow will run with target specification ${targetString}" -[[ -n "${DISABLE_QC}" ]] && echo_info "QC is disabled, skip it." +${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt ${targetString} \ + --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} --dynamic-resources \ + ${ALIEN_O2DPG_FILEGRAPH:+--remove-files-early ${ALIEN_O2DPG_FILEGRAPH}} \ + ${ALIEN_O2DPG_ADDITIONAL_WORKFLOW_RUNNER_ARGS} -if [[ -z "${DISABLE_QC}" && "${MCRC}" == "0" && "${remainingargs}" == *"--include-local-qc"* ]] ; then - # do QC tasks - echo_info "Doing QC" - ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json --target-labels QC --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} -k - # NOTE that with the -k|--keep-going option, the runner will try to keep on executing even if some tasks fail. - # That means, even if there is a failing QC task, the return code will be 0 - MCRC=$? -fi +MCRC=$? # <--- we'll report back this code # # full logs tar-ed for output, regardless the error code or validation - to catch also QC logs... From 40a28660db2f97071dd17e6f9ba5a9aa628410d0 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 30 Sep 2025 13:13:21 +0200 Subject: [PATCH 096/362] make more QC tasks dependent on detector presence --- MC/bin/o2dpg_qc_finalization_workflow.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/MC/bin/o2dpg_qc_finalization_workflow.py b/MC/bin/o2dpg_qc_finalization_workflow.py index e05bf83d1..31f0b48a3 100755 --- a/MC/bin/o2dpg_qc_finalization_workflow.py +++ b/MC/bin/o2dpg_qc_finalization_workflow.py @@ -128,9 +128,11 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif add_QC_finalization('RecPointsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/ft0-reconstruction-config.json') add_QC_finalization('FV0DigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fv0-digits.json') add_QC_finalization('FDDRecPointsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fdd-recpoints.json') - add_QC_finalization('CPVDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-digits-task.json') - add_QC_finalization('CPVClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-clusters-task.json') - add_QC_finalization('PHSCellsClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/phs-cells-clusters-task.json') + if isActive('CPV'): + add_QC_finalization('CPVDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-digits-task.json') + add_QC_finalization('CPVClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-clusters-task.json') + if isActive('PHS'): + add_QC_finalization('PHSCellsClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/phs-cells-clusters-task.json') # The list of QC Post-processing workflows add_QC_postprocessing('tofTrendingHits', 'json://${O2DPG_ROOT}/MC/config/QC/json/tof-trending-hits.json', [QC_finalize_name('tofDigitsQC')], runSpecific=False, prodSpecific=True) From 0ed0a86f121aa95d4a84ed899d098094983a2780 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 30 Sep 2025 12:48:26 +0200 Subject: [PATCH 097/362] anchoredMC: treat case of disabled TOF detector --- MC/bin/o2dpg_sim_workflow.py | 25 ++++++++++++++++--------- MC/bin/o2dpg_workflow_utils.py | 3 +++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 6923a50cc..3a6ca1f30 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1330,7 +1330,8 @@ def getDigiTaskName(det): putConfigValues(), ('',' --disable-mc')[args.no_mc_labels] ]) - workflow['stages'].append(TOFRECOtask) + if isActive('TOF'): + workflow['stages'].append(TOFRECOtask) #<--------- TOF-TPC(-ITS) global track matcher workflow toftpcmatchneeds = [TOFRECOtask['name'], TPCRECOtask['name'], ITSTPCMATCHtask['name'], TRDTRACKINGtask2['name']] @@ -1355,7 +1356,8 @@ def getDigiTaskName(det): tpc_corr_options_mc ] TOFTPCMATCHERtask['cmd'] = task_finalizer(tofmatcher_cmd_parts) - workflow['stages'].append(TOFTPCMATCHERtask) + if isActive('TOF'): + workflow['stages'].append(TOFTPCMATCHERtask) # MFT reco: needing access to kinematics (when assessment enabled) mftreconeeds = [getDigiTaskName("MFT")] @@ -1524,7 +1526,11 @@ def getDigiTaskName(det): workflow['stages'].append(HMPRECOtask) #<--------- HMP forward matching - hmpmatchneeds = [HMPRECOtask['name'], ITSTPCMATCHtask['name'], TOFTPCMATCHERtask['name'], TRDTRACKINGtask2['name']] + hmpmatchneeds = [HMPRECOtask['name'], + ITSTPCMATCHtask['name'], + TOFTPCMATCHERtask['name'] if isActive("TOF") else None, + TRDTRACKINGtask2['name']] + hmpmatchneeds = [ n for n in hmpmatchneeds if n != None ] hmp_match_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-hmpid-matcher-workflow', 'track-sources', default_value='ITS-TPC,ITS-TPC-TRD,TPC-TRD')) HMPMATCHtask = createTask(name='hmpmatch_'+str(tf), needs=hmpmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') HMPMATCHtask['cmd'] = task_finalizer( @@ -1559,7 +1565,7 @@ def getDigiTaskName(det): HMPMATCHtask['name'], HMPMATCHtask['name'], ITSTPCMATCHtask['name'], - TOFTPCMATCHERtask['name'], + TOFTPCMATCHERtask['name'] if isActive("TOF") else None, MFTMCHMATCHtask['name'], MCHMIDMATCHtask['name']] pvfinderneeds = [ p for p in pvfinderneeds if p != None ] @@ -1792,11 +1798,12 @@ def remove_json_prefix(path): configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/trd-tracking-task.json') ### TOF - addQCPerTF(taskName='tofDigitsQC', - needs=[getDigiTaskName("TOF")], - readerCommand='${O2_ROOT}/bin/o2-tof-reco-workflow --delay-1st-tf 3 --input-type digits --output-type none', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tofdigits.json', - objectsFile='tofDigitsQC.root') + if isActive('TOF'): + addQCPerTF(taskName='tofDigitsQC', + needs=[getDigiTaskName("TOF")], + readerCommand='${O2_ROOT}/bin/o2-tof-reco-workflow --delay-1st-tf 3 --input-type digits --output-type none', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tofdigits.json', + objectsFile='tofDigitsQC.root') # depending if TRD and FT0 are available if isActive('FT0') and isActive('TRD'): diff --git a/MC/bin/o2dpg_workflow_utils.py b/MC/bin/o2dpg_workflow_utils.py index 31860856a..585cb49ed 100755 --- a/MC/bin/o2dpg_workflow_utils.py +++ b/MC/bin/o2dpg_workflow_utils.py @@ -172,6 +172,9 @@ def dump_workflow(workflow, filename, meta=None): s['cmd'] = '. ' + taskwrapper_string + ' ' + s['name']+'.log \'' + s['cmd'] + '\'' # remove unnecessary whitespaces for better readibility s['cmd'] = trimString(s['cmd']) + # remove None entries from needs list + s['needs'] = [ n for n in s['needs'] if n != None ] + # make the final dict to be dumped to_dump = {"stages": to_dump} filename = make_workflow_filename(filename) From 1c4641e208516147456c56346d3696be970a217d Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 30 Sep 2025 13:53:33 +0200 Subject: [PATCH 098/362] also disable TOF QC tasks when TOF not present --- MC/bin/o2dpg_sim_workflow.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 3a6ca1f30..c5fed1e54 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1805,27 +1805,27 @@ def remove_json_prefix(path): configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tofdigits.json', objectsFile='tofDigitsQC.root') - # depending if TRD and FT0 are available - if isActive('FT0') and isActive('TRD'): - addQCPerTF(taskName='tofft0PIDQC', + # depending if TRD and FT0 are available + if isActive('FT0') and isActive('TRD'): + addQCPerTF(taskName='tofft0PIDQC', needs=[TOFTPCMATCHERtask['name'], FT0RECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC,ITS-TPC-TRD,ITS-TPC-TRD-TOF,TPC-TRD,TPC-TRD-TOF" --cluster-types FT0', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidft0tof.json') - elif isActive('FT0'): - addQCPerTF(taskName='tofft0PIDQC', + elif isActive('FT0'): + addQCPerTF(taskName='tofft0PIDQC', needs=[TOFTPCMATCHERtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC" --cluster-types FT0', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidft0tofNoTRD.json') - elif isActive('TRD'): - addQCPerTF(taskName='tofPIDQC', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidft0tofNoTRD.json') + elif isActive('TRD'): + addQCPerTF(taskName='tofPIDQC', needs=[TOFTPCMATCHERtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC,ITS-TPC-TRD,ITS-TPC-TRD-TOF,TPC-TRD,TPC-TRD-TOF" --cluster-types none', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtof.json') - else: - addQCPerTF(taskName='tofPIDQC', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtof.json') + else: + addQCPerTF(taskName='tofPIDQC', needs=[TOFTPCMATCHERtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC" --cluster-types none', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtofNoTRD.json') + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtofNoTRD.json') ### EMCAL if isActive('EMC'): From 7ff87043fa337b9af931a5f38083b646c7e13b47 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 1 Oct 2025 00:36:46 +0200 Subject: [PATCH 099/362] Update variable for ROOT compiler env cashes --- MC/bin/o2_dpg_workflow_runner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index 30f3462fa..8709bbbe3 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -1777,6 +1777,7 @@ def speedup_ROOT_Init(): if not (args.no_rootinit_speedup == True): print ("setting up ROOT system") os.environ['ROOT_LDSYSPATH'] = libpath.decode() + os.environ['CLING_LDSYSPATH'] = libpath.decode() # b) the PATH for compiler includes needed by Cling cmd = "LC_ALL=C c++ -xc++ -E -v /dev/null 2>&1 | sed -n '/^#include/,${/^ \\/.*++/{p}}'" @@ -1787,6 +1788,7 @@ def speedup_ROOT_Init(): if not (args.no_rootinit_speedup == True): actionlogger.info("Determined ROOT_CPPSYSINCL=" + joined) os.environ['ROOT_CPPSYSINCL'] = joined + os.environ['CLING_CPPSYSINCL'] = joined speedup_ROOT_Init() From c979b67093fa8923267587a8ff60cb44c86898b5 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Wed, 1 Oct 2025 15:58:38 +0200 Subject: [PATCH 100/362] Custom number of events in generator tests --- .../epos4/generator/examplepbpb.optns | 32 ++++++++++ MC/config/examples/ini/GeneratorEPOS4PbPb.ini | 12 ++++ .../examples/ini/tests/GeneratorEPOS4PbPb.C | 60 +++++++++++++++++++ test/run_generator_tests.sh | 14 ++++- 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 MC/config/examples/epos4/generator/examplepbpb.optns create mode 100644 MC/config/examples/ini/GeneratorEPOS4PbPb.ini create mode 100644 MC/config/examples/ini/tests/GeneratorEPOS4PbPb.C diff --git a/MC/config/examples/epos4/generator/examplepbpb.optns b/MC/config/examples/epos4/generator/examplepbpb.optns new file mode 100644 index 000000000..217b2db77 --- /dev/null +++ b/MC/config/examples/epos4/generator/examplepbpb.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! Lead-Lead collision with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 82 !projectile atomic number +set maproj 208 !projectile mass number +set latarg 82 !target atomic number +set matarg 208 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 \ No newline at end of file diff --git a/MC/config/examples/ini/GeneratorEPOS4PbPb.ini b/MC/config/examples/ini/GeneratorEPOS4PbPb.ini new file mode 100644 index 000000000..6732c459c --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4PbPb.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 1 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/examplepbpb.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4PbPb.C b/MC/config/examples/ini/tests/GeneratorEPOS4PbPb.C new file mode 100644 index 000000000..3cc43d99c --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4PbPb.C @@ -0,0 +1,60 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there is 1 event, as customly set in the ini file + // Lead-Lead collisions with hydro and hadronic cascade are very slow to simulate + if (nEvents != 1) + { + std::cerr << "Expected 1 event, got " << nEvents << "\n"; + return 1; + } + // check if each event has two lead ions with 557440 (208*5360) GeV of energy + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + // Check if lead ion track energy is approximately equal to 557440 GeV (a tolerance of 50 MeV is considered, straight equality does not work due to floating point precision) + if (std::abs(energy - 557440) < 5e-2 && track.GetPdgCode() == 1000822080) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 lead ions at 557440 GeV\n"; + return 1; + } + } + return 0; +} \ No newline at end of file diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index c977f49c1..1fd510158 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -76,6 +76,16 @@ get_test_script_path_for_ini() echo ${path_to_test_script} } +get_nevents_from_ini() +{ + # function to force the number of events to be simulated from the ini file (default = 100) + # Syntax: #NEV_TEST> 10 (space between #NEV_TEST> and the number is mandatory) + # To be used only if external generator takes too long to run causing timeouts in CI + local ini_path=${1} + local nev=$(grep "#NEV_TEST>" ${ini_path} | tail -n 1 | awk '{print $2}' | tr -d ' ') + [[ "${nev}" == "" ]] && nev=100 + echo ${nev} +} exec_test() { @@ -89,12 +99,14 @@ exec_test() local RET=0 # this is how our test script is expected to be called local test_script=$(get_test_script_path_for_ini ${ini_path}) + # get the number of events to be simulated from the ini file + local nev=$(get_nevents_from_ini ${ini_path}) # prepare the header of the log files echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_KINE} echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_GENERIC_KINE} echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_SIM} # run the simulation, fail if not successful - o2-sim -g ${generator_lower} ${trigger} --noGeant -n 100 -j 4 --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" >> ${LOG_FILE_SIM} 2>&1 + o2-sim -g ${generator_lower} ${trigger} --noGeant -n ${nev} -j 4 --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" >> ${LOG_FILE_SIM} 2>&1 RET=${?} [[ "${RET}" != "0" ]] && { remove_artifacts ; return ${RET} ; } From 41467f35ad5b0203e8e7aa316c32b81084e7aa16 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 30 Sep 2025 12:53:26 +0200 Subject: [PATCH 101/362] anchorMC: Integrate aligned geometry download into O2DPG workflow So far, we are creating geometry files as step of the anchorMC script. However, it is better to do this as part of the actual MC workflow in order to benefit from the features of the workflow runner (checkpointing, etc). --- MC/bin/o2dpg_sim_workflow.py | 54 ++++++++++++++++++++++++++++++++++-- MC/run/ANCHOR/anchorMC.sh | 32 +-------------------- 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index c5fed1e54..4e359e3f9 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -510,10 +510,60 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): return common + " --shm-segment-size ${SHMSIZE:-50000000000} " else: return common - + + +# prefetch the aligned geometry object (for use in reconstruction) +GEOM_PREFETCH_TASK = createTask(name='geomprefetch', cpu='0') +# We need to query the config if this is done with or without parallel world. This needs to be improved +# as it could be defaulted in the ConfigKey system +with_parallel_world = 1 if args.confKey.find("useParallelWorld=1") != -1 else 0 +geom_cmd = f''' +# -- Create aligned geometry using ITS ideal alignment to avoid overlaps in geant +ENABLEPW={with_parallel_world} + +# when parallel world processing is disabled we need to switch off ITS alignment +if [ "${{ENABLEPW}}" == "0" ]; then + CCDBOBJECTS_IDEAL_MC="ITS/Calib/Align" + TIMESTAMP_IDEAL_MC=1 + ${{O2_ROOT}}/bin/o2-ccdb-downloadccdbfile --host http://alice-ccdb.cern.ch/ -p ${{CCDBOBJECTS_IDEAL_MC}} \ + -d ${{ALICEO2_CCDB_LOCALCACHE}} --timestamp ${{TIMESTAMP_IDEAL_MC}} + CCDB_RC="$?" + if [ ! "${{CCDB_RC}}" == "0" ]; then + echo "Problem during CCDB prefetching of ${{CCDBOBJECTS_IDEAL_MC}}. Exiting." + exit ${{CCDB_RC}} + fi +fi + +if [ "$ENABLEPW" == "0" ]; then + REMAP_OPT="--condition-remap=file://${{ALICEO2_CCDB_LOCALCACHE}}=ITS/Calib/Align" +else + REMAP_OPT="" +fi + +# fetch the global alignment geometry +${{O2_ROOT}}/bin/o2-create-aligned-geometry-workflow ${{ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after $ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}} \ + --configKeyValues "HBFUtils.startTime={args.timestamp}" -b --run ${{REMAP_OPT}} + +# copy the object into the CCDB cache +mkdir -p $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned +ln -s -f $PWD/o2sim_geometry-aligned.root $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned/snapshot.root +if [ "$ENABLEPW" == "0" ]; then + [[ -f $PWD/its_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry && ln -s -f $PWD/its_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry/snapshot.root +fi + +# MFT +[[ -f $PWD/mft_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry && ln -s -f $PWD/mft_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry/snapshot.root +''' + +with open("geomprefetcher_script.sh",'w') as f: + f.write(geom_cmd) +GEOM_PREFETCH_TASK['cmd'] = 'chmod +x ${PWD}/geomprefetcher_script.sh; ${PWD}/geomprefetcher_script.sh' +workflow['stages'].append(GEOM_PREFETCH_TASK) + + # create/publish the GRPs and other GLO objects for consistent use further down the pipeline orbitsPerTF=int(args.orbitsPerTF) -GRP_TASK = createTask(name='grpcreate', cpu='0') +GRP_TASK = createTask(name='grpcreate', needs=["geomprefetch"], cpu='0') GRP_TASK['cmd'] = 'o2-grp-simgrp-tool createGRPs --timestamp ' + str(args.timestamp) + ' --run ' + str(args.run) + ' --publishto ${ALICEO2_CCDB_LOCALCACHE:-.ccdb} -o grp --hbfpertf ' + str(orbitsPerTF) + ' --field ' + args.field GRP_TASK['cmd'] += ' --readoutDets ' + " ".join(activeDetectors) + ' --print ' + ('','--lhcif-CCDB')[args.run_anchored] if (not args.run_anchored == True) and len(args.bcPatternFile) > 0: diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 77fb37af3..e127f308e 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -351,37 +351,7 @@ if [ "${ISEXCLUDED}" ]; then exit 0 fi -# -- Create aligned geometry using ITS ideal alignment to avoid overlaps in geant -ENABLEPW=0 -if [[ ${remainingargs} == *"GeometryManagerParam.useParallelWorld=1"* ]]; then - ENABLEPW=1 -fi - -if [ "${ENABLEPW}" == "0" ]; then - CCDBOBJECTS_IDEAL_MC="ITS/Calib/Align" - TIMESTAMP_IDEAL_MC=1 - ${O2_ROOT}/bin/o2-ccdb-downloadccdbfile --host http://alice-ccdb.cern.ch/ -p ${CCDBOBJECTS_IDEAL_MC} -d ${ALICEO2_CCDB_LOCALCACHE} --timestamp ${TIMESTAMP_IDEAL_MC} - CCDB_RC="${?}" - if [ ! "${CCDB_RC}" == "0" ]; then - echo_error "Problem during CCDB prefetching of ${CCDBOBJECTS_IDEAL_MC}. Exiting." - exit ${CCDB_RC} - fi -fi - -# TODO This can potentially be removed or if needed, should be taken over by o2dpg_sim_workflow_anchored.py and O2_dpg_workflow_runner.py -if [ "${ENABLEPW}" == "0" ]; then - echo "run with echo in pipe" | ${O2_ROOT}/bin/o2-create-aligned-geometry-workflow ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}} --configKeyValues "HBFUtils.startTime=${TIMESTAMP}" --condition-remap=file://${ALICEO2_CCDB_LOCALCACHE}=ITS/Calib/Align -b --run -else - echo "run with echo in pipe" | ${O2_ROOT}/bin/o2-create-aligned-geometry-workflow ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}} --configKeyValues "HBFUtils.startTime=${TIMESTAMP}" -b --run -fi -mkdir -p $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned -ln -s -f $PWD/o2sim_geometry-aligned.root $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned/snapshot.root -if [ "${ENABLEPW}" == "0" ]; then - [[ -f $PWD/its_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry && ln -s -f $PWD/its_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry/snapshot.root -fi -[[ -f $PWD/mft_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry && ln -s -f $PWD/mft_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry/snapshot.root - -# -- RUN THE MC WORKLOAD TO PRODUCE AOD -- +# -- RUN THE MC WORKLOAD TO PRODUCE TARGETS -- export FAIRMQ_IPC_PREFIX=./ From d0e198135402f1018a7fb9afeceb29bf14564f38 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 2 Oct 2025 09:02:50 +0200 Subject: [PATCH 102/362] MC: allow ITS3 to be simulated by dpg scripts (#2128) * MC: allow to specify detector list * MC: allow to run ITS3 --- MC/bin/o2dpg_sim_workflow.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 4e359e3f9..ebc33953b 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -71,6 +71,7 @@ parser.add_argument('-trigger',help='event selection: particle, external', default='') parser.add_argument('-ini',help='generator init parameters file (full paths required), for example: ${O2DPG_ROOT}/MC/config/PWGHF/ini/GeneratorHF.ini', default='') parser.add_argument('-confKey',help='o2sim, generator or trigger configuration key values, for example: "GeneratorPythia8.config=pythia8.cfg;A.x=y"', default='') +parser.add_argument('--detectorList',help='pick which version of ALICE should be simulated', default='ALICE2') parser.add_argument('--readoutDets',help='comma separated string of detectors readout (does not modify material budget - only hit creation)', default='all') parser.add_argument('--make-evtpool', help='Generate workflow for event pool creation.', action='store_true') @@ -565,7 +566,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): orbitsPerTF=int(args.orbitsPerTF) GRP_TASK = createTask(name='grpcreate', needs=["geomprefetch"], cpu='0') GRP_TASK['cmd'] = 'o2-grp-simgrp-tool createGRPs --timestamp ' + str(args.timestamp) + ' --run ' + str(args.run) + ' --publishto ${ALICEO2_CCDB_LOCALCACHE:-.ccdb} -o grp --hbfpertf ' + str(orbitsPerTF) + ' --field ' + args.field -GRP_TASK['cmd'] += ' --readoutDets ' + " ".join(activeDetectors) + ' --print ' + ('','--lhcif-CCDB')[args.run_anchored] +GRP_TASK['cmd'] += ' --detectorList ' + args.detectorList + ' --readoutDets ' + " ".join(activeDetectors) + ' --print ' + ('','--lhcif-CCDB')[args.run_anchored] if (not args.run_anchored == True) and len(args.bcPatternFile) > 0: GRP_TASK['cmd'] += ' --bcPatternFile ' + str(args.bcPatternFile) if len(CONFKEYMV) > 0: @@ -714,7 +715,8 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): + ' --field ccdb ' + str(CONFKEYBKG) \ + ('',' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) \ + ' --vertexMode kCCDB' \ - + ' --fromCollContext collisioncontext.root:bkg' + + ' --fromCollContext collisioncontext.root:bkg ' \ + + ' --detectorList ' + args.detectorList if not isActive('all'): BKGtask['cmd'] += ' --readoutDetectors ' + " ".join(activeDetectors) @@ -748,6 +750,9 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): # a list of smaller sensors (used to construct digitization tasks in a parametrized way) smallsensorlist = [ "ITS", "TOF", "FDD", "MCH", "MID", "MFT", "HMP", "PHS", "CPV", "ZDC" ] +if args.detectorList == 'ALICE2.1': + smallsensorlist = ['IT3' if sensor == 'ITS' else sensor for sensor in smallsensorlist] + # a list of detectors that serve as input for the trigger processor CTP --> these need to be processed together for now ctp_trigger_inputlist = [ "FT0", "FV0", "EMC" ] @@ -805,12 +810,15 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): # determine final conf key for QED simulation QEDBaseConfig = "GeneratorExternal.fileName=$O2_ROOT/share/Generators/external/QEDLoader.C;QEDGenParam.yMin=-7;QEDGenParam.yMax=7;QEDGenParam.ptMin=0.001;QEDGenParam.ptMax=1.;QEDGenParam.xSectionHad="+str(XSecSys[COLTYPE])+";QEDGenParam.Z="+str(Zsys[COLTYPE])+";QEDGenParam.cmEnergy="+str(ECMS)+";Diamond.width[2]=6.;" QEDCONFKEY = constructConfigKeyArg(create_geant_config(args, QEDBaseConfig + args.confKeyQED)) - + qed_detectorlist = ' ITS MFT FT0 FV0 FDD ' + if args.detectorList == 'ALICE2.1': + qed_detectorlist = qed_detectorlist.replace('ITS', 'IT3') QED_task['cmd'] = 'o2-sim -e TGeant3 --field ccdb -j ' + str('1') + ' -o qed' \ - + ' -n ' + str(NEventsQED) + ' -m PIPE ITS MFT FT0 FV0 FDD ' \ + + ' -n ' + str(NEventsQED) + ' -m ' + qed_detectorlist \ + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) \ + ' --seed ' + str(TFSEED) \ + ' -g extgen ' \ + + ' --detectorList ' + args.detectorList \ + QEDCONFKEY QED_task['cmd'] += '; RC=$?; QEDXSecCheck=`grep xSectionQED qedgenparam.ini | sed \'s/xSectionQED=//\'`' QED_task['cmd'] += '; echo "CheckXSection ' + str(QEDXSecExpected[COLTYPE]) + ' = $QEDXSecCheck"; [[ ${RC} == 0 ]]' @@ -914,6 +922,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): + ' -g ' + str(GENERATOR) + ' ' + str(INIFILE) + ' -o genevents ' + embeddinto \ + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] \ + ' --seed ' + str(TFSEED) + ' -n ' + str(NSIGEVENTS) \ + + ' --detectorList ' + args.detectorList \ + ' --fromCollContext collisioncontext.root:' + signalprefix if GENERATOR=="hepmc": SGNGENtask['cmd'] += "; RC=$?; ${O2DPG_ROOT}/UTILS/UpdateHepMCEventSkip.sh ../HepMCEventSkip.json " + str(tf) + '; [[ ${RC} == 0 ]]' @@ -935,6 +944,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): relative_cpu=7/8, n_workers=NWORKERS_TF, mem=str(sgnmem)) sgncmdbase = '${O2_ROOT}/bin/o2-sim -e ' + str(SIMENGINE) + ' ' + str(MODULES) + ' -n ' + str(NSIGEVENTS) + ' --seed ' + str(TFSEED) \ + ' --field ccdb -j ' + str(NWORKERS_TF) + ' ' + str(CONFKEY) + ' ' + str(INIFILE) + ' -o ' + signalprefix + ' ' + embeddinto \ + + ' --detectorList ' + args.detectorList \ + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) if sep_event_mode: SGNtask['cmd'] = sgncmdbase + ' -g extkinO2 --extKinFile genevents_Kine.root ' + ' --vertexMode kNoVertex' @@ -1121,7 +1131,7 @@ def createRestDigiTask(name, det='ALLSMALLER'): tneeds += [QED_task['name']] commondigicmd = '${O2_ROOT}/bin/o2-sim-digitizer-workflow ' + getDPL_global_options() + ' -n ' + str(args.ns) + simsoption \ + ' --interactionRate ' + str(INTRATE) + ' --incontext ' + str(CONTEXTFILE) + ' --disable-write-ini' \ - + putConfigValues(["MFTAlpideParam", "ITSAlpideParam", "ITSDigitizerParam"], + + putConfigValues(["MFTAlpideParam", "ITSAlpideParam", "ITSDigitizerParam" if args.detectorList == 'ALICE2' else "IT3DigitizerParam"], localCF={"DigiParams.seed" : str(TFSEED), "MCHDigitizer.seed" : str(TFSEED)}) + QEDdigiargs if det=='ALLSMALLER': # here we combine all smaller digits in one DPL workflow @@ -1294,12 +1304,12 @@ def getDigiTaskName(det): #<--------- ITS reco task ITSMemEstimate = 12000 if havePbPb else 2000 # PbPb has much large mem requirement for now (in worst case) - ITSRECOtask=createTask(name='itsreco_'+str(tf), needs=[getDigiTaskName("ITS")], - tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem=str(ITSMemEstimate)) + ITSRECOtask=createTask(name='itsreco_'+str(tf), needs=[getDigiTaskName("ITS" if args.detectorList == 'ALICE2' else "IT3")], + tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem=str(ITSMemEstimate)) ITSRECOtask['cmd'] = task_finalizer([ - "${O2_ROOT}/bin/o2-its-reco-workflow", + "${O2_ROOT}/bin/o2-its-reco-workflow" if args.detectorList == 'ALICE2' else "${O2_ROOT}/bin/o2-its3-reco-workflow", getDPL_global_options(bigshm=havePbPb), - '--trackerCA', + '--trackerCA' if args.detectorList == 'ALICE2' else '', '--tracking-mode async', putConfigValues(["ITSVertexerParam", "ITSAlpideParam", @@ -1337,6 +1347,7 @@ def getDigiTaskName(det): 'ITSClustererParam', 'GPU_rec_tpc', 'trackTuneParams', + 'GlobalParams', 'ft0tag'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco), tpc_corr_scaling_options, @@ -1365,6 +1376,7 @@ def getDigiTaskName(det): 'trackTuneParams', 'GPU_rec_tpc', 'TPCGasParam', + 'GlobalParams', 'TPCCorrMap'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco), '--track-sources ' + trd_track_sources, tpc_corr_scaling_options, @@ -1655,7 +1667,7 @@ def getDigiTaskName(det): [ '${O2_ROOT}/bin/o2-secondary-vertexing-workflow', getDPL_global_options(bigshm=True), svfinder_threads, - putConfigValues(['svertexer', 'TPCCorrMap'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco), + putConfigValues(['svertexer', 'TPCCorrMap', 'GlobalParams'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco), tpc_corr_scaling_options, tpc_corr_options_mc, '--vertexing-sources ' + svfinder_sources, From 224078c12acf39a6007203b7d76be52a45f46830 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 2 Oct 2025 11:46:00 +0200 Subject: [PATCH 103/362] fix detectorList argument for PbPb (#2143) In #2128, I introduced a bug where the detectorList argument did not have a separating space after it. --- MC/bin/o2dpg_sim_workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index ebc33953b..54b56cd0d 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -818,7 +818,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) \ + ' --seed ' + str(TFSEED) \ + ' -g extgen ' \ - + ' --detectorList ' + args.detectorList \ + + ' --detectorList ' + args.detectorList + ' ' \ + QEDCONFKEY QED_task['cmd'] += '; RC=$?; QEDXSecCheck=`grep xSectionQED qedgenparam.ini | sed \'s/xSectionQED=//\'`' QED_task['cmd'] += '; echo "CheckXSection ' + str(QEDXSecExpected[COLTYPE]) + ' = $QEDXSecCheck"; [[ ${RC} == 0 ]]' From 5f04d25c4e65cefe77222e9691daca4a1cd28a65 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 1 Oct 2025 06:00:05 +0200 Subject: [PATCH 104/362] Top-N memory consumer feature --- MC/utils/o2dpg_sim_metrics.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MC/utils/o2dpg_sim_metrics.py b/MC/utils/o2dpg_sim_metrics.py index 25dbb00df..97cb40260 100755 --- a/MC/utils/o2dpg_sim_metrics.py +++ b/MC/utils/o2dpg_sim_metrics.py @@ -773,6 +773,19 @@ def print_statistics(resource_object): print ("Mean-CPU (cores): ", mean_cpu) print ("Max-CPU (cores): ", max_cpu) print ("CPU-efficiency: ", mean_cpu / meta["cpu_limit"]) + + #(c) Top N memory consumers by name + top_n = 5 + top_mem = ( + dframe.groupby('name')['pss'] + .max() # peak PSS for each component + .sort_values(ascending=False) # sort by memory usage + .head(top_n) + ) + + print(f"\nTop-{top_n} memory consumers (by peak PSS):") + for comp, mem in top_mem.items(): + print(f" {comp:<20s} {mem:10.2f} MB") print ("---> ") def stat(args): From fba4c22e56bb633516badecc541f3490d9858047 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 1 Oct 2025 08:55:26 +0200 Subject: [PATCH 105/362] Disable reading tf1 Kine files for EventStat No longer necessary and prevents early sgn_Kine.root removal. --- MC/bin/o2dpg_determine_eventstat.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/MC/bin/o2dpg_determine_eventstat.py b/MC/bin/o2dpg_determine_eventstat.py index 9e91a24c8..2daddd870 100755 --- a/MC/bin/o2dpg_determine_eventstat.py +++ b/MC/bin/o2dpg_determine_eventstat.py @@ -121,9 +121,11 @@ def read_AO2D_eventcount(file): return eventcount AO2D_eventcount = read_AO2D_eventcount(args.aod_file) -GEANT_eventcount = read_accumulated_GEANT_eventcount() -if AO2D_eventcount != GEANT_eventcount: - print ("WARN: AO2D MC event count and GEANT event count differ") + +# for debugging +# GEANT_eventcount = read_accumulated_GEANT_eventcount() +# if AO2D_eventcount != GEANT_eventcount: +# print ("WARN: AO2D MC event count and GEANT event count differ") print ("Found " + str(AO2D_eventcount) + " events in AO2D file") write_stat_file(AO2D_eventcount) From 5ebc579844ee12e018348c3d7d5fd06d6cf0cb7b Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 1 Oct 2025 09:37:42 +0200 Subject: [PATCH 106/362] metrics: report also max,mean disc usage --- MC/utils/o2dpg_sim_metrics.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MC/utils/o2dpg_sim_metrics.py b/MC/utils/o2dpg_sim_metrics.py index 97cb40260..711e616dd 100755 --- a/MC/utils/o2dpg_sim_metrics.py +++ b/MC/utils/o2dpg_sim_metrics.py @@ -782,10 +782,13 @@ def print_statistics(resource_object): .sort_values(ascending=False) # sort by memory usage .head(top_n) ) - print(f"\nTop-{top_n} memory consumers (by peak PSS):") for comp, mem in top_mem.items(): print(f" {comp:<20s} {mem:10.2f} MB") + + #(d) max disc consumption + print ("\nMax-DISC usage (MB): ", dframe['disc'].max()) + print ("Mean-DISC usage (MB): ", dframe['disc'].mean()) print ("---> ") def stat(args): From 40625bffe361508977dd8673782578bb124d9629 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 1 Oct 2025 07:39:45 +0200 Subject: [PATCH 107/362] TRD QC: Do not write tracklets While studying file-access graphs in O2DPG MC, I noticed that trdtracklets.root get written twice: One from the digitizer workflow and once from the TRD-DIGI-QC task. This can corrupt the processing and is probably a bug. QC should only read digits/trdtracklets. The reason appears to be the use of `o2-trd-trap-sim` as the reader command for digits and tracklets. For now, the problem can probably be avoided by using `o2-trd-trap-sim --disable-root-output true`. However, this might still create new trdtracklets in memory which should not be needed as they have been previously created during digitization. So it would be good to just use a true `o2-trd-sim-artefacts-reader` workflow or similar in the future. --- MC/bin/o2dpg_sim_workflow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 54b56cd0d..e5e7a65b1 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1849,9 +1849,10 @@ def remove_json_prefix(path): configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-standard-direct.json') ### TRD + # TODO: check if the readerCommand also reperforms tracklet construction (which already done in digitization) addQCPerTF(taskName='trdDigitsQC', needs=[TRDDigitask['name']], - readerCommand='o2-trd-trap-sim', + readerCommand='o2-trd-trap-sim --disable-root-output true', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') addQCPerTF(taskName='trdTrackingQC', From c74238cf5a9d09ee8038ac5a795d00f8c2ccd55d Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Thu, 2 Oct 2025 14:48:45 +0200 Subject: [PATCH 108/362] [MCH] added MW plots for digits and preclusters async QC (#2027) Two MW plots are added in the MCH async QC configuration, one providing the board-by-board readout rate and the other the board-by-board pseudo-efficiency. --- DATA/production/qc-async/mch-digits.json | 5 +++++ DATA/production/qc-async/mch-reco.json | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/DATA/production/qc-async/mch-digits.json b/DATA/production/qc-async/mch-digits.json index cf3594bc5..4b867fce6 100644 --- a/DATA/production/qc-async/mch-digits.json +++ b/DATA/production/qc-async/mch-digits.json @@ -36,7 +36,12 @@ "type": "direct", "query": "digits:MCH/DIGITS" }, + "movingWindows": [ + "RateSignalPerDualSampa" + ], "taskParameters": { + "Enable1DRateMaps": "true", + "Enable2DRateMaps": "false", "Diagnostic": "false" }, "grpGeomRequest": { diff --git a/DATA/production/qc-async/mch-reco.json b/DATA/production/qc-async/mch-reco.json index 55a18d32f..0fec68d6b 100644 --- a/DATA/production/qc-async/mch-reco.json +++ b/DATA/production/qc-async/mch-reco.json @@ -49,6 +49,13 @@ "dataSource": { "type": "direct", "query": "preclusters:MCH/PRECLUSTERS/0;preclusterdigits:MCH/PRECLUSTERDIGITS/0" + }, + "movingWindows": [ + "PseudoeffPerDualSampa" + ], + "taskParameters": { + "Enable1DPseudoeffMaps": "true", + "Enable2DPseudoeffMaps": "false" } }, "FRofs": { @@ -68,4 +75,4 @@ } } } -} \ No newline at end of file +} From e0fc23062b9feb12745fd85bce94f1e72d07ad1d Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 1 Oct 2025 15:08:32 +0200 Subject: [PATCH 109/362] small beautification --- MC/bin/o2_dpg_workflow_runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index 8709bbbe3..1301a5bad 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -460,9 +460,9 @@ def update_resource_estimates(workflow, resource_json): oldmem = task["resources"]["mem"] actionlogger.info("Updating mem estimate for " + task["name"] + " from " + str(oldmem) + " to " + str(newmem)) task["resources"]["mem"] = newmem - newcpu = new_resources.get("cpu", None) # cpu + newcpu = new_resources.get("cpu", None) if newcpu is not None: oldcpu = task["resources"]["cpu"] rel_cpu = task["resources"]["relative_cpu"] From 04c9dae75ba27f662cc50d989b4cf9e5e673db2c Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Wed, 1 Oct 2025 19:39:41 +0200 Subject: [PATCH 110/362] o2dpg_sim_metrics: Introduce JSON statistics and merging of statistics --- MC/utils/o2dpg_sim_metrics.py | 243 +++++++++++++++++++++++++++++++++- 1 file changed, 239 insertions(+), 4 deletions(-) diff --git a/MC/utils/o2dpg_sim_metrics.py b/MC/utils/o2dpg_sim_metrics.py index 711e616dd..c78fb1a59 100755 --- a/MC/utils/o2dpg_sim_metrics.py +++ b/MC/utils/o2dpg_sim_metrics.py @@ -12,6 +12,7 @@ import matplotlib import json import numpy as np +import math import pandas as pd ############################################################################ @@ -744,6 +745,108 @@ def extract_resources(pipelines): # Collect all metrics we got, here we want to have the median from all the iterations return [Resources(p) for p in pipelines] +def merge_stats(elementary, running): + """ + Merge an incoming elementary JSON into a running stats structure. + Also maintains running std using Welford's method. + + Each metric stores: + mean, std, M2, min, max, count + """ + if not elementary: + return running + + n_new_total = int(elementary.get("count", 1)) + running["count"] = running.get("count", 0) + n_new_total + + for name, metrics in elementary.items(): + if name == "count": + continue + + if name not in running: + running[name] = {"count": 0} + + # existing count for this name + n_old_name = running[name].get("count", 0) + + for metric, vals in metrics.items(): + if not isinstance(vals, dict): + continue + + if metric not in running[name]: + running[name][metric] = { + "min": vals.get("min"), + "max": vals.get("max"), + "mean": vals.get("mean"), + "std": 0.0, + "M2": 0.0, + "count": n_new_total + } + continue + + rmetric = running[name][metric] + n_old = rmetric.get("count", 0) + n_new = n_new_total + + # update min / max + e_min = vals.get("min") + e_max = vals.get("max") + if e_min is not None: + rmetric["min"] = e_min if rmetric["min"] is None else min(rmetric["min"], e_min) + if e_max is not None: + rmetric["max"] = e_max if rmetric["max"] is None else max(rmetric["max"], e_max) + + # combine means & M2 + mean_a = rmetric.get("mean") + mean_b = vals.get("mean") + + # If either mean is missing, use the one that exists + if mean_a is None and mean_b is None: + # Nothing to do + continue + elif mean_a is None: + rmetric["mean"] = mean_b + rmetric["M2"] = 0.0 + rmetric["count"] = n_new + elif mean_b is None: + # keep existing stats + rmetric["mean"] = mean_a + rmetric["M2"] = rmetric.get("M2", 0.0) + rmetric["count"] = n_old + else: + # both defined → do weighted merge + delta = mean_b - mean_a + new_count = n_old + n_new + new_mean = mean_a + delta * (n_new / new_count) + new_M2 = rmetric.get("M2", 0.0) + 0.0 + (delta**2) * (n_old * n_new / new_count) + + rmetric["mean"] = new_mean + rmetric["M2"] = new_M2 + rmetric["count"] = new_count + + # update std from M2 + c = rmetric["count"] + rmetric["std"] = math.sqrt(rmetric["M2"] / c) if c > 1 else 0.0 + + running[name]["count"] = n_old_name + n_new_total + + # round mean and std for readability + for name, metrics in running.items(): + if name == "count": + continue + for metric, vals in metrics.items(): + if not isinstance(vals, dict): + continue + if "mean" in vals: + vals["mean"] = r3(vals["mean"]) + if "std" in vals: + vals["std"] = r3(vals["std"]) + if "min" in vals: + vals["min"] = r3(vals["min"]) + if "max" in vals: + vals["max"] = r3(vals["max"]) + + return running def print_statistics(resource_object): """ @@ -787,9 +890,105 @@ def print_statistics(resource_object): print(f" {comp:<20s} {mem:10.2f} MB") #(d) max disc consumption - print ("\nMax-DISC usage (MB): ", dframe['disc'].max()) - print ("Mean-DISC usage (MB): ", dframe['disc'].mean()) - print ("---> ") + if 'disc' in dframe: + print ("\nMax-DISC usage (MB): ", dframe['disc'].max()) + print ("Mean-DISC usage (MB): ", dframe['disc'].mean()) + print ("---> ") + +def r3(x): + """Round to 3 decimals, return None for None/NaN.""" + if x is None: + return None + try: + xf = float(x) + except Exception: + return None + if math.isnan(xf): + return None + return round(xf, 3) + +def produce_json_stat(resource_object): + print ("<--- Producing resource json from file ", resource_object.pipeline_file) + dframe = resource_object.df + meta = resource_object.meta + + # also write json summary; This is a file that can be used + # to adjust the resource estimates in o2dpg_workflow_runner.py + # + resource_json = {} + # group by 'name' and compute all needed stats for each metric + stats = ( + dframe + .groupby('name') + .agg({ + 'pss': ['min', 'max', 'mean'], + 'uss': ['min', 'max', 'mean'], + 'cpu': ['min', 'max', 'mean'] + }) + ) + + # turn the multi-level columns into flat names + stats.columns = [f"{col[0]}_{col[1]}" for col in stats.columns] + stats = stats.reset_index() + + # ----- compute lifetime ~ walltime per (timeframe, name) ----- + # ------------------------------------------------ + # Filter out unrealistic timeframes (nice == 19) because it's not the realistic runtime + df_nice_filtered = dframe[dframe['nice'] != 19].copy() + + # the calculates of mean runtime should be averaged over timeframes + lifetime_per_tf = ( + df_nice_filtered + .groupby(['timeframe', 'name'])['iter'] + .agg(lambda x: x.max() - x.min() + 1) # +1 to include both ends + .reset_index(name='lifetime') + ) + + # now average over timeframes for each name + mean_lifetime = ( + lifetime_per_tf + .groupby('name')['lifetime'] + .mean() + ) + max_lifetime = ( + lifetime_per_tf + .groupby('name')['lifetime'] + .max() + ) + min_lifetime = ( + lifetime_per_tf + .groupby('name')['lifetime'] + .max() + ) + + resource_json["count"] = 1 # basic sample size + + # convert to nested dictionary + for _, row in stats.iterrows(): + name = row['name'] + resource_json[name] = { + 'pss': { + 'min': r3(row['pss_min']), + 'max': r3(row['pss_max']), + 'mean': r3(row['pss_mean']) + }, + 'uss': { + 'min': r3(row['uss_min']), + 'max': r3(row['uss_max']), + 'mean': r3(row['uss_mean']) + }, + 'cpu': { + 'min': r3(row['cpu_min']), + 'max': r3(row['cpu_max']), + 'mean': r3(row['cpu_mean']) + }, + 'lifetime': { + 'min' : r3(float(min_lifetime.get(name, np.nan))), + 'max' : r3(float(max_lifetime.get(name, np.nan))), + 'mean' : r3(float(mean_lifetime.get(name, np.nan))) + } + } + return resource_json def stat(args): """ @@ -801,6 +1000,32 @@ def stat(args): print_statistics(res) +def merge_stats_into(list_of_json_stats, outputfile): + running = {} + # read all the inputs + for inp_json in list_of_json_stats: + running = merge_stats(inp_json, running) + + # now write out the result into the output file + if running: + with open(outputfile, 'w') as f: + json.dump(running, f) + + +def json_stat(args): + resources = extract_resources(args.pipelines) + all_stats = [produce_json_stat(res) for res in resources] + merge_stats_into(all_stats, args.output) + + +def merge_json_stats(args): + all_stats = [] + for inp in args.inputs: + # load the json as a dict + with open(inp,'r') as f: + all_stats.append(json.load(f)) + merge_stats_into(all_stats, args.output) + def history(args): """ Entrypoint for history @@ -1048,7 +1273,17 @@ def main(): stat_parser.set_defaults(func=stat) stat_parser.add_argument("-p", "--pipelines", nargs="*", help="pipeline_metric files from o2_dpg_workflow_runner", required=True) - plot_parser = sub_parsers.add_parser("history", help="Plot (multiple) metrcis from extracted metrics JSON file(s)") + json_stat_parser = sub_parsers.add_parser("json-stat", help="Produce basic json stat (compatible with o2dog_workflow_runner injection)") + json_stat_parser.set_defaults(func=json_stat) + json_stat_parser.add_argument("-p", "--pipelines", nargs="*", help="Pipeline_metric files from o2_dpg_workflow_runner; Merges information", required=True) + json_stat_parser.add_argument("-o", "--output", type=str, help="Output json filename", required=True) + + merge_stat_parser = sub_parsers.add_parser("merge-json-stats", help="Merge information from json-stats into an aggregated stat") + merge_stat_parser.set_defaults(func=merge_json_stats) + merge_stat_parser.add_argument("-i", "--inputs", nargs="*", help="List of incoming/input json stat files", required=True) + merge_stat_parser.add_argument("-o", "--output", type=str, help="Output json filename", required=True) + + plot_parser = sub_parsers.add_parser("history", help="Plot (multiple) metrics from extracted metrics JSON file(s)") plot_parser.set_defaults(func=history) plot_parser.add_argument("-p", "--pipelines", nargs="*", help="pipeline_metric files from o2_dpg_workflow_runner", required=True) plot_parser.add_argument("--output", help="output directory", default="resource_history") From fc30fba2856844be1ab758e8f3cfaf1f7e4cabde Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 2 Oct 2025 13:32:53 +0200 Subject: [PATCH 111/362] meta info in metric json output --- MC/utils/o2dpg_sim_metrics.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/MC/utils/o2dpg_sim_metrics.py b/MC/utils/o2dpg_sim_metrics.py index c78fb1a59..36ae00387 100755 --- a/MC/utils/o2dpg_sim_metrics.py +++ b/MC/utils/o2dpg_sim_metrics.py @@ -1000,22 +1000,32 @@ def stat(args): print_statistics(res) -def merge_stats_into(list_of_json_stats, outputfile): +def merge_stats_into(list_of_json_stats, outputfile, metadata): running = {} # read all the inputs for inp_json in list_of_json_stats: running = merge_stats(inp_json, running) + # attach meta-data + running["meta-data"] = metadata + # now write out the result into the output file if running: with open(outputfile, 'w') as f: json.dump(running, f) +def build_meta_header(stringarg): + meta = {} + if stringarg != "": + meta = json.loads(stringarg) + return meta + def json_stat(args): resources = extract_resources(args.pipelines) all_stats = [produce_json_stat(res) for res in resources] - merge_stats_into(all_stats, args.output) + + merge_stats_into(all_stats, args.output, build_meta_header(args.header_data)) def merge_json_stats(args): @@ -1024,7 +1034,8 @@ def merge_json_stats(args): # load the json as a dict with open(inp,'r') as f: all_stats.append(json.load(f)) - merge_stats_into(all_stats, args.output) + + merge_stats_into(all_stats, args.output, build_meta_header(args.header_data)) def history(args): """ @@ -1277,11 +1288,13 @@ def main(): json_stat_parser.set_defaults(func=json_stat) json_stat_parser.add_argument("-p", "--pipelines", nargs="*", help="Pipeline_metric files from o2_dpg_workflow_runner; Merges information", required=True) json_stat_parser.add_argument("-o", "--output", type=str, help="Output json filename", required=True) + json_stat_parser.add_argument("-hd", "--header-data", type=str, default='', help="Some meta-data headers to be included in the JSON") merge_stat_parser = sub_parsers.add_parser("merge-json-stats", help="Merge information from json-stats into an aggregated stat") merge_stat_parser.set_defaults(func=merge_json_stats) merge_stat_parser.add_argument("-i", "--inputs", nargs="*", help="List of incoming/input json stat files", required=True) merge_stat_parser.add_argument("-o", "--output", type=str, help="Output json filename", required=True) + merge_stat_parser.add_argument("-hd", "--header-data", type=str, default="", help="Some meta-data headers to be included in the JSON") plot_parser = sub_parsers.add_parser("history", help="Plot (multiple) metrics from extracted metrics JSON file(s)") plot_parser.set_defaults(func=history) From a121b9d9a6b1f172aafcf898bd0571c2b30b735c Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 2 Oct 2025 13:26:34 +0200 Subject: [PATCH 112/362] AnchorMC: Allow more option overwrites --- MC/bin/o2dpg_sim_workflow.py | 2 +- MC/bin/o2dpg_sim_workflow_anchored.py | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index e5e7a65b1..e11a2a120 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -567,7 +567,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): GRP_TASK = createTask(name='grpcreate', needs=["geomprefetch"], cpu='0') GRP_TASK['cmd'] = 'o2-grp-simgrp-tool createGRPs --timestamp ' + str(args.timestamp) + ' --run ' + str(args.run) + ' --publishto ${ALICEO2_CCDB_LOCALCACHE:-.ccdb} -o grp --hbfpertf ' + str(orbitsPerTF) + ' --field ' + args.field GRP_TASK['cmd'] += ' --detectorList ' + args.detectorList + ' --readoutDets ' + " ".join(activeDetectors) + ' --print ' + ('','--lhcif-CCDB')[args.run_anchored] -if (not args.run_anchored == True) and len(args.bcPatternFile) > 0: +if len(args.bcPatternFile) > 0: GRP_TASK['cmd'] += ' --bcPatternFile ' + str(args.bcPatternFile) if len(CONFKEYMV) > 0: # this is allowing the possibility to setup/use a different MeanVertex object than the one from CCDB diff --git a/MC/bin/o2dpg_sim_workflow_anchored.py b/MC/bin/o2dpg_sim_workflow_anchored.py index 5d60450f3..57e6676b6 100755 --- a/MC/bin/o2dpg_sim_workflow_anchored.py +++ b/MC/bin/o2dpg_sim_workflow_anchored.py @@ -582,13 +582,19 @@ def main(): forwardargs += ' --ctp-scaler ' + str(ctp_local_rate_raw) # we finally pass forward to the unanchored MC workflow creation - # TODO: this needs to be done in a pythonic way clearly - # NOTE: forwardargs can - in principle - contain some of the arguments that are appended here. However, the last passed argument wins, so they would be overwritten. + # NOTE: forwardargs can - in principle - contain some of the arguments that are appended here. + # However, the last passed argument wins, so they would be overwritten. If this should not happen, the option + # needs to be handled as further below: energyarg = (" -eCM " + str(eCM)) if A1 == A2 else (" -eA " + str(eA) + " -eB " + str(eB)) forwardargs += " -tf " + str(args.tf) + " --sor " + str(run_start) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " --run-anchored --first-orbit " \ - + str(GLOparams["FirstOrbit"]) + " -field ccdb -bcPatternFile ccdb" + " --orbitsPerTF " + str(GLOparams["OrbitsPerTF"]) + " -col " + str(ColSystem) + str(energyarg) + + str(GLOparams["FirstOrbit"]) + " --orbitsPerTF " + str(GLOparams["OrbitsPerTF"]) + " -col " + str(ColSystem) + str(energyarg) + # the following options can be overwritten/influence from the outside if not '--readoutDets' in forwardargs: forwardargs += ' --readoutDets ' + GLOparams['detList'] + if not '-field' in forwardargs: + forwardargs += ' -field ccdb ' + if not '-bcPatternFile' in forwardargs: + forwardargs += ' -bcPatternFile ccdb ' print ("forward args ", forwardargs) cmd = "${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py " + forwardargs From fc65b5372e34df30de4501e8399bb81b3929049d Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 6 Oct 2025 15:58:51 +0200 Subject: [PATCH 113/362] MC: add special check for IT3 mocked output Signed-off-by: Felix Schlepper --- MC/bin/o2dpg_workflow_utils.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_workflow_utils.py b/MC/bin/o2dpg_workflow_utils.py index 585cb49ed..bb34c3660 100755 --- a/MC/bin/o2dpg_workflow_utils.py +++ b/MC/bin/o2dpg_workflow_utils.py @@ -22,7 +22,12 @@ def deactivate_detector(det): INACTIVE_DETECTORS.append(det) def isActive(det): - return det not in INACTIVE_DETECTORS and ("all" in ACTIVE_DETECTORS or det in ACTIVE_DETECTORS) + def check(detector): + return detector not in INACTIVE_DETECTORS and ("all" in ACTIVE_DETECTORS or detector in ACTIVE_DETECTORS) + if det == "ITS": # special remapping for upgrade only needed in one direction since IT3 output pretends to be ITS + return check("ITS") or check("IT3") + else: + return check(det) def compute_n_workers(interaction_rate, collision_system, n_workers_user=8, n_workers_min=1, interaction_rate_linear_below=300000): """ From 6d329a970b27fb6aae4691db6056b0538d72afc3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 7 Oct 2025 08:51:46 +0200 Subject: [PATCH 114/362] add additional newline at the end of inner fun --- MC/bin/o2dpg_workflow_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/MC/bin/o2dpg_workflow_utils.py b/MC/bin/o2dpg_workflow_utils.py index bb34c3660..763c472ab 100755 --- a/MC/bin/o2dpg_workflow_utils.py +++ b/MC/bin/o2dpg_workflow_utils.py @@ -24,6 +24,7 @@ def deactivate_detector(det): def isActive(det): def check(detector): return detector not in INACTIVE_DETECTORS and ("all" in ACTIVE_DETECTORS or detector in ACTIVE_DETECTORS) + if det == "ITS": # special remapping for upgrade only needed in one direction since IT3 output pretends to be ITS return check("ITS") or check("IT3") else: From 2954b82d1bee4604fb6d599b34dd09b25c4de99a Mon Sep 17 00:00:00 2001 From: sgaretti <129837066+sgaretti@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:38:29 +0200 Subject: [PATCH 115/362] [PWGDQ]: updating generator Pythia8 (#2148) Using a configuration file with Run 3 beam energy and new SigFitDefPar parameters --- ...nerator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini index c007f85a6..1a5877afe 100644 --- a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini @@ -5,4 +5,5 @@ funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,7) [GeneratorPythia8] ### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hi.cfg +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hi.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg From fd274b35e57581cc3441e602a1db9c5d4779fc69 Mon Sep 17 00:00:00 2001 From: Jseo <47848181+JinjooSeo@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:35:21 +0200 Subject: [PATCH 116/362] Dq pb pb (#2142) * DQ PbPb MC * fix * Update pythia8_PbPb_5TeV.cfg * modift ini * Add test macro --- .../generator_pythia8_HadronTriggered_PbPb.C | 390 ++++++++++++++++++ ...nerator_InjectedCharmoniaMidy_PbPb5TeV.ini | 7 + ...Generator_InjectedCharmoniaMidy_PbPb5TeV.C | 84 ++++ 3 files changed, 481 insertions(+) create mode 100644 MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C create mode 100755 MC/config/PWGDQ/ini/Generator_InjectedCharmoniaMidy_PbPb5TeV.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedCharmoniaMidy_PbPb5TeV.C diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C new file mode 100644 index 000000000..2e6fe4a12 --- /dev/null +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C @@ -0,0 +1,390 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" +#include "TParticle.h" + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) +#include "GeneratorEvtGen.C" + +#include + +using namespace o2::eventgen; + +namespace o2 +{ +namespace eventgen +{ + +class GeneratorPythia8HadronTriggeredPbPb : public o2::eventgen::GeneratorPythia8 { +public: + + /// constructor + GeneratorPythia8HadronTriggeredPbPb(int inputTriggerRatio = 5) { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + // define minimum bias event generator + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_PbPb_5TeV.cfg"); + pythiaMBgen.readFile(pathconfigMB.Data()); + pythiaMBgen.readString("Random:setSeed on"); + pythiaMBgen.readString("Random:seed " + std::to_string(seed)); + mConfigMBdecays = ""; + mRapidityMin = -1.; + mRapidityMax = 1.; + mVerbose = false; + } + + /// Destructor + ~GeneratorPythia8HadronTriggeredPbPb() = default; + + void addHadronPDGs(int pdg) { mHadronsPDGs.push_back(pdg); }; + + void setRapidityRange(double valMin, double valMax) + { + mRapidityMin = valMin; + mRapidityMax = valMax; + }; + + void setTriggerGap(int triggerGap) {mInverseTriggerRatio = triggerGap;} + + void setConfigMBdecays(TString val){mConfigMBdecays = val;} + + void setVerbose(bool val) { mVerbose = val; }; + +protected: + + bool generateEvent() override { + return true; + } + + bool Init() override { + if(mConfigMBdecays.Contains("cfg")) { + pythiaMBgen.readFile(mConfigMBdecays.Data()); + } + GeneratorPythia8::Init(); + pythiaMBgen.init(); + return true; + } + + std::vector findAllCharmonia(const Pythia8::Event& event) { + std::vector out; out.reserve(4); + + for (int ipa = 0; ipa < event.size(); ++ipa) { + + auto daughterList = event[ipa].daughterList(); + + for (auto ida : daughterList) { + for (int pdg : mHadronsPDGs) { // check that at least one of the pdg code is found in the event + if (event[ida].id() == pdg) { + if ((event[ida].y() > mRapidityMin) && (event[ida].y() < mRapidityMax)) { + cout << "============= Found jpsi y,pt " << event[ida].y() << ", " << event[ida].pT() << endl; + out.push_back(ida); + } + } + } + } + } + + return out; + } + +void collectAncestors(const Pythia8::Event& event, int idx, std::vector& decayChains, std::vector& visited) { + if (idx < 0 || idx >= event.size()) return; + if (!visited[idx]) { + visited[idx] = 1; + decayChains.push_back(idx); + } + + const int idabs = std::abs(event[idx].id()); + if (idabs == 4 || idabs == 5 || idabs == 21) return; + + int mother1 = event[idx].mother1(); + int mother2 = event[idx].mother2(); + if (mother1 < 0) return; + if (mother2 < mother1) mother2 = mother1; + for (int m = mother1; m <= mother2; ++m) { + if (m == idx) continue; + collectAncestors(event, m, decayChains, visited); + } +} + +void collectDaughters(const Pythia8::Event& event, int idx, std::vector& decayChains, std::vector& visited) { + if (idx < 0 || idx >= event.size()) return; + if (visited[idx] == 0) { + decayChains.push_back(idx); + } + + if (visited[idx] == 2) return; + visited[idx] = 2; + + int daughter1 = event[idx].daughter1(); + int daughter2 = event[idx].daughter2(); + if (daughter1 < 0) return; + if (daughter2 < daughter1) daughter2 = daughter1; + for (int d = daughter1; d <= daughter2; ++d) { + if (d == idx) continue; + collectDaughters(event, d, decayChains, visited); + } +} + +TParticle makeTParticleTemp(const Pythia8::Event& event, int idx) { + const auto& q = event[idx]; + int status = q.status(); + if (status < 0) { + return TParticle(0, 0, -1, -1, -1, -1, + 0.,0.,0.,0., 0.,0.,0.,0.); + } + + int m1 = q.mother1(); + int m2 = q.mother2(); + int d1 = q.daughter1(); + int d2 = q.daughter2(); + return TParticle(q.id(), status, m1, m2, d1, d2, + q.px(), q.py(), q.pz(), q.e(), + q.xProd(), q.yProd(), q.zProd(), q.tProd()); +} + +Bool_t importParticles() override +{ + //LOG(info) << ""; + //LOG(info) << "*************************************************************"; + //LOG(info) << "************** New signal event considered **************"; + //LOG(info) << "*************************************************************"; + //LOG(info) << ""; + + const int nSig = std::max(1, (int)std::lround(mNumSigEvs)); + for (int isig=0; isig charmonia; + while (! (genOk && !charmonia.empty())) { + /// reset event + mPythia.event.reset(); + genOk = GeneratorPythia8::generateEvent(); + if (!genOk) continue; + charmonia = findAllCharmonia(mPythia.event); + } + + std::vector decayChains; + std::vector visited(mPythia.event.size(), 0); + decayChains.reserve(256); + + // find all ancestors of the charmonia + for (size_t ic = 0; ic < charmonia.size(); ++ic) { + int cidx = charmonia[ic]; + collectAncestors(mPythia.event, cidx, decayChains, visited); + } + + // find all daughters of the charmonia + for (size_t ic = 0; ic < charmonia.size(); ++ic) { + int cidx = charmonia[ic]; + collectDaughters(mPythia.event, cidx, decayChains, visited); + } + + std::vector idxMap(mPythia.event.size(), -1); + mParticles.reserve(mParticles.size() + (int)decayChains.size()); + + for (int i = 0; i < (int)decayChains.size(); ++i) { + const int srcIdx = decayChains[i]; + if (srcIdx < 0 || srcIdx >= mPythia.event.size()) continue; + + TParticle part = makeTParticleTemp(mPythia.event, srcIdx); + if(part.GetPdgCode() == 0) continue; + + int newIdx = (int)mParticles.size(); + mParticles.push_back(part); + idxMap[srcIdx] = newIdx; + } + + for (int iLoc = 0; iLoc < (int) decayChains.size(); ++iLoc) { + const int srcIdx = decayChains[iLoc]; + if (srcIdx < 0 || srcIdx >= (int)idxMap.size()) continue; + const int outIdx = idxMap[srcIdx]; + if (outIdx < 0) continue; + + const auto& src = mPythia.event[srcIdx]; + + const int mother1 = (src.mother1() >= 0 ? idxMap[src.mother1()] : -1); + const int mother2 = (src.mother2() >= 0 ? idxMap[src.mother2()] : -1); + const int daughter1 = (src.daughter1()>= 0 ? idxMap[src.daughter1()] : -1); + const int daughter2 = (src.daughter2()>= 0 ? idxMap[src.daughter2()] : -1); + + // update TParticle + TParticle& particle = mParticles[outIdx]; + particle.SetFirstMother(mother1); + particle.SetLastMother(mother2); + particle.SetFirstDaughter(daughter1); + particle.SetLastDaughter(daughter2); + } + LOG(info) << "-----------------------------------------------"; + LOG(info) << "============ After event " << isig << " (size " << decayChains.size() << ")"; + LOG(info) << "Full stack (size " << mParticles.size() << "):"; + LOG(info) << "-----------------------------------------------"; + // printParticleVector(mParticles); + } + + if (mVerbose) mOutputEvent.list(); + + return kTRUE; +} + +void notifyEmbedding(const o2::dataformats::MCEventHeader* bkgHeader) override { + LOG(info) << "[notifyEmbedding] ----- Function called"; + + /// Impact parameter between the two nuclei + const float x = bkgHeader->GetB(); + LOG(info) << "[notifyEmbedding] ----- Collision impact parameter: " << x; + + /// number of events to be embedded in a background event + mNumSigEvs = 5 + 0.886202881*std::pow(std::max(0.0f, 17.5f - x),1.7); + LOG(info) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std::endl; +}; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + Pythia8::Pythia pythiaMBgen; // minimum bias event + TString mConfigMBdecays; + std::vector mHadronsPDGs; + double mRapidityMin; + double mRapidityMax; + bool mVerbose; + + // number of signal events to be embedded in a background event + int mNumSigEvs{1}; +}; + +} + +} + +// Predefined generators: +FairGenerator* + GeneratorPromptJpsi_EvtGenMidY(int triggerGap, double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->setVerbose(verbose); + + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + + gen->SetSizePdg(1); + gen->AddPdg(443, 0); + + gen->SetForceDecay(kEvtDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorPromptJpsiPsi2S_EvtGenMidY(int triggerGap, double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->addHadronPDGs(100443); + gen->setVerbose(verbose); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + gen->SetSizePdg(2); + gen->AddPdg(443, 0); + gen->AddPdg(100443, 1); + gen->SetForceDecay(kEvtDiElectron); + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + // print debug + // gen->PrintDebug(); + return gen; +} + +FairGenerator* + GeneratorPromptJpsi_EvtGenFwdy(int triggerGap, double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->setVerbose(verbose); + + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + + gen->SetSizePdg(1); + gen->AddPdg(443, 0); + + gen->SetForceDecay(kEvtDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorPromptJpsiPsi2S_EvtGenFwdY(int triggerGap, double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->addHadronPDGs(100443); + gen->setVerbose(verbose); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + gen->SetSizePdg(2); + gen->AddPdg(443, 0); + gen->AddPdg(100443, 1); + gen->SetForceDecay(kEvtDiMuon); + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + // print debug + // gen->PrintDebug(); + return gen; +} diff --git a/MC/config/PWGDQ/ini/Generator_InjectedCharmoniaMidy_PbPb5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedCharmoniaMidy_PbPb5TeV.ini new file mode 100755 index 000000000..d3e0e5931 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedCharmoniaMidy_PbPb5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C +funcName=GeneratorPromptJpsiPsi2S_EvtGenMidY(1,-1,1,false) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedCharmoniaMidy_PbPb5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedCharmoniaMidy_PbPb5TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedCharmoniaMidy_PbPb5TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From 6b44b5d3f959b87db1bb8ce1b66c661ff8c3d6c5 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 2 Oct 2025 21:49:42 +0200 Subject: [PATCH 117/362] anchorMC: Improve checking of essential variables * we need to check for variable presence before any assignment * prevent publication of MCProd when LPM production tag was empty --- MC/prodinfo/mcprodinfo_ccdb_upload.py | 4 ++++ MC/run/ANCHOR/anchorMC.sh | 26 ++++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/MC/prodinfo/mcprodinfo_ccdb_upload.py b/MC/prodinfo/mcprodinfo_ccdb_upload.py index 4a6ed75f3..2de6cfd81 100644 --- a/MC/prodinfo/mcprodinfo_ccdb_upload.py +++ b/MC/prodinfo/mcprodinfo_ccdb_upload.py @@ -148,6 +148,10 @@ def upload_mcprodinfo_meta(base_url, user, run_number, lpm_prod_tag, keys, cert_ def publish_MCProdInfo(mc_prod_info, ccdb_url = "https://alice-ccdb.cern.ch", username = "aliprod", force_overwrite=False, include_meta_into_aod=False): print("Publishing MCProdInfo") + if mc_prod_info.LPMProductionTag == None or len(mc_prod_info.LPMProductionTag) == 0: + print ("No LPM production tag found; Not publishing") + return + # see if this already has meta-data uploaded, otherwise do nothing mc_prod_info_q = query_mcprodinfo(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag) if mc_prod_info_q == None or force_overwrite == True: diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index e127f308e..19973eb23 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -119,18 +119,7 @@ export ALIEN_JDL_LPMANCHORYEAR=${ALIEN_JDL_LPMANCHORYEAR:-${ANCHORYEAR}} # decide whether to run TPC time series; on by default, switched off by setting to 0 export ALIEN_JDL_ADDTIMESERIESINMC=${ALIEN_JDL_ADDTIMESERIESINMC:-1} -# cache the production tag, will be set to a special anchor tag; reset later in fact -ALIEN_JDL_LPMPRODUCTIONTAG_KEEP=$ALIEN_JDL_LPMPRODUCTIONTAG -echo_info "Substituting ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG with ALIEN_JDL_LPMANCHORPRODUCTION=$ALIEN_JDL_LPMANCHORPRODUCTION for simulating reco pass..." -ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMANCHORPRODUCTION - -if [[ $ALIEN_JDL_ANCHOR_SIM_OPTIONS == *"--tpc-distortion-type 2"* ]]; then - export O2DPG_ENABLE_TPC_DISTORTIONS=ON - # set the SCALING SOURCE to CTP for MC unless explicitely given from outside - export ALIEN_JDL_TPCSCALINGSOURCE=${ALIEN_JDL_TPCSCALINGSOURCE:-"CTP"} -fi - -# check variables that need to be set +# check for presence of essential variables that need to be set [ -z "${ALIEN_JDL_LPMANCHORPASSNAME}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORPASSNAME or ANCHORPASSNAME" ; exit 1 ; } [ -z "${ALIEN_JDL_LPMRUNNUMBER}" ] && { echo_error "Set ALIEN_JDL_LPMRUNNUMBER or RUNNUMBER" ; exit 1 ; } [ -z "${ALIEN_JDL_LPMPRODUCTIONTYPE}" ] && { echo_error "Set ALIEN_JDL_LPMPRODUCTIONTYPE or PRODUCTIONTYPE" ; exit 1 ; } @@ -144,6 +133,19 @@ fi [ -z "${SPLITID}" ] && { echo_error "Set SPLITID" ; exit 1 ; } [ -z "${PRODSPLIT}" ] && { echo_error "Set PRODSPLIT" ; exit 1 ; } + +# cache the production tag, will be set to a special anchor tag; reset later in fact +ALIEN_JDL_LPMPRODUCTIONTAG_KEEP=$ALIEN_JDL_LPMPRODUCTIONTAG +echo_info "Substituting ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG with ALIEN_JDL_LPMANCHORPRODUCTION=$ALIEN_JDL_LPMANCHORPRODUCTION for simulating reco pass..." +ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMANCHORPRODUCTION + +if [[ $ALIEN_JDL_ANCHOR_SIM_OPTIONS == *"--tpc-distortion-type 2"* ]]; then + export O2DPG_ENABLE_TPC_DISTORTIONS=ON + # set the SCALING SOURCE to CTP for MC unless explicitely given from outside + export ALIEN_JDL_TPCSCALINGSOURCE=${ALIEN_JDL_TPCSCALINGSOURCE:-"CTP"} +fi + + # The number of signal events can be given, but should be useful only in # certain expert modes. In the default case, the final event number is determined by the timeframe length. if [ -z "${NSIGEVENTS}" ]; then From 9e82588f0285d490ed90dcaad4bd349d7cb37ab3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 7 Oct 2025 14:08:49 +0200 Subject: [PATCH 118/362] MC: pvfinder need reco input only if det active Signed-off-by: Felix Schlepper --- MC/bin/o2dpg_sim_workflow.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index e11a2a120..3972c577a 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1617,19 +1617,18 @@ def getDigiTaskName(det): pvfinder_matching_sources = cleanDetectorInputList(pvfinder_matching_sources) pvfinderneeds = [TRDTRACKINGtask2['name'], - FT0RECOtask['name'], - FV0RECOtask['name'], - EMCRECOtask['name'], + FT0RECOtask['name'] if isActive("FT0") else None, + FV0RECOtask['name'] if isActive("FV0") else None, + EMCRECOtask['name'] if isActive("EMC") else None, PHSRECOtask['name'] if isActive("PHS") else None, CPVRECOtask['name'] if isActive("CPV") else None, - FDDRECOtask['name'], + FDDRECOtask['name'] if isActive("FDD") else None, ZDCRECOtask['name'] if isActive("ZDC") else None, - HMPMATCHtask['name'], - HMPMATCHtask['name'], - ITSTPCMATCHtask['name'], - TOFTPCMATCHERtask['name'] if isActive("TOF") else None, - MFTMCHMATCHtask['name'], - MCHMIDMATCHtask['name']] + HMPMATCHtask['name'] if isActive("HMP") else None, + ITSTPCMATCHtask['name'] if isActive("ITS") and isActive("TPC") else None, + TOFTPCMATCHERtask['name'] if isActive("TPC") and isActive("TOF") else None, + MFTMCHMATCHtask['name'] if isActive("MFT") and isActive("MCH") else None, + MCHMIDMATCHtask['name'] if isActive("MCH") and isActive("MID") else None] pvfinderneeds = [ p for p in pvfinderneeds if p != None ] PVFINDERtask = createTask(name='pvfinder_'+str(tf), needs=pvfinderneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=NWORKERS_TF, mem='4000') From 7c29d3534c681458a605dbcb9b40b5ef6023d759 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 2 Oct 2025 23:02:37 +0200 Subject: [PATCH 119/362] o2dpg_workflow_runner.py: Adapt format for --update-resources to that of o2dpg_sim_metrics.py --- MC/bin/o2_dpg_workflow_runner.py | 8 +++++--- MC/utils/o2dpg_sim_metrics.py | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index 1301a5bad..a9fbb28b4 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -440,6 +440,7 @@ def getweight(tid): # update the resource estimates of a workflow based on resources given via JSON def update_resource_estimates(workflow, resource_json): + # the resource_dict here is generated by tool o2dpg_sim_metrics.py json-stat resource_dict = load_json(resource_json) stages = workflow["stages"] @@ -455,17 +456,18 @@ def update_resource_estimates(workflow, resource_json): new_resources = resource_dict[name] # memory - newmem = new_resources.get("mem", None) + newmem = new_resources.get("pss", {}).get("max", None) if newmem is not None: oldmem = task["resources"]["mem"] actionlogger.info("Updating mem estimate for " + task["name"] + " from " + str(oldmem) + " to " + str(newmem)) task["resources"]["mem"] = newmem # cpu - newcpu = new_resources.get("cpu", None) + newcpu = new_resources.get("cpu", {}).get("mean", None) if newcpu is not None: oldcpu = task["resources"]["cpu"] rel_cpu = task["resources"]["relative_cpu"] + # TODO: No longer sure about this since we inject numbers from actually measured workloads if rel_cpu is not None: # respect the relative CPU settings # By default, the CPU value in the workflow is already scaled if relative_cpu is given. @@ -597,7 +599,7 @@ def __init__(self, tid, name, cpu, cpu_relative, mem, resource_boundaries): # sampled resources of this self.cpu_sampled = None self.mem_sampled = None - # Set these after a task has finished to compute new estomates for related tasks + # Set these after a task has finished to compute new estimates for related tasks self.walltime = None self.cpu_taken = None self.mem_taken = None diff --git a/MC/utils/o2dpg_sim_metrics.py b/MC/utils/o2dpg_sim_metrics.py index 36ae00387..f675a6b58 100755 --- a/MC/utils/o2dpg_sim_metrics.py +++ b/MC/utils/o2dpg_sim_metrics.py @@ -1004,16 +1004,19 @@ def merge_stats_into(list_of_json_stats, outputfile, metadata): running = {} # read all the inputs for inp_json in list_of_json_stats: + # we may have to strip the meta-data section first of all running = merge_stats(inp_json, running) # attach meta-data running["meta-data"] = metadata # now write out the result into the output file - if running: + if running and outputfile != None: with open(outputfile, 'w') as f: json.dump(running, f) + return running + def build_meta_header(stringarg): meta = {} From f1a59353493f4d1e756604f6f1aabacabef3e796 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 3 Oct 2025 06:10:28 +0200 Subject: [PATCH 120/362] further modularize o2dpg_sim_metrics --- MC/utils/o2dpg_sim_metrics.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/MC/utils/o2dpg_sim_metrics.py b/MC/utils/o2dpg_sim_metrics.py index f675a6b58..cb90fec09 100755 --- a/MC/utils/o2dpg_sim_metrics.py +++ b/MC/utils/o2dpg_sim_metrics.py @@ -1018,18 +1018,26 @@ def merge_stats_into(list_of_json_stats, outputfile, metadata): return running -def build_meta_header(stringarg): +def build_meta_header(arg): meta = {} - if stringarg != "": - meta = json.loads(stringarg) + if type(arg) == str: + if arg != "": + meta = json.loads(arg) + elif type(arg) == dict: + meta = deepcopy(arg) + else: + print ("Unsupported Meta input type") return meta -def json_stat(args): - resources = extract_resources(args.pipelines) +def json_stat_impl(pipelines, output, header_data): + resources = extract_resources(pipelines) all_stats = [produce_json_stat(res) for res in resources] - merge_stats_into(all_stats, args.output, build_meta_header(args.header_data)) + merge_stats_into(all_stats, output, build_meta_header(header_data)) + +def json_stat(args): + json_stat_impl(args.pipelines, args.output, args.header_data) def merge_json_stats(args): all_stats = [] From fa2f66002d43a7c6772569aec0967deb3890d912 Mon Sep 17 00:00:00 2001 From: Chuntai <48704924+wuctlby@users.noreply.github.com> Date: Wed, 8 Oct 2025 15:04:24 +0200 Subject: [PATCH 121/362] Add the `userhook` to the `ini` files used for the event pools production (#2122) * Add hooks for bbbar * Add hooks for ccbar * Update the variables' name from `checkPdgQuarkOne` to `checkPdgQuark` * Rename the `.ini` and `.c` file with the `OmegaC_NoDecay` suffix * Update the decay channels for `GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C` * Updates for `bbbar` * add `#NEV_TEST> 10` into the beggining of `ini` files * update the test scripts * update test script of nodecay --- .../GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini | 3 +++ ...ratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini | 3 +++ ..._D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini | 3 +++ ...neratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini | 3 +++ ...eneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini | 3 +++ ...rHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini | 3 +++ ...atorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini | 3 +++ ...D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini | 3 +++ .../GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini | 3 +++ ...atorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini} | 5 ++++- ..._D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini | 3 +++ ...neratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini | 3 +++ ...eneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini | 5 ++++- ...rHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini | 3 +++ ...atorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini | 3 +++ ...D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini | 3 +++ ...neratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C | 2 +- ...HF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C | 2 +- ...GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C | 14 ++++++++++++-- .../GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C | 2 +- ...torHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C | 2 +- ...F_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C | 2 +- ...eratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C} | 19 ++++++++----------- ...HF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C | 2 +- ...GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C | 14 ++++++++++++-- .../GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C | 2 +- ...torHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C | 2 +- ...F_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C | 2 +- 28 files changed, 91 insertions(+), 26 deletions(-) rename MC/config/PWGHF/ini/{GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.ini => GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini} (64%) rename MC/config/PWGHF/ini/tests/{GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.C => GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C} (77%) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini index 3868e83a1..1a8eeb8b5 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini index 2661ee333..091f15e22 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini index 1f335d8b9..6fd35e411 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini index cb7dcb724..e16fbfb70 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132, 4232 [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini index 374f24889..d1fd4223f 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini index 52218bc9d..cee03f3bc 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini index 4d073970a..8bc123304 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4232}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini index 5bc9cfd04..8b5935473 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4232}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini index 2c1b9c411..95c99d275 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini similarity index 64% rename from MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.ini rename to MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini index 7bdc17baf..fedb78299 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini @@ -1,8 +1,11 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_Omegac_to_Omega.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini index 5e2d34dd3..68348cbbd 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini index 6505ea24b..5e301a4cf 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132, 4232} [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini index 98fb54c62..2b23edbf2 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini @@ -1,8 +1,11 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini index 4425b2f9a..650eb8a5f 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini index ba9fb1e09..c308bfeda 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4232}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini index 892665f6d..849c5f4fa 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4232}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C index 73788a608..70fecc536 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 5; + int checkPdgQuark{5}; int checkPdgHadron{4332}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C index 73788a608..70fecc536 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 5; + int checkPdgQuark{5}; int checkPdgHadron{4332}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C index 69d9a256c..f2c79c2ad 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C @@ -6,8 +6,17 @@ int External() { std::vector checkPdgHadron{4132, 4232}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}} // Xic+ + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -65,6 +74,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C index c840907c4..5f406097e 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 5; + int checkPdgQuark{5}; int checkPdgHadron{4132}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C index c840907c4..5f406097e 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 5; + int checkPdgQuark{5}; int checkPdgHadron{4132}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C index be57c96e1..4ec473f52 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 5; + int checkPdgQuark{5}; int checkPdgHadron{4232}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C similarity index 77% rename from MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.C rename to MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C index 268a57174..58ef8cbf1 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C @@ -1,10 +1,10 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 4; + int checkPdgQuark{4}; int checkPdgHadron{4332}; - int checkHadronDecays{3334}; + int checkHadronDecays{0}; TFile file(path.c_str(), "READ"); if (file.IsZombie()) { @@ -19,7 +19,7 @@ int External() { tree->SetBranchAddress("MCEventHeader.", &eventHeader); int nEventsInj{}; - int nQuarks{}, nSignals{}, nSignalGoodDecay{}; + int nQuarks{}, nSignals{}; auto nEvents = tree->GetEntries(); for (int i = 0; i < nEvents; i++) { @@ -44,10 +44,8 @@ int External() { nSignals++; // count signal PDG for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { - auto pdgDau = tracks->at(j).GetPdgCode(); - if (std::abs(pdgDau) == checkHadronDecays) { - nSignalGoodDecay; - break; + if (j >= 0) { + checkHadronDecays += 1; } } } @@ -59,7 +57,7 @@ int External() { std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; std::cout <<"# signal hadrons: " << nSignals << "\n"; - std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; if (nEventsInj < nEvents) { std::cerr << "Number of generated events with triggered events different than expected\n"; @@ -76,9 +74,8 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (it should not happen, but to be conservative) - std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + if (checkHadronDecays > 0) { + std::cerr << "Decayed OmegaC, it should never decay\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C index dc5ba9604..81ea759b2 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 4; + int checkPdgQuark{4}; int checkPdgHadron{4332}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C index 9f999d474..e2f818fb2 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C @@ -6,8 +6,17 @@ int External() { std::vector checkPdgHadron{4132, 4232}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}} // Xic+ + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -65,6 +74,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C index caf5fd98f..b05f61cda 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 4; + int checkPdgQuark{4}; int checkPdgHadron{4132}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C index caf5fd98f..b05f61cda 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 4; + int checkPdgQuark{4}; int checkPdgHadron{4132}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C index e386c8a8b..f595aadd8 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 4; + int checkPdgQuark{4}; int checkPdgHadron{4232}; int checkHadronDecays{0}; From a9ace7471e18cfc3b76acabcd416354d851e7a25 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 3 Oct 2025 12:51:09 +0200 Subject: [PATCH 122/362] O2DPG: Fix vertex inconsistency between background and signal MC events Fixes https://its.cern.ch/jira/browse/O2-6368. The background events still sampled the vertex position from CCDB while it should have taken it from the pregenerated collision context. This commit rectifies this. --- MC/bin/o2dpg_sim_workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 3972c577a..d54fce527 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -714,7 +714,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): + ' -g ' + str(GENBKG) + ' ' + str(MODULES) + ' -o bkg ' + str(INIBKG) \ + ' --field ccdb ' + str(CONFKEYBKG) \ + ('',' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) \ - + ' --vertexMode kCCDB' \ + + ' --vertexMode ' + vtxmode_sgngen \ + ' --fromCollContext collisioncontext.root:bkg ' \ + ' --detectorList ' + args.detectorList From 83b2c5a4cb5799b1fa3b13a163bfd98a1ac21a0c Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 3 Oct 2025 13:28:40 +0200 Subject: [PATCH 123/362] cleanup unused env var --- MC/run/ANCHOR/anchorMC.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 19973eb23..a81df913b 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -294,8 +294,6 @@ fi # -- CREATE THE MC JOB DESCRIPTION ANCHORED TO RUN -- MODULES="--skipModules ZDC" -# Since this is used, set it explicitly -ALICEO2_CCDB_LOCALCACHE=${ALICEO2_CCDB_LOCALCACHE:-$(pwd)/ccdb} # publish MCPRODINFO for first few jobs of a production # if external script exported PUBLISH_MCPRODINFO, it will be published anyways From b26d718940278407904c2c9d98d688c9c70b5adc Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 3 Oct 2025 13:46:19 +0200 Subject: [PATCH 124/362] O2DPG-MC: Adding more utilities for pipeline metric aggregation/processing * possibility to extract aggegrated metrics from existing MC productions on the GRID * little server prototype that could aggregate metrics via a REST API in real time * small jq templates to have a top-N consumer summary --- MC/utils/metrics/README.md | 3 + MC/utils/metrics/metrics_harvester.py | 224 ++++++++++++++++++++++++++ MC/utils/metrics/server.py | 92 +++++++++++ MC/utils/metrics/top_metrics.sh | 31 ++++ 4 files changed, 350 insertions(+) create mode 100644 MC/utils/metrics/README.md create mode 100644 MC/utils/metrics/metrics_harvester.py create mode 100644 MC/utils/metrics/server.py create mode 100644 MC/utils/metrics/top_metrics.sh diff --git a/MC/utils/metrics/README.md b/MC/utils/metrics/README.md new file mode 100644 index 000000000..38043aade --- /dev/null +++ b/MC/utils/metrics/README.md @@ -0,0 +1,3 @@ +Set of scripts and utilities for the creation and processing +of workflow metrics (CPU, memory, walltime) for tasks executed +in o2dpg_workflow_runner.py and derived from its pipeline_metric*.log monitoring. \ No newline at end of file diff --git a/MC/utils/metrics/metrics_harvester.py b/MC/utils/metrics/metrics_harvester.py new file mode 100644 index 000000000..30585ed26 --- /dev/null +++ b/MC/utils/metrics/metrics_harvester.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python3 + +# A python tool, that calculates mean O2DPG workflow metrics by +# harvesting from data from pipeline_metric files from the GRID (for a given lpm production tag). + +import json +import subprocess +from collections import defaultdict +import re +import os +import argparse +import random +from pathlib import Path +import sys +import time +from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed + +# add the parent directory of the current file to sys.path to find the o2dpg_sim_metric +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +from o2dpg_sim_metrics import json_stat_impl + +def alien_find(path, pattern="*", logging=False): + cmd = ["alien.py", "find", path, pattern] + if logging: + print (f"Performing {cmd}") + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + return [line.strip() for line in result.stdout.splitlines() if line.strip()] + + +def alien_cp(alien_path, local_path, parent=None, fatal=False, logging=False): + cmd = ["alien.py", "cp"] + if parent != None: + cmd = cmd + ["-parent", f"{parent}"] + cmd = cmd + [f"alien://{alien_path}", f"file://{local_path}"] + if logging: + print (f"Performing {cmd}") + try: + subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) + except subprocess.CalledProcessError as e: + pass + +def alien_cp_inputfile(inputfile, logging=False): + cmd = ["alien.py", "cp", "-input", f"{inputfile}"] + if logging: + print (f"Performing {cmd}") + subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) + +def parse_workflow_path(path, prod_tag): + parts = path.strip("/").split("/") + try: + idx = parts.index(prod_tag) + except ValueError: + return None + + after = parts[idx + 1 :] + if len(after) < 2: + return None + + if after[0].isdigit() and len(after[0]) == 1: + cycle = int(after[0]) + run_number = int(after[1]) + split = after[2] + else: + cycle = None + run_number = int(after[0]) + split = after[1] + + return cycle, run_number, split + + +def calculate_statistics(selecteddirs, prod_tag, run_number, batchcopy = False): + """ + downloads the metrics files and calculates aggregates statistics + """ + targetdir = f"/tmp/o2dpg_metrics_harvester/{prod_tag}/{run_number}" + if not os.path.exists(targetdir): + os.makedirs(targetdir) + + start=time.time() + # determine target dir based on tag and run_number + if batchcopy == True: + # make an inputfile + inputfile = f"{targetdir}/cp_input.list" + with open(inputfile,'w') as f: + for dir in selecteddirs: + path = Path(dir) + # Get the last 1 components --> mimics -parent which does not work with inputlists + last_N = Path(*path.parts[-1:]) + f.write(f"{dir}/pipeline_metr* file:{targetdir}/{last_N}\n") + + # copy with the input-file + alien_cp_inputfile(inputfile, logging=True) + + else: + for dir in selecteddirs: + # avoid copy if we can ! + # we need to keep 2-top level dirs + alien_cp(f"{dir}/pipeline_metr*", targetdir, parent=1) + + end=time.time() + print(f"Copy took {end-start:.4f} seconds") + + # construct the list of all inputfiles + input_files = [str(p) for p in Path(targetdir).rglob('pipeline_metr*')] + print(input_files) + + # calculate the stats with all the files in targetdir + outputfilename=f"{targetdir}/merged_metrics.json" + meta_info = {"prod-tag" : prod_tag, "run-number" : run_number} + json_stat_impl(input_files, outputfilename, meta_info) + +import os +from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor + +def treat_parallel(func, data, use_threads=False, max_workers=None): + """ + Apply `func` to each element of `data` in parallel. + + Parameters + ---------- + func : callable + The function to apply to each element. + data : iterable + The data to process. + use_threads : bool, default=False + If True, use threads (good for I/O-bound tasks). + If False, use processes (good for CPU-bound tasks). + max_workers : int, optional + Number of workers to use. Defaults to number of CPUs for processes. + + Returns + ------- + list + The results in the same order as `data`. + """ + if max_workers is None: + max_workers = os.cpu_count() if not use_threads else min(32, os.cpu_count() * 5) + + Executor = ThreadPoolExecutor if use_threads else ProcessPoolExecutor + + # --- Use map to preserve order --- + with Executor(max_workers=max_workers) as executor: + results = list(executor.map(func, data)) + + return results + +def treat_one_run(data_element): + """ + The final worker function to execute for each run. + Expects it's input parameters in a list to work well with Thread/ProcessExecutor and treat_parallel above. + + data_element should be a tuple, where + index 0 --> the run_number + index 1 --> a list of tuples(cycle, split, directory) + index 2 --> production tag + index 3 --> sample_size + """ + run_number, candidates = data_element[0], data_element[1] + prod_tag = data_element[2] + sample_size = data_element[3] + universe = [ w[2] for w in candidates ] + selected_dirs = random.sample(universe, min(len(universe), sample_size)) + print (f"For {run_number} selected {selected_dirs}") + calculate_statistics(selected_dirs, prod_tag, run_number, batchcopy=True) + + +def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None, overwrite=False, samplesize=20): + base_path = f"/alice/sim/{year}/{prod_tag}" + + pipelinemetric_files = alien_find(base_path, "pipeline_metric*") + + # exclude some unnecessary paths + pipelinemetric_files = [ + zf for zf in pipelinemetric_files + if "/AOD/" not in zf and "/QC/" not in zf and "/TimeseriesTPCmerging/" not in zf and "/Stage" not in zf + ] + print (f"Found {len(pipelinemetric_files)} pipeline metric files") + + # directories containing workflow.json + workflow_dirs = {os.path.dirname(wf) for wf in pipelinemetric_files} + print (f"Found {len(workflow_dirs)} workflow dirs") + + # Step 2: group by run_number + runs = defaultdict(list) + for dir in workflow_dirs: + parsed = parse_workflow_path(dir, prod_tag) + if parsed is None: + continue + cycle, run_number, split = parsed + runs[run_number].append((cycle, split, dir)) + print(f"Found {len(runs)} run numbers") + + # Step 3: for each run_number, pick samplesize files for the final calculation + # for run_number, candidates in sorted(runs.items()): + # universe = [ w[2] for w in candidates ] + # selected_dirs = random.sample(universe, min(len(universe), samplesize)) + # print (f"For {run_number} selected {selected_dirs}") + + # # calculate merged statistics from the sample + # calculate_statistics(selected_dirs, prod_tag, run_number, batchcopy=False) + + data = [ (d[0], d[1], prod_tag, samplesize) for d in sorted(runs.items()) ] + do_parallel = True + if do_parallel == True: + treat_parallel(treat_one_run, data, use_threads=False, max_workers=8) + else: + for data_element in data: + treat_one_run(data_element) + +def main(): + parser = argparse.ArgumentParser( + description="Harvest MC metrics from AlienGRID; aggregate; and publish to CCDB" + ) + parser.add_argument("--prod_tag", required=True, help="Production tag (e.g. prod2025a)") + parser.add_argument("--ccdb", required=False, default="https://alice-ccdb.cern.ch", help="CCDB server URL") + parser.add_argument("--username", required=False, help="GRID username (needs appropriate AliEn token initialized)") + parser.add_argument("--year", default="2025", help="Production year (default: 2025)") + parser.add_argument("--overwrite", action="store_true", help="Overwrite existing entries") + args = parser.parse_args() + + process_prod_tag(args.prod_tag, year=args.year, ccdb_url=args.ccdb, username=args.username, overwrite=args.overwrite) + +if __name__ == "__main__": + main() diff --git a/MC/utils/metrics/server.py b/MC/utils/metrics/server.py new file mode 100644 index 000000000..6c768c961 --- /dev/null +++ b/MC/utils/metrics/server.py @@ -0,0 +1,92 @@ + +# A simple HTTPS server with an endpoint on which +# callers can inject O2DPG_workflow_runner stat json metrics. +# The service is supposed to run as aggregator of these individual metrics +# and to provide high-quality merged statistics on resource estimates. These +# estimates can then be used to improve the scheduling of o2dpg_workflow_runner workflows. + +from fastapi import FastAPI +from pydantic import BaseModel +from asyncio import Queue, create_task +import asyncio, json, time +import aiofiles +from fastapi import Request + +import sys, os + +# add the parent directory of the current file to sys.path to find the o2dpg_sim_metric +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +from o2dpg_sim_metrics import merge_stats_into + +app = FastAPI() +queue = Queue() +agg = {} # {(metric_name): {"sum": 0.0, "count": 0}} +flush_interval = 5 # seconds +outfile = "metrics.json" + +# Global state +agg_by_tag = {} # { production_tag: cached_result } + + +@app.post("/metric") +async def receive_metric(request : Request): + # just enqueue, return quickly + payload = await request.json() + await queue.put(payload) + return {"status": "ok"} + +def init_cache(): + """ + Initializes the cache of results from files + """ + pass + +def flush_to_disc(tag): + """ + flushes result for tag to disc + """ + metrics = agg_by_tag.get(tag, {}) + filename = f"aggr_metrics_tag_{tag}.json" + with open(filename, 'w') as f: + json.dump(metrics, f) + +async def worker(): + """ + Function performing the metrics aggregation + """ + while True: + payload = await queue.get() + + # Extract production-tag from metadata + meta = payload.get("meta-data", {}) + tag = meta.get("production-tag", "default") + + print (f"Worker is treating payload for tag {tag}") + + current = agg_by_tag.get(tag, {}) # fetch existing aggregate + updated = merge_stats_into([payload, current], None, meta) # merge new payload with cached + agg_by_tag[tag] = updated # store back in cache + + flush_to_disc(tag) + + queue.task_done() + + +async def flusher(): + while True: + await asyncio.sleep(flush_interval) + snapshot = { + k: (v["sum"] / v["count"]) if v["count"] else 0 + for k, v in agg.items() + } + async with aiofiles.open(outfile, "w") as f: + await f.write(json.dumps(snapshot, indent=2)) + print(f"Flushed {len(snapshot)} metrics at {time.ctime()}") + + +@app.on_event("startup") +async def startup(): + # start multiple workers for parallelism + for _ in range(8): # one per CPU core + create_task(worker()) + # create_task(flusher()) diff --git a/MC/utils/metrics/top_metrics.sh b/MC/utils/metrics/top_metrics.sh new file mode 100644 index 000000000..5f9e748ae --- /dev/null +++ b/MC/utils/metrics/top_metrics.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# a simple top-N metrics query for a couple of examples using jq +# assumes JSON produced by o2dpg_sim_metrics.py + +# top CPU-time consumers +jq 'to_entries + | map(select(.value.cpu?.mean != null and .value.lifetime?.mean != null)) + | sort_by(-(.value.cpu.mean * .value.lifetime.mean)) + | .[:5] + | map({name: .key, + cpu_mean: .value.cpu.mean, + lifetime_mean: .value.lifetime.mean, + product: (.value.cpu.mean * .value.lifetime.mean)})' merged_metrics.json + +# top mem consumers + + +# top cpu consumers +jq 'to_entries + | map(select(.value.cpu?.mean != null)) + | sort_by(-.value.cpu.mean) + | .[:5] + | map({name: .key, cpu_mean: .value.cpu.mean})' + +# top walltime consumers +jq 'to_entries + | map(select(.value.lifetime?.mean != null)) + | sort_by(-.value.lifetime.mean) + | .[:5] + | map({name: .key, lifetime_mean: .value.lifetime.mean})' \ No newline at end of file From 740d94eccb40fe2f9ccc8e827fc46df8e376b884 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 3 Oct 2025 08:48:52 +0200 Subject: [PATCH 125/362] Fix of an environment problem affecting 2stage processing Under certain conditions, the environment for tasks running under an alternative (2nd-stage) software tag lacked variables from the global-init section. This affected for instance the CCDB caching and led to inconsistent MC workflows. This is now fixed with this commit. Thanks to @shahor02 for finding the issue. --- MC/bin/o2_dpg_workflow_runner.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index a9fbb28b4..229125c3c 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -1029,6 +1029,12 @@ def __init__(self, workflowfile, args, jmax=100): self.do_early_file_removal = True self.file_removal_candidates = filegraph_expand_timeframes(filegraph_data, self.timeframeset, self.full_target_namelist) + def apply_global_env(self, environ_dict): + for e in self.globalinit['env']: + if environ_dict.get(e, None) == None: + value = self.globalinit['env'][e] + actionlogger.info("Applying global environment from init section " + str(e) + " : " + str(value)) + environ_dict[e] = str(value) def perform_early_file_removal(self, taskids): """ @@ -1259,9 +1265,13 @@ def submit(self, tid, nice): if self.workflowspec['stages'][tid].get('env')!=None: taskenv.update(self.workflowspec['stages'][tid]['env']) - # envfilename = "taskenv_" + str(tid) + ".json" - # with open(envfilename, "w") as file: - # json.dump(taskenv, file, indent=2) + # add global workflow environment + self.apply_global_env(taskenv) + + if os.environ.get('PIPELINE_RUNNER_DUMP_TASKENVS') != None: + envfilename = "taskenv_" + str(tid) + ".log" + with open(envfilename, "w") as file: + json.dump(taskenv, file, indent=2) p = psutil.Popen(['/bin/bash','-c',c], cwd=workdir, env=taskenv) try: From c1e84c1f1d320e2f89f6aae4f37fc4c232c44e8b Mon Sep 17 00:00:00 2001 From: arvindkhuntia <31609955+arvindkhuntia@users.noreply.github.com> Date: Fri, 10 Oct 2025 12:55:54 +0200 Subject: [PATCH 126/362] ini file for OO nuclei-injected (#2155) * ini file for OO nuclei-injected * test macro added --------- Co-authored-by: Arvind Khuntia --- .../PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini | 6 ++ .../ini/tests/GeneratorLFHyperNucleiOOGap.C | 58 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiOOGap.C diff --git a/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini new file mode 100644 index 000000000..b960ffe3a --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C +funcName=generateLongLivedGapTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun", 1) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiOOGap.C b/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiOOGap.C new file mode 100644 index 000000000..0f51674fb --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiOOGap.C @@ -0,0 +1,58 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector possiblePDGs = {1000010020, -1000010020, + 1000010030, -1000010030, + 1000020030, -1000020030, + 1000020040, -1000020040, + 1010010030, -1010010030, + 1010010040, -1010010040}; + + int nPossiblePDGs = possiblePDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector injectedPDGs; + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(possiblePDGs.begin(), possiblePDGs.end(), pdg); + if (it != possiblePDGs.end() && track.isPrimary()) // found + { + injectedPDGs.push_back(pdg); + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + if(injectedPDGs.empty()){ + std::cerr << "No injected particles\n"; + return 1; // At least one of the injected particles should be generated + } + for (int i = 0; i < nPossiblePDGs; i++) + { + std::cout << "# Injected nuclei \n"; + std::cout << possiblePDGs[i] << ": " << std::count(injectedPDGs.begin(), injectedPDGs.end(), possiblePDGs[i]) << "\n"; + } + return 0; +} From 58270d6f5f9cdb42fbabae444f910579519d244b Mon Sep 17 00:00:00 2001 From: Chuntai <48704924+wuctlby@users.noreply.github.com> Date: Fri, 10 Oct 2025 16:30:54 +0200 Subject: [PATCH 127/362] add `ini`, `cfg` config files and test macro for OO collision (#2157) --- ...torHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini | 8 + ...ratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C | 189 +++++++++++ ...hia8_charmhadronic_with_decays_SCCR_OO.cfg | 299 ++++++++++++++++++ 3 files changed, 496 insertions(+) create mode 100755 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini new file mode 100755 index 000000000..080a6c2b0 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(2, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C new file mode 100644 index 000000000..5cc0e18e6 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C @@ -0,0 +1,189 @@ +int External(std::string path = "o2sim_Kine.root") { + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./2; // one event triggered out of 2 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = float(nSignalGoodDecay) / nSignals; + if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg new file mode 100644 index 000000000..ab5e02f46 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg @@ -0,0 +1,299 @@ +# Pythia8 configuration file for charm hadronic production in OO collisions at 5.36 TeV + +### beams +Beams:idA 1000080160 # Oxygen +Beams:idB 1000080160 # Oxygen +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +Beams:frameType 1 +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen 0 +HeavyIon:SigFitDefPar 2.15,18.42,0.33 + +Random:setSeed on + +### switching on spatially constrained QCD colour reconnection (SC-CR) mode +ColourReconnection:mode = 1 +ColourReconnection:timeDilationMode = 0 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 1.05 +ColourReconnection:allowJunctions = on +ColourReconnection:lambdaForm = 1 +ColourReconnection:mPseudo = 1.05 +ColourReconnection:junctionCorrection = 1.37 +ColourReconnection:dipoleMaxDist = 0.5 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.4 +StringFlav:probQQ1toQQ0join = 0.5,0.7,0.9,1.0 +MultiPartonInteractions:pT0Ref = 2.37 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation = 5 +BeamRemnants:beamJunction = on +ColourReconnection:heavyLambdaForm = 1 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +# HF decays +### BR are set to yield 50% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (50%) +421:oneChannel = 1 0.50000 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (12.50%) +421:addChannel = 1 0.00625 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.08750 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.01250 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.01875 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (12.50%) +421:addChannel = 1 0.12500 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (12.50%) +421:addChannel = 1 0.08750 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.03750 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (12.50%) +421:addChannel = 1 0.12500 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (50%) +411:oneChannel = 1 0.40189 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +411:addChannel = 1 0.05356 0 -10311 211 ### D+ -> antiK*0(1430) π+ 1.25% +411:addChannel = 1 0.04455 0 -313 211 ### D+ -> K*0(892) pi+ 1.04% +### D+ -> K- π+ π+ π0 (small, 3%) +411:addChannel = 1 0.03000 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (36.00%, set 25% for D+ -> φ π+, 11% for the rest) +411:addChannel = 1 0.25000 0 333 211 ### D+ -> φ π+ 2.69e-3 !needed for signal +411:addChannel = 1 0.03929 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.02865 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.04206 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (11.00%) +411:addChannel = 1 0.02911 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.01618 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.06471 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (50%) +431:oneChannel = 1 0.50000 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.15000 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 2%) +431:addChannel = 1 0.02000 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (11.00%) +431:addChannel = 1 0.00220 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.00220 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.10560 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (11.00%) +431:addChannel = 1 0.03080 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.02200 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.03960 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.01760 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (11.00%) +431:addChannel = 1 0.11000 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 + +### add OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 +### rho0 -> π+ π- +113:onMode = off +113:onIfAll = 211 211 +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +3122:onMode = off +3122:onIfAll = 2212 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 + +# switch off all decay channels +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4232:onMode = off +4132:onMode = off +443:onMode = off +4332:onMode = off + +# Allow the decay of HF +### D0 -> K π +421:onIfMatch = 321 211 +### D0 -> K π π0 +421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 + +### D+/- -> K π π +411:onIfMatch = 321 211 211 +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* π +411:onIfMatch = 313 211 +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 211 +### D+/- -> antiK* K +411:onIfMatch = 10311 321 +### D+/- -> φ π +411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 + +### Ds -> φ π +431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 + +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 \ No newline at end of file From 355a532577bc78b143f6682388743bc5e2d78aee Mon Sep 17 00:00:00 2001 From: arvindkhuntia <31609955+arvindkhuntia@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:29:02 +0200 Subject: [PATCH 128/362] Added OO-Gun for nuclei and hypernuclei (#2158) * ini file for OO nuclei-injected * corrected the format * test macro added * Added OO-Gun for nuclei and hypernuclei --------- Co-authored-by: Arvind Khuntia --- MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini | 4 ++-- MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun diff --git a/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini index b960ffe3a..2c2477aab 100644 --- a/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini +++ b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C -funcName=generateLongLivedGapTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun", 1) +funcName=generateLongLivedGapTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun", 1) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun b/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun new file mode 100644 index 000000000..66ba2dc0f --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun @@ -0,0 +1,10 @@ +# PDG N ptMin ptMax yMin yMax +1000010020 2 0.2 10 -1 1 +1000010030 2 0.2 10 -1 1 +1000020030 2 0.2 10 -1 1 +1000020040 2 0.2 10 -1 1 +1010010030 2 0.2 10 -1 1 +1010010040 2 0.2 10 -1 1 +1010020040 2 0.2 10 -1 1 +1010000030 1 0.2 10 -1 1 +1000030040 1 0.2 10 -1 1 \ No newline at end of file From 142f7696b11b3110b64f2abe90c4f1b8de222843 Mon Sep 17 00:00:00 2001 From: Lubos Krcal Date: Thu, 16 Oct 2025 14:56:02 +0200 Subject: [PATCH 129/362] Remove special staging partitions from epn-topo-alloc --- DATA/tools/epn/gen_topo.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/DATA/tools/epn/gen_topo.sh b/DATA/tools/epn/gen_topo.sh index 79c4a5db4..0a90ab1da 100755 --- a/DATA/tools/epn/gen_topo.sh +++ b/DATA/tools/epn/gen_topo.sh @@ -41,11 +41,7 @@ fi # Extra arguments for topology merger if [[ -z "$GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS" ]]; then - if [[ "${GEN_TOPO_DEPLOYMENT_TYPE:-}" == "ALICE_STAGING" ]]; then - export GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS="--recozone staging-mi50 --reco100zone staging-mi100 --calibzone calib" - else - export GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS="--recozone online-mi50 --reco100zone online-mi100 --calibzone calib" - fi + export GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS="--recozone online-mi50 --reco100zone online-mi100 --calibzone calib" fi if [[ -z "$GEN_TOPO_MI100_NODES" ]]; then export GEN_TOPO_MI100_NODES=-1; fi From f7eb97c1bc1986447819cc6b87b16b472995b75d Mon Sep 17 00:00:00 2001 From: sgaretti <129837066+sgaretti@users.noreply.github.com> Date: Mon, 20 Oct 2025 14:45:49 +0200 Subject: [PATCH 130/362] [PWGDQ] New ini file with Trigger Ratio = 2 (#2162) * [PWGDQ] New ini file with TriggerRatio = 2 Testing new TriggerRatio using 2 instead of 5 * [PWGDQ] New test file to test TriggerRatio = 2 Adding new test file since a new ini file has been created to test TriggerRatio = 2 --- ...Fwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini | 9 ++ ...iaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C | 85 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini new file mode 100644 index 000000000..d3611a518 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(2,7) + +[GeneratorPythia8] +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hi.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C new file mode 100644 index 000000000..e88864af3 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From aef777fc5d9ab65e652c6e98c1ac449975a4e626 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 21 Oct 2025 11:29:19 +0200 Subject: [PATCH 131/362] 2tag: Correctly restore user-overwritten O2DPG env vars --- MC/run/ANCHOR/anchorMC.sh | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index a81df913b..9bc591704 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -198,12 +198,12 @@ fi #<----- START OF part that should run under a clean alternative software environment if this was given ------ if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then if [ "${LOADEDMODULES}" ]; then - export > env_before_stashing.env + printenv > env_before_stashing.printenv echo "Stashing initial modules" module save initial_modules.list # we stash the current modules environment module list --no-pager module purge --no-pager - export > env_after_stashing.env + printenv > env_after_stashing.printenv echo "Modules after purge" module list --no-pager fi @@ -272,10 +272,17 @@ if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then echo "Restoring initial environment" module --no-pager restore initial_modules.list module saverm initial_modules.list - if [ "${ALIEN_JDL_O2DPG_OVERWRITE}" ]; then - echo "Setting back O2DPG_ROOT to overwritten path ${ALIEN_JDL_O2DPG_OVERWRITE}" - export O2DPG_ROOT=${ALIEN_JDL_O2DPG_OVERWRITE} - fi + + # Restore overwritten O2DPG variables set by modules but changed by user + # (in particular custom O2DPG_ROOT and O2DPG_MC_CONFIG_ROOT) + printenv > env_after_restore.printenv + comm -12 <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ + <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort) | + while read -r var; do + b=$(grep "^$var=" env_before_stashing.printenv | cut -d= -f2-) + a=$(grep "^$var=" env_after_restore.printenv | cut -d= -f2-) + [[ "$b" != "$a" ]] && export "$var=$b" && echo "Reapplied: $var to ${b}" + done fi #<----- END OF part that should run under a clean alternative software environment if this was given ------ From 8ccc9996f84a8aaf5cb5bce1414adb2d7d9d20cd Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Sun, 5 Oct 2025 13:59:58 +0200 Subject: [PATCH 132/362] Fix a quoting problem related to CCDB remapping The CCDB remapping arguments appeared sometimes correctly quoted and in some cases not. This is because the task_finalizer reapplied string construction/quoting which was not generic enough. This is fixed with this commit. In addition, we now automatically quote ALIEN_JDL_REMAPPING if needed. Both versions ``` export ALIEN_JDL_REMAPPING="foo;bar" ``` as well as (quoted) ``` export ALIEN_JDL_REMAPPING='"foo;bar"' ``` will work. It is recommended to just use the former. --- MC/bin/o2dpg_dpl_config_tools.py | 23 +++++++++++++++++------ MC/bin/o2dpg_sim_workflow.py | 4 ++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/MC/bin/o2dpg_dpl_config_tools.py b/MC/bin/o2dpg_dpl_config_tools.py index 26dbfbf86..388e4306f 100755 --- a/MC/bin/o2dpg_dpl_config_tools.py +++ b/MC/bin/o2dpg_dpl_config_tools.py @@ -161,6 +161,23 @@ def log_line(logger, message): else: logger.write(message + "\n") +def quote_for_nested_string(val): + s = str(val) + # Already double-quoted? + if s.startswith('"') and s.endswith('"'): + return s + # Escape inner quotes + s_escaped = s.replace('"', r'\"') + return f'"{s_escaped}"' + +def quote_if_needed(val): + # Only quote values that are likely to break shell parsing + # or contain nested shell-sensitive characters + s = str(val) + if re.search(r'[ \t;:&|<>]', s): + return quote_for_nested_string(s) + return s + def modify_dpl_command(cmd_str, config_anchor, allow_overwrite=False, logger=None, configname=None): # check if cmd_str is given as list, in which case we transfrom to string if isinstance(cmd_str, list) == True: @@ -196,12 +213,6 @@ def modify_dpl_command(cmd_str, config_anchor, allow_overwrite=False, logger=Non added = [] overwritten = [] - def quote_if_needed(val): - s = str(val) - if " " in s and not (s.startswith('"') and s.endswith('"')): - return f'"{s}"' - return s - # Step 1: Existing options (preserved or overwritten) for key, val in existing_opts.items(): if allow_overwrite and key in anchor_opts: diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index d54fce527..5431429a3 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -43,7 +43,7 @@ from o2dpg_workflow_utils import createTask, createGlobalInitTask, dump_workflow, adjust_RECO_environment, isActive, activate_detector, deactivate_detector, compute_n_workers, merge_dicts from o2dpg_qc_finalization_workflow import include_all_QC_finalization from o2dpg_sim_config import create_sim_config, create_geant_config, constructConfigKeyArg, option_if_available, overwrite_config -from o2dpg_dpl_config_tools import parse_command_string, modify_dpl_command, dpl_option_from_config, TaskFinalizer +from o2dpg_dpl_config_tools import dpl_option_from_config, TaskFinalizer, quote_if_needed # for some JAliEn interaction from alienpy.alien import JAlien @@ -504,7 +504,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): if ccdbbackend: common=common + " --condition-not-after " + str(args.condition_not_after) if ccdbRemap != None: - common=common + " --condition-remap " + ccdbRemap + common=common + f" --condition-remap {quote_if_needed(ccdbRemap)} " if args.noIPC!=None: return common + " --no-IPC " if bigshm: From bdef5343d55465975cb777859e39bf50fe749385 Mon Sep 17 00:00:00 2001 From: MasahiroOida-HU <135219490+MasahiroOida-HU@users.noreply.github.com> Date: Thu, 23 Oct 2025 19:51:43 +0900 Subject: [PATCH 133/362] extend total momentum range embedding LF mesons (#2168) --- .../generator/Generator_pythia8_GapTriggered_LFmumu.C | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C index 16bff075a..5fb499d0a 100644 --- a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C @@ -71,7 +71,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // eta auto geneta = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kEta,"eta"); // 221 geneta->SetName("eta"); - geneta->SetMomentumRange(0., 25.); + geneta->SetMomentumRange(0., 200.); geneta->SetPtRange(minPt, maxPt); geneta->SetYRange(yMin, yMax); geneta->SetPhiRange(phiMin, phiMax); @@ -86,7 +86,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // etaprime auto genetaprime = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kEtaprime,"etaprime"); // 331 genetaprime->SetName("etaprime"); - genetaprime->SetMomentumRange(0., 25.); + genetaprime->SetMomentumRange(0., 200.); genetaprime->SetPtRange(minPt, maxPt); genetaprime->SetYRange(yMin, yMax); genetaprime->SetPhiRange(phiMin, phiMax); @@ -101,7 +101,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // rho auto genrho = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kRho0,"rho"); // 113 genrho->SetName("rho"); - genrho->SetMomentumRange(0., 25.); + genrho->SetMomentumRange(0., 200.); genrho->SetPtRange(minPt, maxPt); genrho->SetYRange(yMin, yMax); genrho->SetPhiRange(phiMin, phiMax); @@ -116,7 +116,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // Omega auto genomega = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kOmega,"omega"); //223 genomega->SetName("omega"); - genomega->SetMomentumRange(0., 25.); + genomega->SetMomentumRange(0., 200.); genomega->SetPtRange(minPt, maxPt); genomega->SetYRange(yMin, yMax); genomega->SetPhiRange(phiMin, phiMax); @@ -131,7 +131,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // phi auto genphi = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kPhi,"phi"); //333 genphi->SetName("phi"); - genphi->SetMomentumRange(0., 25.); + genphi->SetMomentumRange(0., 200.); genphi->SetPtRange(minPt, maxPt); genphi->SetYRange(yMin, yMax); genphi->SetPhiRange(phiMin, phiMax); From f5a77f0255dfad8e8b2acd751c0e2e91bf7878f8 Mon Sep 17 00:00:00 2001 From: Lubos Krcal Date: Tue, 21 Oct 2025 16:42:00 +0200 Subject: [PATCH 134/362] Move TfBuilder startup script to /usr/local/bin/tfbuilder.sh --- DATA/tools/datadistribution_workflows/dd-discard.xml | 2 +- DATA/tools/datadistribution_workflows/dd-disk.xml | 2 +- DATA/tools/datadistribution_workflows/dd-processing-disk.xml | 2 +- DATA/tools/datadistribution_workflows/dd-processing.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DATA/tools/datadistribution_workflows/dd-discard.xml b/DATA/tools/datadistribution_workflows/dd-discard.xml index 361e690cf..3a5178b63 100644 --- a/DATA/tools/datadistribution_workflows/dd-discard.xml +++ b/DATA/tools/datadistribution_workflows/dd-discard.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh standalone + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh standalone TfBuilderRequirement diff --git a/DATA/tools/datadistribution_workflows/dd-disk.xml b/DATA/tools/datadistribution_workflows/dd-disk.xml index 094c79c8f..9651e83f1 100644 --- a/DATA/tools/datadistribution_workflows/dd-disk.xml +++ b/DATA/tools/datadistribution_workflows/dd-disk.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh disk2G + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh disk2G TfBuilderRequirement diff --git a/DATA/tools/datadistribution_workflows/dd-processing-disk.xml b/DATA/tools/datadistribution_workflows/dd-processing-disk.xml index 005db63af..baa2fb917 100644 --- a/DATA/tools/datadistribution_workflows/dd-processing-disk.xml +++ b/DATA/tools/datadistribution_workflows/dd-processing-disk.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh disk2G_data + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh disk2G_data TfBuilderRequirement diff --git a/DATA/tools/datadistribution_workflows/dd-processing.xml b/DATA/tools/datadistribution_workflows/dd-processing.xml index cb6cd7c79..1e13d2023 100644 --- a/DATA/tools/datadistribution_workflows/dd-processing.xml +++ b/DATA/tools/datadistribution_workflows/dd-processing.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh data + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh data TfBuilderRequirement From f9064fc3bf118af8d2a9478c52eb72e06b175fc9 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Wed, 22 Oct 2025 19:41:55 +0200 Subject: [PATCH 135/362] parse script: allow to set min, max TF id for rawtf output and max number of TFs per rawtf file via env variables --- DATA/tools/parse | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/tools/parse b/DATA/tools/parse index 1234f426f..cf0335f3f 100755 --- a/DATA/tools/parse +++ b/DATA/tools/parse @@ -223,7 +223,7 @@ for line in f: odccommand += ' ' + os.environ['GEN_TOPO_ODC_EPN_TOPO_ARGS'] if True: replacestring = '' - dd_env_variables = ['DD_DISK_FRACTION', 'EPN_DD_TEST', 'EPN_DD_TEST_2', 'EPN_DD_TEST_3', 'SHM_MANAGER_SHMID'] + dd_env_variables = ['DD_DISK_FRACTION', 'TF_SINK_NUM_TFS', 'DD_STF_MIN_ID', 'DD_STF_MAX_ID', 'EPN_DD_TEST', 'EPN_DD_TEST_2', 'EPN_DD_TEST_3', 'SHM_MANAGER_SHMID'] for i in dd_env_variables: if i in os.environ: replacestring += ' ' + i + '=' + os.environ[i] From c6c80f9ae7d229a886040335f63ee37002bed22a Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Thu, 23 Oct 2025 23:57:29 +0200 Subject: [PATCH 136/362] Implemented loopers dependence on IR and collision system (#2171) --- .../common/external/generator/TPCLoopers.C | 149 ++++++++++++++++-- .../common/ini/GeneratorLoopersFlatFile.ini | 8 + 2 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 MC/config/common/ini/GeneratorLoopersFlatFile.ini diff --git a/MC/config/common/external/generator/TPCLoopers.C b/MC/config/common/external/generator/TPCLoopers.C index 2d2a0074b..98785732d 100644 --- a/MC/config/common/external/generator/TPCLoopers.C +++ b/MC/config/common/external/generator/TPCLoopers.C @@ -224,7 +224,8 @@ class GenTPCLoopers : public Generator LOG(debug) << "Current time offset wrt BC: " << mInteractionTimeRecords[mCurrentEvent].getTimeOffsetWrtBC() << " ns"; mTimeLimit = (mCurrentEvent < mInteractionTimeRecords.size() - 1) ? mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns() : mTimeEnd - mInteractionTimeRecords[mCurrentEvent].bc2ns(); // With flat gas the number of loopers are adapted based on time interval widths - nLoopers = mFlatGasNumber * (mTimeLimit / mIntTimeRecMean); + // The denominator is either the LHC orbit (if mFlatGasOrbit is true) or the mean interaction time record interval + nLoopers = mFlatGasOrbit ? (mFlatGasNumber * (mTimeLimit / o2::constants::lhc::LHCOrbitNS)) : (mFlatGasNumber * (mTimeLimit / mIntTimeRecMean)); nLoopersPairs = static_cast(std::round(nLoopers * mLoopsFractionPairs)); nLoopersCompton = nLoopers - nLoopersPairs; SetNLoopers(nLoopersPairs, nLoopersCompton); @@ -397,18 +398,28 @@ class GenTPCLoopers : public Generator } } - void setFlatGas(Bool_t &flat, const Int_t &number = -1) + void setFlatGas(Bool_t &flat, const Int_t &number = -1, const Int_t &nloopers_orbit = -1) { mFlatGas = flat; if (mFlatGas) { - if (number < 0) + if(nloopers_orbit > 0) { - LOG(warn) << "Warning: Number of loopers per event must be non-negative! Switching option off."; - mFlatGas = false; - mFlatGasNumber = -1; + mFlatGasOrbit = true; + mFlatGasNumber = nloopers_orbit; + LOG(info) << "Flat gas loopers will be generated using orbit reference."; } else { - mFlatGasNumber = number; + mFlatGasOrbit = false; + if (number < 0) + { + LOG(warn) << "Warning: Number of loopers per event must be non-negative! Switching option off."; + mFlatGas = false; + mFlatGasNumber = -1; + } else { + mFlatGasNumber = number; + } + } + if (mFlatGas){ mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr; mCollisionContext = mContextFile ? (o2::steer::DigitizationContext *)mContextFile->Get("DigitizationContext") : nullptr; mInteractionTimeRecords = mCollisionContext ? mCollisionContext->getEventRecords() : std::vector{}; @@ -425,9 +436,9 @@ class GenTPCLoopers : public Generator mIntTimeRecMean += mInteractionTimeRecords[c + 1].bc2ns() - mInteractionTimeRecords[c].bc2ns(); } mIntTimeRecMean /= (mInteractionTimeRecords.size() - 1); // Average interaction time record used as reference - const auto& hbfUtils = o2::raw::HBFUtils::Instance(); + const auto &hbfUtils = o2::raw::HBFUtils::Instance(); // Get the start time of the second orbit after the last interaction record - const auto& lastIR = mInteractionTimeRecords.back(); + const auto &lastIR = mInteractionTimeRecords.back(); o2::InteractionRecord finalOrbitIR(0, lastIR.orbit + 2); // Final orbit, BC = 0 mTimeEnd = finalOrbitIR.bc2ns(); LOG(debug) << "Final orbit start time: " << mTimeEnd << " ns while last interaction record time is " << mInteractionTimeRecords.back().bc2ns() << " ns"; @@ -435,7 +446,7 @@ class GenTPCLoopers : public Generator } else { mFlatGasNumber = -1; } - LOG(info) << "Flat gas loopers: " << (mFlatGas ? "ON" : "OFF") << ", Reference loopers number per event: " << mFlatGasNumber; + LOG(info) << "Flat gas loopers: " << (mFlatGas ? "ON" : "OFF") << ", Reference loopers number per " << (mFlatGasOrbit ? "orbit " : "event ") << mFlatGasNumber; } void setFractionPairs(float &fractionPairs) @@ -449,6 +460,45 @@ class GenTPCLoopers : public Generator LOG(info) << "Pairs fraction set to: " << mLoopsFractionPairs; } + void SetRate(const std::string &rateFile, const bool isPbPb = true, const int &intRate = 50000) + { + // Checking if the rate file exists and is not empty + TFile rate_file(rateFile.c_str(), "READ"); + if (!rate_file.IsOpen() || rate_file.IsZombie()) + { + LOG(fatal) << "Error: Rate file is empty or does not exist!"; + exit(1); + } + const char* fitName = isPbPb ? "fitPbPb" : "fitpp"; + auto fit = (TF1 *)rate_file.Get(fitName); + if (!fit) + { + LOG(fatal) << "Error: Could not find fit function '" << fitName << "' in rate file!"; + exit(1); + } + auto ref = static_cast(std::floor(fit->Eval(intRate / 1000.))); // fit expects rate in kHz + rate_file.Close(); + if (ref <= 0) + { + LOG(fatal) << "Computed flat gas number reference per orbit is <=0"; + exit(1); + } else { + LOG(info) << "Set flat gas number to " << ref << " loopers per orbit using " << fitName << " from " << intRate << " Hz interaction rate."; + auto flat = true; + setFlatGas(flat, -1, ref); + } + } + + void SetAdjust(const float &adjust = 0.f) + { + if (mFlatGas && mFlatGasOrbit && adjust >= -1.f && adjust != 0.f) + { + LOG(info) << "Adjusting flat gas number per orbit by " << adjust * 100.f << "%"; + mFlatGasNumber = static_cast(std::round(mFlatGasNumber * (1.f + adjust))); + LOG(info) << "New flat gas number per orbit: " << mFlatGasNumber; + } + } + private: std::unique_ptr mONNX_pair = nullptr; std::unique_ptr mONNX_compton = nullptr; @@ -474,11 +524,13 @@ class GenTPCLoopers : public Generator o2::steer::DigitizationContext *mCollisionContext = nullptr; // Pointer to the digitization context std::vector mInteractionTimeRecords; // Interaction time records from collision context Bool_t mFlatGas = false; // Flag to indicate if flat gas loopers are used + Bool_t mFlatGasOrbit = false; // Flag to indicate if flat gas loopers are per orbit Int_t mFlatGasNumber = -1; // Number of flat gas loopers per event double mIntTimeRecMean = 1.0; // Average interaction time record used for the reference double mTimeLimit = 0.0; // Time limit for the current event double mTimeEnd = 0.0; // Time limit for the last event float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs + std::string mRateFile = ""; // File with clusters/rate information per orbit }; } // namespace eventgen @@ -562,7 +614,7 @@ FairGenerator * FairGenerator * Generator_TPCLoopersFlat(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", std::string scaler_pair = "scaler_pair.json", std::string scaler_compton = "scaler_compton.json", - bool flat_gas = true, const int loops_num = 500, float fraction_pairs = 0.08) + bool flat_gas = true, const int loops_num = 500, float fraction_pairs = 0.08, const int nloopers_orbit = -1) { // Expand all environment paths model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); @@ -624,6 +676,79 @@ Generator_TPCLoopersFlat(std::string model_pairs = "tpcloopmodel.onnx", std::str model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; auto generator = new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); generator->setFractionPairs(fraction_pairs); - generator->setFlatGas(flat_gas, loops_num); + generator->setFlatGas(flat_gas, loops_num, nloopers_orbit); return generator; } + +// Generator with flat gas loopers. Reference number of loopers is provided per orbit via external file +FairGenerator * +Generator_TPCLoopersOrbitRef(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string scaler_pair = "scaler_pair.json", std::string scaler_compton = "scaler_compton.json", + std::string nclxrate = "nclxrate.root", bool isPbPb = true, const int intrate = 38000, const float adjust = 0.f) +{ + // Expand all environment paths + model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); + model_compton = gSystem->ExpandPathName(model_compton.c_str()); + scaler_pair = gSystem->ExpandPathName(scaler_pair.c_str()); + scaler_compton = gSystem->ExpandPathName(scaler_compton.c_str()); + nclxrate = gSystem->ExpandPathName(nclxrate.c_str()); + const std::array models = {model_pairs, model_compton, nclxrate}; + const std::array local_names = {"WGANpair.onnx", "WGANcompton.onnx", "nclxrate.root"}; + const std::array isAlien = {models[0].starts_with("alien://"), models[1].starts_with("alien://"), nclxrate.starts_with("alien://")}; + const std::array isCCDB = {models[0].starts_with("ccdb://"), models[1].starts_with("ccdb://"), nclxrate.starts_with("ccdb://")}; + if (std::any_of(isAlien.begin(), isAlien.end(), [](bool v) + { return v; })) + { + if (!gGrid) + { + TGrid::Connect("alien://"); + if (!gGrid) + { + LOG(fatal) << "AliEn connection failed, check token."; + exit(1); + } + } + for (size_t i = 0; i < models.size(); ++i) + { + if (isAlien[i] && !TFile::Cp(models[i].c_str(), local_names[i].c_str())) + { + LOG(fatal) << "Error: Model file " << models[i] << " does not exist!"; + exit(1); + } + } + } + if (std::any_of(isCCDB.begin(), isCCDB.end(), [](bool v) + { return v; })) + { + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("http://alice-ccdb.cern.ch"); + for (size_t i = 0; i < models.size(); ++i) + { + if (isCCDB[i]) + { + auto model_path = models[i].substr(7); // Remove "ccdb://" + // Treat filename if provided in the CCDB path + auto extension = model_path.find(".onnx"); + if (extension != std::string::npos) + { + auto last_slash = model_path.find_last_of('/'); + model_path = model_path.substr(0, last_slash); + } + std::map filter; + if (!ccdb_api.retrieveBlob(model_path, "./", filter, o2::ccdb::getCurrentTimestamp(), false, local_names[i].c_str())) + { + LOG(fatal) << "Error: issues in retrieving " << model_path << " from CCDB!"; + exit(1); + } + } + } + } + model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; + model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; + nclxrate = isAlien[2] || isCCDB[2] ? local_names[2] : nclxrate; + auto generator = new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); + generator->SetRate(nclxrate, isPbPb, intrate); + // Adjust can be negative (-1 maximum) or positive to decrease or increase the number of loopers per orbit + generator->SetAdjust(adjust); + return generator; +} \ No newline at end of file diff --git a/MC/config/common/ini/GeneratorLoopersFlatFile.ini b/MC/config/common/ini/GeneratorLoopersFlatFile.ini new file mode 100644 index 000000000..285a7cb5b --- /dev/null +++ b/MC/config/common/ini/GeneratorLoopersFlatFile.ini @@ -0,0 +1,8 @@ +# TPC loopers injector using fit to calculate reference loopers number per orbit. File with fit function is pulled from the CCDB. +# Three additional parameters are available in the function: (isPbPb = true, intRate = 38000, adjust = 0.) +# isPbPb and intRate must be set in case the collision system is not PbPb at 38 kHz, while adjust can be used to decrease/increase +# the number of loopers per orbit obtained from the reference (e.g. -0.1 reduces the loopers by 10%) +#---> GeneratorTPCloopers +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/TPCLoopers.C +funcName = Generator_TPCLoopersOrbitRef("ccdb://Users/m/mgiacalo/WGAN_ExtGenPair", "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerPairParams.json", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerComptonParams.json","ccdb://Users/m/mgiacalo/ClustersTrackRatio") From bcbb58a87f0edee4a42a2249327d88a34b54fa73 Mon Sep 17 00:00:00 2001 From: shreyasiacharya <34233706+shreyasiacharya@users.noreply.github.com> Date: Mon, 27 Oct 2025 08:40:29 +0100 Subject: [PATCH 137/362] Prompt charmonia in OO midrapidity with traigger gap 2 (default was 5) (#2169) * Create Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini * Create Create Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C * Rename Create Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C to Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C --- ...romptCharmoniaMidy_TriggerGap_2_OO5TeV.ini | 7 ++ ...dPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C | 84 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini new file mode 100644 index 000000000..21ba911d3 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(2,12) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From a53f4c0e5d7c504458aae055b546e4633e80d0f5 Mon Sep 17 00:00:00 2001 From: iravasen Date: Tue, 21 Oct 2025 13:54:01 +0200 Subject: [PATCH 138/362] split vresetd 1d/2d processing due to different number of injections --- DATA/production/calib/its-threshold-processing.sh | 2 +- DATA/production/standalone-calibration.desc | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DATA/production/calib/its-threshold-processing.sh b/DATA/production/calib/its-threshold-processing.sh index 0859a7270..8bb2a6fdf 100755 --- a/DATA/production/calib/its-threshold-processing.sh +++ b/DATA/production/calib/its-threshold-processing.sh @@ -30,7 +30,7 @@ fi if [ $RUNTYPE_ITS == "tuningbb" ]; then ADDITIONAL_OPTIONS_CAL="--min-vcasn 30 --max-vcasn 130" fi -if [[ $RUNTYPE_ITS == "tot1row" || $RUNTYPE_ITS == "vresetd" ]]; then +if [[ $RUNTYPE_ITS == "tot1row" || $RUNTYPE_ITS == "vresetd-2d" ]]; then ADDITIONAL_OPTIONS_CAL="--ninj 10" fi if [ $RUNTYPE_ITS == "totfullfast" ]; then diff --git a/DATA/production/standalone-calibration.desc b/DATA/production/standalone-calibration.desc index 13ff741bc..ad69e8c6b 100644 --- a/DATA/production/standalone-calibration.desc +++ b/DATA/production/standalone-calibration.desc @@ -26,7 +26,9 @@ ITS-tot-1row: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=tot1row production/calib/its- ITS-tot-fullfast: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=totfullfast production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=totfullfast production/calib/its-threshold-aggregator.sh" -ITS-vresetd: "O2PDPSuite" reco,5,5,"RUNTYPE_ITS=vresetd production/calib/its-threshold-processing.sh" calib,5,"RUNTYPE_ITS=vresetd production/calib/its-threshold-aggregator.sh" +ITS-vresetd-1d: "O2PDPSuite" reco,5,5,"RUNTYPE_ITS=vresetd-1d production/calib/its-threshold-processing.sh" calib,5,"RUNTYPE_ITS=vresetd-1d production/calib/its-threshold-aggregator.sh" + +ITS-vresetd-2d: "O2PDPSuite" reco,5,5,"RUNTYPE_ITS=vresetd-2d production/calib/its-threshold-processing.sh" calib,5,"RUNTYPE_ITS=vresetd-2d production/calib/its-threshold-aggregator.sh" TOF-diagnostic-calibration: "O2PDPSuite" reco,10,10,"SHMSIZE=120376524800 production/calib/tof-standalone-reco.sh" calib,4,"production/calib/tof-diagn-aggregator.sh" From 759c1a135508693aaf1bb63a00e44b3f03c2f242 Mon Sep 17 00:00:00 2001 From: SCHOTTER Romain <47983209+romainschotter@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:35:37 +0100 Subject: [PATCH 139/362] Update DPL configurations related to analysis QC (#2149) * Update existing O2Physics analysis configurations to latest standards * Remove global counters in multcentable and the use of NN in TPC PID --- .../json/analyses_config.json | 105 ++--- .../o2-analysis-event-selection-service.json | 57 +++ .../dpl/o2-analysis-ft0-corrected-table.json | 13 + ...ysis-fwdtrack-to-collision-associator.json | 13 + .../dpl/o2-analysis-lf-strangenesstofpid.json | 166 ++++++++ .../dpl/o2-analysis-mm-track-propagation.json | 29 ++ .../json/dpl/o2-analysis-multcenttable.json | 145 +++++++ .../dpl/o2-analysis-perf-k0s-resolution.json | 146 ++++++- .../json/dpl/o2-analysis-pid-tof-merge.json | 96 +++++ .../json/dpl/o2-analysis-pid-tpc-service.json | 52 +++ .../dpl/o2-analysis-propagation-service.json | 403 ++++++++++++++++++ .../json/dpl/o2-analysis-trackselection.json | 16 +- 12 files changed, 1164 insertions(+), 77 deletions(-) create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-event-selection-service.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-ft0-corrected-table.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-fwdtrack-to-collision-associator.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-lf-strangenesstofpid.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-mm-track-propagation.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-multcenttable.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-pid-tof-merge.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-pid-tpc-service.json create mode 100644 MC/config/analysis_testing/json/dpl/o2-analysis-propagation-service.json diff --git a/MC/config/analysis_testing/json/analyses_config.json b/MC/config/analysis_testing/json/analyses_config.json index c06fbb864..bc2998ce4 100644 --- a/MC/config/analysis_testing/json/analyses_config.json +++ b/MC/config/analysis_testing/json/analyses_config.json @@ -6,8 +6,8 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": false, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysistutorial-mc-histograms"] }, { @@ -16,10 +16,9 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", "o2-analysis-qa-efficiency"] }, { @@ -28,10 +27,9 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", "o2-analysis-qa-event-track"] }, { @@ -40,18 +38,14 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-lf-lambdakzerobuilder", - "o2-analysis-track-propagation", - "o2-analysis-trackselection", - "o2-analysis-pid-tof-base", - "o2-analysis-pid-tof", - "o2-analysis-pid-tof-full", - "o2-analysis-pid-tpc-base", - "o2-analysis-pid-tpc", - "o2-analysis-event-selection", - "o2-analysis-timestamp", - "o2-analysis-multiplicity-table", - "o2-analysis-qa-k0s-tracking-efficiency", + "tasks": ["o2-analysis-trackselection", + "o2-analysis-pid-tof-merge", + "o2-analysis-lf-strangenesstofpid", + "o2-analysis-pid-tpc-service", + "o2-analysis-event-selection-service", + "o2-analysis-multcenttable", + "o2-analysis-ft0-corrected-table", + "o2-analysis-propagationservice", "o2-analysis-perf-k0s-resolution"] }, { @@ -61,21 +55,16 @@ "valid_mc": true, "valid_data": true, "tasks": ["o2-analysis-ft0-corrected-table", - "o2-analysis-timestamp", - "o2-analysis-track-propagation", + "o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", - "o2-analysis-pid-tof-base", - "o2-analysis-pid-tof", - "o2-analysis-pid-tof-full", + "o2-analysis-multcenttable", + "o2-analysis-pid-tof-merge", "o2-analysis-pid-tof-qa", "o2-analysis-pid-tof-qa-evtime", - "o2-analysis-pid-tof-beta", "o2-analysis-pid-tof-qa-beta", "o2-analysis-pid-tpc-qa", - "o2-analysis-pid-tpc-base", - "o2-analysis-pid-tpc"] + "o2-analysis-pid-tpc-service"] }, { "name": "PWGMMMFT", @@ -83,11 +72,11 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", + "o2-analysis-multcenttable", + "o2-analysis-fwdtrack-to-collision-associator", "o2-analysis-mm-track-propagation", "o2-analysis-mm-dndeta-mft"] }, @@ -97,9 +86,8 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", - "o2-analysis-event-selection", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-event-selection-qa"] }, { @@ -108,11 +96,10 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", + "o2-analysis-multcenttable", "o2-analysis-ft0-corrected-table", "o2-analysis-time-dependent-qa"] }, @@ -130,7 +117,7 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": false, - "tasks": ["o2-analysis-timestamp", + "tasks": ["o2-analysis-event-selection-service", "o2-analysis-mm-vertexing-fwd"] }, { @@ -139,10 +126,9 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": false, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", "o2-analysis-task-mc-simple-qc"] }, { @@ -156,12 +142,10 @@ "o2-analysis-je-emcal-correction-task", "o2-analysis-je-emc-clustermonitor", "o2-analysis-je-emc-tmmonitor", - "o2-analysis-timestamp", - "o2-analysis-track-propagation", + "o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-pid-tpc", - "o2-analysis-pid-tpc-base" + "o2-analysis-pid-tpc-service" ] }, { @@ -170,11 +154,10 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", + "o2-analysis-multcenttable", "o2-analysis-ft0-corrected-table", "o2-analysis-ft0-qa"] }, @@ -191,15 +174,11 @@ "o2-analysis-track-to-collision-associator", "o2-analysis-hf-pid-creator", "o2-analysis-trackselection", - "o2-analysis-multiplicity-table", - "o2-analysis-centrality-table", - "o2-analysis-event-selection", - "o2-analysis-track-propagation", - "o2-analysis-timestamp", - "o2-analysis-pid-tpc", - "o2-analysis-pid-tpc-base", - "o2-analysis-pid-tof-full", - "o2-analysis-pid-tof-base", + "o2-analysis-multcenttable", + "o2-analysis-propagationservice", + "o2-analysis-event-selection-service", + "o2-analysis-pid-tpc-service", + "o2-analysis-pid-tof-merge", "o2-analysis-ft0-corrected-table"] } ] diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-event-selection-service.json b/MC/config/analysis_testing/json/dpl/o2-analysis-event-selection-service.json new file mode 100644 index 000000000..c17cdcb3c --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-event-selection-service.json @@ -0,0 +1,57 @@ +{ + "event-selection-service": { + "timestamp": { + "verbose": "0", + "fatalOnInvalidTimestamp": "0", + "rct-path": "RCT/Info/RunInformation", + "orbit-reset-path": "CTP/Calib/OrbitReset", + "isRun2MC": "-1" + }, + "bcselOpts": { + "amIneeded": "-1", + "triggerBcShift": "0", + "ITSROFrameStartBorderMargin": "-1", + "ITSROFrameEndBorderMargin": "-1", + "TimeFrameStartBorderMargin": "-1", + "TimeFrameEndBorderMargin": "-1", + "checkRunDurationLimits": "0", + "maxInactiveChipsPerLayer": { + "values": [ + "8", + "8", + "8", + "111", + "111", + "195", + "195" + ] + }, + "NumberOfOrbitsPerTF": "-1" + }, + "evselOpts": { + "amIneeded": "-1", + "muonSelection": "0", + "maxDiffZvtxFT0vsPV": "1", + "isMC": "-1", + "confSigmaBCforHighPtTracks": "4", + "TimeIntervalForOccupancyCalculationMin": "-40", + "TimeIntervalForOccupancyCalculationMax": "100", + "TimeRangeVetoOnCollStandard": "10", + "TimeRangeVetoOnCollNarrow": "2", + "FT0CamplPerCollCutVetoOnCollInTimeRange": "8000", + "FT0CamplPerCollCutVetoOnCollInROF": "5000", + "EpsilonVzDiffVetoInROF": "0.300000012", + "UseWeightsForOccupancyEstimator": "1", + "NumberOfOrbitsPerTF": "-1", + "TestAlternativeBcMatching": "0", + "TestModifyTimeVetoOnNearbyColl": "0", + "TestVetoOnTRDinPast": "0", + "TestVzDiffNsigma": "3", + "TestVzDiffMargin": "0.200000003" + }, + "lumiOpts": { + "amIneeded": "-1" + }, + "ccdburl": "http://alice-ccdb.cern.ch" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-ft0-corrected-table.json b/MC/config/analysis_testing/json/dpl/o2-analysis-ft0-corrected-table.json new file mode 100644 index 000000000..5fe5e456b --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-ft0-corrected-table.json @@ -0,0 +1,13 @@ +{ + "ft0-corrected-table": { + "resoFT0A": "20", + "resoFT0C": "20", + "addHistograms": "0", + "collisionSystem": "-2", + "ccdb-url": "http://alice-ccdb.cern.ch", + "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF", + "ccdb-timestamp": "-1", + "processStandard": "1", + "processWithBypassFT0timeInMC": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-fwdtrack-to-collision-associator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-fwdtrack-to-collision-associator.json new file mode 100644 index 000000000..8273cfdf4 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-fwdtrack-to-collision-associator.json @@ -0,0 +1,13 @@ +{ + "fwd-track-to-collision-association": { + "nSigmaForTimeCompat": "4", + "timeMargin": "0", + "includeUnassigned": "0", + "fillTableOfCollIdsPerTrack": "1", + "bcWindowForOneSigma": "115", + "processFwdAssocWithTime": "0", + "processFwdStandardAssoc": "0", + "processMFTAssocWithTime": "1", + "processMFTStandardAssoc": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-lf-strangenesstofpid.json b/MC/config/analysis_testing/json/dpl/o2-analysis-lf-strangenesstofpid.json new file mode 100644 index 000000000..f168e5634 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-lf-strangenesstofpid.json @@ -0,0 +1,166 @@ +{ + "strangenesstofpid": { + "calculationMethod": "0", + "calculateV0s": "-1", + "calculateCascades": "-1", + "calculateV0TOFPIDs": "-1", + "calculateV0TOFBetas": "-1", + "calculateV0TOFDebugs": "-1", + "calculateCascTOFPIDs": "-1", + "d_bz": "-999", + "tofPosition": "377.93399", + "doQA": "0", + "doNSigmas": "1", + "doQANSigma": "0", + "v0Calibration": { + "qaDCADau": "0.5", + "qaCosPA": "0.999000013", + "qaMassWindow": "0.00499999989", + "qaTPCNSigma": "5" + }, + "cascadeCalibration": { + "qaV0DCADau": "0.5", + "qaCascDCADau": "0.5", + "qaV0CosPA": "0.995000005", + "qaCascCosPA": "0.995000005", + "qaMassWindow": "0.00499999989", + "qaTPCNSigma": "5" + }, + "ccdb": { + "ccdb-url": "http://alice-ccdb.cern.ch", + "grpPath": "GLO/GRP/GRP", + "grpmagPath": "GLO/Config/GRPMagField", + "lutPath": "GLO/Param/MatLUT", + "nSigmaPath": "Users/d/ddobrigk/stratof", + "mVtxPath": "GLO/Calib/MeanVertex" + }, + "useCustomRunNumber": "1", + "manualRunNumber": "544122", + "axisPosition": { + "values": [ + "400", + "-400", + "400" + ] + }, + "axisEta": { + "values": [ + "20", + "-1", + "1" + ] + }, + "axisDeltaTime": { + "values": [ + "2000", + "-1000", + "1000" + ] + }, + "axisDeltaTimeVsPrimaryCalculation": { + "values": [ + "500", + "-500", + "500" + ] + }, + "axisTime": { + "values": [ + "400", + "10000", + "50000" + ] + }, + "axisNSigma": { + "values": [ + "200", + "-10", + "10" + ] + }, + "axisRatioMethods": { + "values": [ + "400", + "0.8999999761581421", + "1.899999976158142" + ] + }, + "axisSnp": { + "values": [ + "220", + "-1.100000023841858", + "1.100000023841858" + ] + }, + "axisP": { + "values": [ + "0", + "0", + "0.10000000149011612", + "0.20000000298023224", + "0.30000001192092896", + "0.4000000059604645", + "0.5", + "0.6000000238418579", + "0.699999988079071", + "0.800000011920929", + "0.8999999761581421", + "1", + "1.100000023841858", + "1.2000000476837158", + "1.2999999523162842", + "1.399999976158142", + "1.5", + "1.600000023841858", + "1.7000000476837158", + "1.7999999523162842", + "1.899999976158142", + "2", + "2.200000047683716", + "2.4000000953674316", + "2.5999999046325684", + "2.799999952316284", + "3", + "3.200000047683716", + "3.4000000953674316", + "3.5999999046325684", + "3.799999952316284", + "4", + "4.400000095367432", + "4.800000190734863", + "5.199999809265137", + "5.599999904632568", + "6", + "6.5", + "7", + "7.5", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "17", + "19", + "21", + "23", + "25", + "30", + "35", + "40", + "50" + ] + }, + "axisSmallP": { + "values": [ + "250", + "0", + "2.5" + ] + }, + "processStandardData": "1", + "processDerivedData": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-mm-track-propagation.json b/MC/config/analysis_testing/json/dpl/o2-analysis-mm-track-propagation.json new file mode 100644 index 000000000..d8e6cce90 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-mm-track-propagation.json @@ -0,0 +1,29 @@ +{ + "ambiguous-track-propagation": { + "ccdburl": "http://alice-ccdb.cern.ch", + "geoPath": "GLO/Config/GeometryAligned", + "grpmagPath": "GLO/Config/GRPMagField", + "mVtxPath": "GLO/Calib/MeanVertex", + "produceExtra": "0", + "produceHistos": "0", + "removeTrivialAssoc": "0", + "binsDCAxy": { + "values": [ + "200", + "-1", + "1" + ] + }, + "binsDCAz": { + "values": [ + "200", + "-1", + "1" + ] + }, + "processCentral": "0", + "processMFT": "0", + "processMFTReassoc": "1", + "processMFTReassoc3D": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-multcenttable.json b/MC/config/analysis_testing/json/dpl/o2-analysis-multcenttable.json new file mode 100644 index 000000000..43a938bf2 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-multcenttable.json @@ -0,0 +1,145 @@ +{ + "mult-cent-table": { + "generatorName": "", + "processRun3WithGlobalCounters": "0", + "processMFT": "0", + "processRun3": "1", + "processCentralityRun2": "0", + "processRun2": "0", + "processMonteCarlo2Mults": "0", + "enabledTables": { + "values": [ + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ] + ] + }, + "maxPtGlobalTrack": "1e+10", + "embedINELgtZEROselection": "0", + "minPtGlobalTrack": "0.15", + "autoConfigureProcess": "0", + "ccdbPathCentrality": "Centrality/Estimators", + "doVertexZeq": "1", + "ccdbPathVtxZ": "Centrality/Calibration", + "minNclsITSibGlobalTrack": "1", + "reconstructionPass": "", + "ccdburl": "http://alice-ccdb.cern.ch", + "processCentralityRun3": "1", + "minNclsITSGlobalTrack": "5", + "processMonteCarlo": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json b/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json index f7e949770..ba0c8142b 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json @@ -30,12 +30,144 @@ 6.2831853 ] }, - "rapidity": "0.5", - "v0lifetime": "3", - "v0setting_cospa": "0.995", - "v0setting_dcanegtopv": "0.1", - "v0setting_dcapostopv": "0.1", - "v0setting_dcav0dau": "1", - "v0setting_radius": "0.9" + "relpTResBins": { + "values": [ + "200", + "0", + "0.5" + ] + }, + "centralityAxis": { + "values": [ + "0", + "0", + "5", + "10", + "20", + "30", + "40", + "50", + "60", + "70", + "80", + "90", + "100", + "101" + ] + }, + "occupancyAxis": { + "values": [ + "0", + "-1", + "0", + "250", + "500", + "750", + "1000", + "1500", + "2000", + "3000", + "4500", + "6000", + "8000", + "10000", + "50000" + ] + }, + "eventSelections": { + "requireSel8": "0", + "requireTriggerTVX": "1", + "rejectITSROFBorder": "1", + "rejectTFBorder": "1", + "requireIsVertexITSTPC": "0", + "requireIsGoodZvtxFT0VsPV": "1", + "requireIsVertexTOFmatched": "0", + "requireIsVertexTRDmatched": "0", + "rejectSameBunchPileup": "1", + "requireNoCollInTimeRangeStd": "0", + "requireNoCollInTimeRangeStrict": "0", + "requireNoCollInTimeRangeNarrow": "0", + "requireNoCollInROFStd": "0", + "requireNoCollInROFStrict": "0", + "requireINEL0": "0", + "requireINEL1": "0", + "maxZVtxPosition": "10", + "centralityEstimator": "0", + "useFT0CbasedOccupancy": "0", + "minOccupancy": "-1", + "maxOccupancy": "-1" + }, + "v0Selections": { + "v0TypeSelection": "1", + "rapidityCut": "0.5", + "daughterEtaCut": "0.800000012", + "v0cospa": "0.995000005", + "dcav0dau": "1", + "dcanegtopv": "0.100000001", + "dcapostopv": "0.100000001", + "v0radius": "1.20000005", + "v0radiusMax": "100000", + "lifetimecut": { + "labels_rows": "", + "labels_cols": [ + "lifetimecutLambda", + "lifetimecutK0S" + ], + "values": [ + [ + "30", + "20" + ] + ] + }, + "armPodCut": "5", + "minTPCrows": "70", + "minITSclusters": "-1", + "minTPCrowsOverFindableClusters": "-1", + "minTPCfoundOverFindableClusters": "-1", + "maxFractionTPCSharedClusters": "1e+09", + "maxITSchi2PerNcls": "1e+09", + "maxTPCchi2PerNcls": "1e+09", + "requirePosITSib": "0", + "requireNegITSib": "0", + "requirePosITSafterburner": "0", + "requireNegITSafterburner": "0", + "trdSelectionPos": "0", + "trdSelectionNeg": "0", + "tofSelectionPos": "0", + "tofSelectionNeg": "0", + "pidHypoPos": "-1", + "pidHypoNeg": "-1", + "tpcPidNsigmaCut": "1e+09", + "tofPidNsigmaCut": "1000000" + }, + "useMultidimHisto": "0", + "enableTPCPlot": "0", + "requireTrueK0s": "0", + "doTreatPiToMuon": "0", + "trackTuner": { + "debugInfo": "0", + "updateTrackDCAs": "0", + "updateTrackCovMat": "0", + "updateCurvature": "0", + "updateCurvatureIU": "0", + "updatePulls": "0", + "isInputFileFromCCDB": "0", + "pathInputFile": "", + "nameInputFile": "", + "pathFileQoverPt": "", + "nameFileQoverPt": "", + "usePvRefitCorrections": "0", + "qOverPtMC": "-1", + "qOverPtData": "-1", + "nPhiBins": "0" + }, + "useTrackTuner": "0", + "trackTunerParams": "debugInfo=0|updateTrackCovMat=0|updateCurvature=1|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|usePvRefitCorrections=0|oneOverPtCurrent=1|oneOverPtUpgr=1.2", + "lutPath": "GLO/Param/MatLUTInner", + "ccdbUrl": "http://alice-ccdb.cern.ch", + "grpmagPath": "GLO/Config/GRPMagField", + "processData": "1", + "processMC": "0" } } diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tof-merge.json b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tof-merge.json new file mode 100644 index 000000000..f4a68dbee --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tof-merge.json @@ -0,0 +1,96 @@ +{ + "tof-pid-merge": { + "enableQaHistograms": "0", + "enableTOFParamsForBetaMass": "0", + "enableParticle": { + "labels_rows": [ + "El", + "Mu", + "Pi", + "Ka", + "Pr", + "De", + "Tr", + "He", + "Al" + ], + "labels_cols": [ + "Enable", + "EnableFull" + ], + "values": [ + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ] + ] + }, + "processRun3": "1", + "processRun2": "0", + "processRun2BetaM": "0", + "processRun3BetaM": "1" + }, + "tof-signal": { + "enableQaHistograms": "0", + "ccdb-url": "http://alice-ccdb.cern.ch", + "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF", + "ccdb-timestamp": "-1", + "timeShiftCCDBPathPos": "Analysis/PID/TOFOffsetPos", + "timeShiftCCDBPathNeg": "Analysis/PID/TOFOffsetPos", + "timeShiftCCDBPathPosMC": "", + "timeShiftCCDBPathNegMC": "", + "paramFileName": "", + "parametrizationPath": "TOF/Calib/Params", + "reconstructionPass": "metadata", + "reconstructionPassDefault": "unanchored", + "fatalOnPassNotAvailable": "0", + "enableTimeDependentResponse": "1", + "collisionSystem": "-1", + "autoSetProcessFunctions": "1", + "processRun3": "1", + "processRun2": "0" + }, + "tof-event-time": { + "minMomentum": "0.5", + "maxMomentum": "2", + "maxEvTimeTOF": "100000", + "sel8TOFEvTime": "0", + "computeEvTimeWithTOF": "1", + "computeEvTimeWithFT0": "1", + "maxNtracksInSet": "10", + "processRun2": "0", + "processRun3": "1" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tpc-service.json b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tpc-service.json new file mode 100644 index 000000000..5069a4eb2 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tpc-service.json @@ -0,0 +1,52 @@ +{ + "pid-tpc-service": { + "ccdburl": "http://alice-ccdb.cern.ch", + "pidTPC": { + "param-file": "", + "ccdbPath": "Analysis/PID/TPC/Response", + "recoPass": "", + "ccdb-timestamp": "0", + "useNetworkCorrection": "0", + "autofetchNetworks": "1", + "skipTPCOnly": "0", + "networkPathLocally": "network.onnx", + "networkPathCCDB": "Analysis/PID/TPC/ML", + "enableNetworkOptimizations": "1", + "networkSetNumThreads": "0", + "savedEdxsCorrected": "-1", + "useCorrecteddEdx": "0", + "pid-full-el": "-1", + "pid-full-mu": "-1", + "pid-full-pi": "-1", + "pid-full-ka": "-1", + "pid-full-pr": "-1", + "pid-full-de": "-1", + "pid-full-tr": "-1", + "pid-full-he": "-1", + "pid-full-al": "-1", + "pid-tiny-el": "-1", + "pid-tiny-mu": "-1", + "pid-tiny-pi": "-1", + "pid-tiny-ka": "-1", + "pid-tiny-pr": "-1", + "pid-tiny-de": "-1", + "pid-tiny-tr": "-1", + "pid-tiny-he": "-1", + "pid-tiny-al": "-1", + "enableTuneOnDataTable": "-1", + "useNetworkEl": "1", + "useNetworkMu": "0", + "useNetworkPi": "1", + "useNetworkKa": "1", + "useNetworkPr": "1", + "useNetworkDe": "0", + "useNetworkTr": "0", + "useNetworkHe": "0", + "useNetworkAl": "0", + "networkBetaGammaCutoff": "0.449999988" + }, + "processTracksIU": "1", + "processTracksIUWithTracksQA": "0", + "processTracksMCIU": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-propagation-service.json b/MC/config/analysis_testing/json/dpl/o2-analysis-propagation-service.json new file mode 100644 index 000000000..05c23a7f0 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-propagation-service.json @@ -0,0 +1,403 @@ +{ + "propagation-service": { + "ccdburl": "http://alice-ccdb.cern.ch", + "ccdb": { + "ccdb-url": "http://alice-ccdb.cern.ch", + "lutPath": "GLO/Param/MatLUTInner", + "grpmagPath": "GLO/Config/GRPMagField", + "mVtxPath": "GLO/Calib/MeanVertex" + }, + "enabledTables": { + "labels_rows": [ + "V0Indices", + "V0CoresBase", + "V0Covs", + "CascIndices", + "KFCascIndices", + "TraCascIndices", + "StoredCascCores", + "StoredKFCascCores", + "StoredTraCascCores", + "CascCovs", + "KFCascCovs", + "TraCascCovs", + "V0TrackXs", + "CascTrackXs", + "CascBBs", + "V0DauCovs", + "V0DauCovIUs", + "V0TraPosAtDCAs", + "V0TraPosAtIUs", + "V0Ivanovs", + "McV0Labels", + "V0MCCores", + "V0CoreMCLabels", + "V0MCCollRefs", + "McCascLabels", + "McKFCascLabels", + "McTraCascLabels", + "McCascBBTags", + "CascMCCores", + "CascCoreMCLabels", + "CascMCCollRefs", + "CascToTraRefs", + "CascToKFRefs", + "TraToCascRefs", + "KFToCascRefs", + "V0FoundTags", + "CascFoundTags" + ], + "labels_cols": [ + "enable" + ], + "values": [ + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "1" + ], + [ + "1" + ], + [ + "1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ] + ] + }, + "deduplicationAlgorithm": "1", + "useV0BufferForCascades": "0", + "mc_findableMode": "0", + "refitWithMaterialCorrection": "0", + "v0BuilderOpts": { + "generatePhotonCandidates": "0", + "moveTPCOnlyTracks": "1", + "minCrossedRows": "60", + "dcanegtopv": "0.0500000007", + "dcapostopv": "0.0500000007", + "v0cospa": "0.96999999999999997", + "dcav0dau": "1.5", + "v0radius": "0.899999976", + "maxDaughterEta": "0.800000012", + "mc_populateV0MCCoresSymmetric": "0", + "mc_populateV0MCCoresAsymmetric": "1", + "mc_treatPiToMuDecays": "1", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "1", + "mc_addGeneratedK0Short": "1", + "mc_addGeneratedLambda": "1", + "mc_addGeneratedAntiLambda": "1", + "mc_addGeneratedGamma": "0", + "mc_addGeneratedGammaMakeCollinear": "0", + "mc_findableDetachedV0": "0" + }, + "cascadeBuilderOpts": { + "useCascadeMomentumAtPrimVtx": "0", + "minCrossedRows": "60", + "dcabachtopv": "0.0500000007", + "cascradius": "0.899999976", + "casccospa": "0.970000029", + "dcacascdau": "1.5", + "lambdaMassWindow": "0.00999999978", + "maxDaughterEta": "0.800000012", + "kfTuneForOmega": "0", + "kfConstructMethod": "2", + "kfUseV0MassConstraint": "1", + "kfUseCascadeMassConstraint": "0", + "kfDoDCAFitterPreMinimV0": "1", + "kfDoDCAFitterPreMinimCasc": "1", + "mc_populateCascMCCoresSymmetric": "0", + "mc_populateCascMCCoresAsymmetric": "1", + "mc_addGeneratedXiMinus": "1", + "mc_addGeneratedXiPlus": "1", + "mc_addGeneratedOmegaMinus": "1", + "mc_addGeneratedOmegaPlus": "1", + "mc_treatPiToMuDecays": "1", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "1", + "mc_findableDetachedCascade": "0" + }, + "preSelectOpts": { + "preselectOnlyDesiredV0s": "0", + "preselectOnlyDesiredCascades": "0", + "lifetimeCut": { + "labels_rows": "", + "labels_cols": [ + "lifetimeCutK0S", + "lifetimeCutLambda", + "lifetimeCutXi", + "lifetimeCutOmega" + ], + "values": [ + [ + "20", + "60", + "40", + "20" + ] + ] + }, + "massCutPhoton": "0.300000012", + "massCutK0": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00281882007", + "0.00114057004", + "0.00172138005", + "0.500262022" + ] + ] + }, + "massCutLambda": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00117517996", + "0.000124098995", + "0.00547936978", + "0.308008999" + ] + ] + }, + "massCutXi": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massCutOm": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massWindownumberOfSigmas": "20", + "massWindowSafetyMargin": "0.00100000005", + "maxTPCpidNsigma": "5" + }, + "trackTuner": { + "debugInfo": "0", + "updateTrackDCAs": "0", + "updateTrackCovMat": "0", + "updateCurvature": "0", + "updateCurvatureIU": "0", + "updatePulls": "0", + "isInputFileFromCCDB": "0", + "pathInputFile": "", + "nameInputFile": "", + "pathFileQoverPt": "", + "nameFileQoverPt": "", + "usePvRefitCorrections": "0", + "qOverPtMC": "-1", + "qOverPtData": "-1", + "nPhiBins": "0" + }, + "trackPropagation": { + "minPropagationDistance": "5", + "useTrackTuner": "0", + "useTrkPid": "0", + "fillTrackTunerTable": "0", + "trackTunerConfigSource": "1", + "trackTunerParams": "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users\/m\/mfaggin\/test\/inputsTrackTuner\/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|pathFileQoverPt=Users\/h\/hsharma\/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", + "axisPtQA": { + "values": [ + "0", + "0", + "0.10000000149011612", + "0.20000000298023224", + "0.30000001192092896", + "0.4000000059604645", + "0.5", + "0.6000000238418579", + "0.699999988079071", + "0.800000011920929", + "0.8999999761581421", + "1", + "1.100000023841858", + "1.2000000476837158", + "1.2999999523162842", + "1.399999976158142", + "1.5", + "1.600000023841858", + "1.7000000476837158", + "1.7999999523162842", + "1.899999976158142", + "2", + "2.200000047683716", + "2.4000000953674316", + "2.5999999046325684", + "2.799999952316284", + "3", + "3.200000047683716", + "3.4000000953674316", + "3.5999999046325684", + "3.799999952316284", + "4", + "4.400000095367432", + "4.800000190734863", + "5.199999809265137", + "5.599999904632568", + "6", + "6.5", + "7", + "7.5", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "17", + "19", + "21", + "23", + "25", + "30", + "35", + "40", + "50" + ] + } + }, + "processRealData": "0", + "processMonteCarlo": "0", + "processRealDataWithPID": "1", + "processMonteCarloWithPID": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json b/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json index b8cc1b072..dc26e77f7 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json @@ -1,12 +1,14 @@ { "track-selection": { - "compatibilityIU": "false", - "etaMax": "0.8", - "etaMin": "-0.8", - "isRun3": "true", - "itsMatching": "1", + "isRun3": "1", + "produceTable": "-1", "produceFBextendedTable": "-1", + "compatibilityIU": "0", + "itsMatching": "1", + "dcaSetup": "0", + "ptMin": "0.100000001", "ptMax": "1e+10", - "ptMin": "0.1" + "etaMin": "-1", + "etaMax": "1" } -} +} \ No newline at end of file From ae18ea577b2defcc26b67016e84b3bdd8df5612f Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Thu, 16 Oct 2025 15:35:10 +0200 Subject: [PATCH 140/362] TPC laser: make GPUTYPE configurable via WORKFLOW_PARAMETERS --- DATA/production/calib/tpc-laser-filter.sh | 8 ++++++++ DATA/production/calib/tpc-laser.sh | 8 ++++++++ DATA/production/standalone-calibration.desc | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/DATA/production/calib/tpc-laser-filter.sh b/DATA/production/calib/tpc-laser-filter.sh index c64c0e9f0..80a9e6b79 100755 --- a/DATA/production/calib/tpc-laser-filter.sh +++ b/DATA/production/calib/tpc-laser-filter.sh @@ -13,6 +13,14 @@ FILEWORKDIR2="/home/epn/odc/files/" #ARGS_ALL_CONFIG+="NameConf.mDirGRP=$FILEWORKDIR;NameConf.mDirGeom=$FILEWORKDIR2;NameConf.mDirCollContext=$FILEWORKDIR;NameConf.mDirMatLUT=$FILEWORKDIR;keyval.input_dir=$FILEWORKDIR;keyval.output_dir=/dev/null" #ARGS_ALL_CONFIG+="NameConf.mDirGRP=$FILEWORKDIR;NameConf.mDirGeom=$FILEWORKDIR2;NameConf.mDirCollContext=$FILEWORKDIR;NameConf.mDirMatLUT=$FILEWORKDIR" +GPUTYPE=${GPUTYPE:-CPU} +HOSTMEMSIZE=0 +if workflow_has_parameter GPU; then + GPUTYPE=HIP + GPUMEMSIZE=$(( 24 << 30 )) + HOSTMEMSIZE=$(( 5 << 30 )) +fi + if [ ${NUMAGPUIDS} != 0 ]; then ARGS_ALL+=" --child-driver 'numactl --membind $NUMAID --cpunodebind $NUMAID'" fi diff --git a/DATA/production/calib/tpc-laser.sh b/DATA/production/calib/tpc-laser.sh index b15b9311a..575e03300 100755 --- a/DATA/production/calib/tpc-laser.sh +++ b/DATA/production/calib/tpc-laser.sh @@ -10,6 +10,14 @@ FILEWORKDIR="/home/wiechula/processData/inputFilesTracking/triggeredLaser" FILEWORKDIR2="/home/epn/odc/files/" +GPUTYPE=${GPUTYPE:-CPU} +HOSTMEMSIZE=0 +if workflow_has_parameter GPU; then + GPUTYPE=HIP + GPUMEMSIZE=$(( 24 << 30 )) + HOSTMEMSIZE=$(( 5 << 30 )) +fi + if [ $NUMAGPUIDS != 0 ]; then ARGS_ALL+=" --child-driver 'numactl --membind $NUMAID --cpunodebind $NUMAID'" fi diff --git a/DATA/production/standalone-calibration.desc b/DATA/production/standalone-calibration.desc index ad69e8c6b..169f2ff9b 100644 --- a/DATA/production/standalone-calibration.desc +++ b/DATA/production/standalone-calibration.desc @@ -40,9 +40,9 @@ TPC-pulser-long: "O2PDPSuite" reco,1,1," production/calib/tpc-pulser-long.sh" TPC-pedestal: "O2PDPSuite" reco,1,1," production/calib/tpc-pedestal.sh" -TPC-laser: "O2PDPSuite" reco,1,1,"SHMSIZE=$((128 << 30)) GPUTYPE=HIP GPUMEMSIZE=$(( 24 << 30 )) HOSTMEMSIZE=$(( 5 << 30 )) production/calib/tpc-laser.sh" +TPC-laser: "O2PDPSuite" reco,1,1,"SHMSIZE=$((128 << 30)) production/calib/tpc-laser.sh" -TPC-laser-multi: "O2PDPSuite" reco,10,10,"SHMSIZE=$((128 << 30)) GPUTYPE=HIP GPUMEMSIZE=$(( 24 << 30 )) HOSTMEMSIZE=$(( 5 << 30 )) production/calib/tpc-laser-filter.sh" calib,1,"production/calib/tpc-laser-aggregator.sh" +TPC-laser-multi: "O2PDPSuite" reco,10,10,"SHMSIZE=$((128 << 30)) production/calib/tpc-laser-filter.sh" calib,1,"production/calib/tpc-laser-aggregator.sh" MFT-noise-calibration: "O2PDPSuite" reco,20,20,"production/calib/mft-noise-processing.sh" calib,20,"production/calib/mft-noise-aggregator.sh" From a6fa4ed9c7bdb56b882c4b981794d11086093eb9 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Wed, 29 Oct 2025 22:02:26 +0100 Subject: [PATCH 141/362] Export ROOT and LD_LIBRARY variables with GSL,HERWIG7,ThePEG and nlohmann_json (#2174) --- test/run_generator_tests.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index 1fd510158..6c5f3b8b8 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -1,5 +1,22 @@ #!/bin/bash +###################################### +# Add Herwig, GSL, ThePEG and nlohmann_json packages to root include path and library path if not already present +###################################### + +# ROOT_INCLUDE_PATH +[[ -n "$THEPEG_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$THEPEG_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$THEPEG_ROOT/include:$ROOT_INCLUDE_PATH" +[[ -n "$HERWIG_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$HERWIG_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$HERWIG_ROOT/include:$ROOT_INCLUDE_PATH" +[[ -n "$GSL_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$GSL_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$GSL_ROOT/include:$ROOT_INCLUDE_PATH" +[[ -n "$NLOHMANN_JSON_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$NLOHMANN_JSON_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$NLOHMANN_JSON_ROOT/include:$ROOT_INCLUDE_PATH" + +# LD_LIBRARY_PATH +[[ -n "$THEPEG_ROOT" && ":$LD_LIBRARY_PATH:" != *":$THEPEG_ROOT/lib/ThePEG:"* ]] && LD_LIBRARY_PATH="$THEPEG_ROOT/lib/ThePEG:$LD_LIBRARY_PATH" +[[ -n "$HERWIG_ROOT" && ":$LD_LIBRARY_PATH:" != *":$HERWIG_ROOT/lib/Herwig:"* ]] && LD_LIBRARY_PATH="$HERWIG_ROOT/lib/Herwig:$LD_LIBRARY_PATH" +[[ -n "$GSL_ROOT" && ":$LD_LIBRARY_PATH:" != *":$GSL_ROOT/lib:"* ]] && LD_LIBRARY_PATH="$GSL_ROOT/lib:$LD_LIBRARY_PATH" + +export ROOT_INCLUDE_PATH LD_LIBRARY_PATH + ###################################### # Entrypoint for O2DPG related tests # ###################################### From 0b8c28d41f2069e852b4cec858179ff168fd8f48 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Thu, 30 Oct 2025 08:16:16 +0100 Subject: [PATCH 142/362] Herwig7 external generator (#2163) Implementation of HERWIG7 external generator to simplify usage --- MC/config/examples/herwig/LHC.in | 36 ++ MC/config/examples/herwig/generator_Herwig.C | 333 ++++++++++++++++++ MC/config/examples/ini/GeneratorHERWIG7.ini | 3 + .../examples/ini/tests/GeneratorHERWIG7.C | 38 ++ 4 files changed, 410 insertions(+) create mode 100644 MC/config/examples/herwig/LHC.in create mode 100644 MC/config/examples/herwig/generator_Herwig.C create mode 100644 MC/config/examples/ini/GeneratorHERWIG7.ini create mode 100644 MC/config/examples/ini/tests/GeneratorHERWIG7.C diff --git a/MC/config/examples/herwig/LHC.in b/MC/config/examples/herwig/LHC.in new file mode 100644 index 000000000..cb1ecb4fb --- /dev/null +++ b/MC/config/examples/herwig/LHC.in @@ -0,0 +1,36 @@ +# -*- ThePEG-repository -*- + +################################################################################ +# This file contains our best tune to UE data from ATLAS at 7 TeV. More recent +# tunes and tunes for other centre-of-mass energies as well as more usage +# instructions can be obtained from this Herwig wiki page: +# http://projects.hepforge.org/herwig/trac/wiki/MB_UE_tunes +# The model for soft interactions and diffractions is explained in +# [S. Gieseke, P. Kirchgaesser, F. Loshaj, arXiv:1612.04701] +################################################################################ + +read snippets/PPCollider.in + +################################################## +# Technical parameters for this run +################################################## +cd /Herwig/Generators +################################################## +# LHC physics parameters (override defaults here) +################################################## +set EventGenerator:EventHandler:LuminosityFunction:Energy 13600.0 +# Minimum Bias +read snippets/MB.in + +# Recommended set of parameters for MB/UE runs +set /Herwig/Hadronization/ColourReconnector:ReconnectionProbability 0.5 +set /Herwig/UnderlyingEvent/MPIHandler:pTmin0 3.502683 +set /Herwig/UnderlyingEvent/MPIHandler:InvRadius 1.402055 +set /Herwig/UnderlyingEvent/MPIHandler:Power 0.416852 +set /Herwig/Partons/RemnantDecayer:ladderPower -0.08 +set /Herwig/Partons/RemnantDecayer:ladderNorm 0.95 + +################################################## +# Save run for later usage with 'Herwig run' +################################################## +saverun LHC EventGenerator \ No newline at end of file diff --git a/MC/config/examples/herwig/generator_Herwig.C b/MC/config/examples/herwig/generator_Herwig.C new file mode 100644 index 000000000..1c3da112c --- /dev/null +++ b/MC/config/examples/herwig/generator_Herwig.C @@ -0,0 +1,333 @@ +#define SKIP_HEPMC_CONVERSION 1 +#define HAVE_HEPMC3 1 + +// O2DPG and ROOT includes +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "fairlogger/Logger.h" +#include "TParticle.h" +#include "TLorentzVector.h" +#include +#include +#include + +// ThePEG +#include "ThePEG/Repository/EventGenerator.h" +#include "ThePEG/EventRecord/Event.h" +#include "ThePEG/EventRecord/Particle.h" +#include "ThePEG/EventRecord/Step.h" +#include "ThePEG/Config/ThePEG.h" +#include "ThePEG/PDT/ParticleData.h" +#include "ThePEG/Repository/Repository.h" + +// Herwig +#include "Herwig/API/HerwigAPI.h" +#include "Herwig/API/HerwigUI.h" + +// Subclass of HerwigUI to provide minimal implementation of the abstract class +class SimpleHerwigUI : public Herwig::HerwigUI +{ +public: + SimpleHerwigUI(const std::string &inFile, + Herwig::RunMode::Mode mode = Herwig::RunMode::READ, int seed = 0) + : m_inFile(inFile), m_mode(mode), + m_in(inFile), m_out(std::cout), m_err(std::cerr), mSeed(seed) + { + if (!m_in) + { + LOG(fatal) << "Cannot open Herwig input file: " << inFile; + exit(1); + } + std::string hDir = std::getenv("HERWIG_ROOT"); + if (!hDir.empty()) + { + Dirs.push_back(hDir + "/share/Herwig"); + } + } + + Herwig::RunMode::Mode runMode() const override { return m_mode; } + + std::string repository() const override { + std::string rpo = std::getenv("HERWIG_ROOT"); + rpo.append("/share/Herwig/HerwigDefaults.rpo"); + return rpo; + } + std::string inputfile() const override { return m_inFile; } + std::string setupfile() const override { return ""; } + + bool resume() const override { return false; } + bool tics() const override { return false; } + std::string tag() const override { return ""; } + std::string integrationList() const override { return ""; } + + const std::vector &prependReadDirectories() const override + { + return Dirs; + } + const std::vector &appendReadDirectories() const override + { + static std::vector empty; + return empty; + } + + long N() const override { return 1; } // number of events + int seed() const override { return mSeed; } + int jobs() const override { return 1; } + unsigned int jobSize() const override { return 1; } + unsigned int maxJobs() const override { return 1; } + + void quitWithHelp() const override { std::exit(1); } + void quit() const override { std::exit(1); } + + std::ostream &outStream() const override { return m_out; } + std::ostream &errStream() const override { return m_err; } + std::istream &inStream() const override { return m_in; } + +private: + std::string m_inFile; + Herwig::RunMode::Mode m_mode; + mutable std::ifstream m_in; + std::ostream &m_out; + std::ostream &m_err; + std::vector Dirs; + int mSeed = 0; +}; + +namespace o2 +{ +namespace eventgen +{ + +/// HERWIG7 event generator using ThePEG interface +/// Author: Marco Giacalone (marco.giacalone@cern.ch) +/// Based on the O2DPG external generator configurations +class GeneratorHerwig : public Generator +{ +public: + /// Default constructor + GeneratorHerwig(const std::string& configFile = "LHC.in", int seed = -1) + : mConfigFile(configFile) + , mEventGenerator(nullptr) + { + LOG(info) << "HERWIG7 Generator construction"; + LOG(info) << "Config file: " << mConfigFile; + std::string extension = mConfigFile.substr(mConfigFile.find_last_of(".")); + if( extension == ".in" ) { + mIsInputFile = true; + LOG(info) << "Using input file for configuration"; + } else if(extension == ".run") { + mIsInputFile = false; + LOG(info) << "Using run file for configuration"; + } else { + LOG(fatal) << "No file extension found in config file: " << mConfigFile; + exit(1); + } + if (seed < 0) + { + auto &conf = o2::conf::SimConfig::Instance(); + mSeed = gRandom->Integer(conf.getStartSeed()); + } else { + mSeed = seed; + } + LOG(info) << "Using seed: " << mSeed << " for HERWIG simulation"; + } + + /// Destructor + ~GeneratorHerwig() = default; + + /// Initialize the generator + Bool_t Init() override + { + LOG(info) << "Initializing HERWIG7 Generator"; + if (mIsInputFile) { + // Process .in file + return initFromInputFile(); + } else { + // Process .run file directly + return initFromRunFile(); + } + } + + /// Generate event + Bool_t generateEvent() override + { + if (!mEventGenerator) { + LOG(error) << "Event generator not initialized"; + return kFALSE; + } + // Clear previous event particles + hParticles.clear(); + + // Generate the event + mPEGEvent = mEventGenerator->shoot(); + + if (!mPEGEvent) + { + LOG(error) << "Failed to generate event"; + return kFALSE; + } + + // Convert ThePEG event to TParticle format + convertEvent(mPEGEvent); + LOG(debug) << "Herwig7 generated " << hParticles.size() << " particles"; + + return kTRUE; + } + + /// Import particles for transport + Bool_t importParticles() override + { + if (hParticles.empty()) { + LOG(warning) << "No particles to import"; + return kFALSE; + } + + // Add particles to the primary generator + for (const auto& particle : hParticles) { + mParticles.push_back(particle); + } + + return kTRUE; + } + +private: + std::string mConfigFile; ///< HERWIG config file (.in or .run) + Bool_t mIsInputFile = false; ///< True for .in files, false for .run files + ThePEG::EGPtr mEventGenerator; ///< ThePEG event generator + std::vector hParticles; ///< Generated Herwig particles + ThePEG::EventPtr mPEGEvent; ///< Pointer to Current event + int mSeed = 0; ///< Random seed for Herwig + + void printHerwigSearchPaths() + { + const auto &list = ThePEG::Repository::listReadDirs(); + + LOG(info) << "Append directories:\n"; + for (const auto &p : list) + LOG(info) << " " << p << "\n"; + } + + /// Initialize from .in file + Bool_t initFromInputFile() + { + LOG(info) << "Initializing from .in file: " << mConfigFile; + + using namespace ThePEG; + SimpleHerwigUI ui(mConfigFile, Herwig::RunMode::READ, mSeed); + Herwig::API::read(ui); + // For debugging, print the search paths + // printHerwigSearchPaths(); + // Currently the .run filename is set inside the .in file itself with + // the line "saverun LHC EventGenerator" or similar. We assume this is the same as + // the .in file name with .run extension, so change that string accordingly in your .in files. + std::string runFile = mConfigFile; + size_t pos = runFile.find_last_of('.'); + runFile.replace(pos, 4, ".run"); + pos = runFile.find_last_of('/'); + runFile = (pos != std::string::npos) ? runFile.substr(pos + 1) : runFile; + mConfigFile = runFile; + LOG(info) << "Generated run file: " << runFile; + auto res = initFromRunFile(); + if (!res) { + LOG(error) << "Failed to initialize from generated run file"; + return kFALSE; + } + return kTRUE; + } + + /// Initialize from .run file + Bool_t initFromRunFile() + { + LOG(info) << "Initializing from .run file: " << mConfigFile; + + using namespace ThePEG; + + if (!std::ifstream(mConfigFile)) + { + LOG(info) << "Run file does not exist: " << mConfigFile; + return kFALSE; + } + SimpleHerwigUI runui(mConfigFile, Herwig::RunMode::RUN, mSeed); + // Prepare the generator + mEventGenerator = Herwig::API::prepareRun(runui); + if (!mEventGenerator) + { + LOG(fatal) << "Error: prepareRun() returned null."; + return kFALSE; + } + + mEventGenerator->initialize(); + LOG(info) << "Herwig generator initialized successfully."; + return kTRUE; + } + + /// Convert ThePEG event to TParticle format + void convertEvent(ThePEG::EventPtr event) + { + if (!event) return; + + // Get all particles from the event + const ThePEG::tPVector& particles = event->getFinalState(); + + for (size_t i = 0; i < particles.size(); ++i) { + ThePEG::tPPtr particle = particles[i]; + if (!particle) continue; + + // Get particle properties + int pdgCode = particle->id(); + int status = getFinalStateStatus(particle); + + // Get 4-momentum + ThePEG::LorentzMomentum momentum = particle->momentum(); + double px = momentum.x() / ThePEG::GeV; // Convert to GeV + double py = momentum.y() / ThePEG::GeV; + double pz = momentum.z() / ThePEG::GeV; + double e = momentum.e() / ThePEG::GeV; + + // Get production vertex + const ThePEG::LorentzPoint &vertex = particle->vertex(); + double vx = vertex.x() / ThePEG::mm; // Convert to mm + double vy = vertex.y() / ThePEG::mm; + double vz = vertex.z() / ThePEG::mm; + double vt = vertex.t() / ThePEG::mm; // Convert to mm/c + + // Create TParticle + TParticle tparticle( + pdgCode, status, + -1, -1, -1, -1, // mother and daughter indices (to be set properly) + px, py, pz, e, + vx, vy, vz, vt + ); + tparticle.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(tparticle.GetStatusCode(), 0).fullEncoding); + tparticle.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(tparticle.GetStatusCode()) == 1); + + hParticles.push_back(tparticle); + } + + LOG(debug) << "Converted " << hParticles.size() << " particles from HERWIG7 event"; + } + + /// Determine final state status for particle + int getFinalStateStatus(ThePEG::tPPtr particle) + { + // In HERWIG/ThePEG, check if particle is stable + if (particle->children().empty()) { + return 1; // Final state particle + } else { + return 2; // Intermediate particle + } + } +}; + +} // namespace eventgen +} // namespace o2 + +/// HERWIG7 generator from .in/.run file. If seed is -1, a random seed is chosen +/// based on the SimConfig starting seed. +FairGenerator* generateHerwig7(const std::string inputFile = "LHC.in", int seed = -1) +{ + auto filePath = gSystem->ExpandPathName(inputFile.c_str()); + auto generator = new o2::eventgen::GeneratorHerwig(filePath, seed); + return generator; +} \ No newline at end of file diff --git a/MC/config/examples/ini/GeneratorHERWIG7.ini b/MC/config/examples/ini/GeneratorHERWIG7.ini new file mode 100644 index 000000000..af904d1e8 --- /dev/null +++ b/MC/config/examples/ini/GeneratorHERWIG7.ini @@ -0,0 +1,3 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/herwig/generator_Herwig.C +funcName=generateHerwig7("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/herwig/LHC.in") diff --git a/MC/config/examples/ini/tests/GeneratorHERWIG7.C b/MC/config/examples/ini/tests/GeneratorHERWIG7.C new file mode 100644 index 000000000..384dda574 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorHERWIG7.C @@ -0,0 +1,38 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + return 0; +} \ No newline at end of file From 0aa78f8ad4e9b22e741f8918d6fd7816302ee88c Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Fri, 31 Oct 2025 07:26:02 +0100 Subject: [PATCH 143/362] Update the injector to use rapidity instead of eta (#2099) * Update the injector to use rapidity instead of eta * modify include method * Try to remove some headers * trial2 * trial3 * fix issue * working version in local * local ok version * add missing headers * remove trigger part --- .../GeneratorLF_ExoticResonances_pp1360.ini | 4 +- .../PWGLF/ini/GeneratorLF_Resonances_PbPb.ini | 4 +- ...eratorLF_Resonances_PbPb5360_injection.ini | 4 +- ...eneratorLF_Resonances_PbPb5360_trigger.ini | 10 - .../GeneratorLF_Resonances_PbPb_exotic.ini | 4 +- .../PWGLF/ini/GeneratorLF_Resonances_pp.ini | 4 +- .../ini/GeneratorLF_Resonances_pp1360.ini | 4 +- ...eneratorLF_Resonances_pp1360_injection.ini | 4 +- .../GeneratorLF_Resonances_pp1360_trigger.ini | 10 - .../ini/GeneratorLF_Resonances_pp900.ini | 4 +- ...GeneratorLF_Resonances_pp900_injection.ini | 4 +- .../GeneratorLF_Resonances_pp900_trigger.ini | 10 - .../ini/GeneratorLF_Resonances_pp_exotic.ini | 4 +- .../GeneratorLF_Resonances_PbPb5360_trigger.C | 180 ----- .../GeneratorLF_Resonances_pp1360_trigger.C | 182 ----- .../GeneratorLF_Resonances_pp900_trigger.C | 170 ----- .../pythia8/generator/exoticresonancegun.json | 12 + .../pythia8/generator/resonancelistgun.json | 48 ++ .../generator/resonancelistgun_exotic.json | 28 + .../resonancelistgun_exotic_pbpb.json | 28 + .../generator/resonancelistgun_inj.json | 14 + .../generator/resonancelistgun_inj_pbpb.json | 14 + .../generator/resonancelistgun_pbpb.json | 48 ++ .../generator/resonancelistgun_trig.json | 34 + .../generator/resonancelistgun_trig_pbpb.json | 34 + .../pythia8/generator_pythia8_LF_rapidity.C | 631 ++++++++++++++++++ 26 files changed, 911 insertions(+), 582 deletions(-) delete mode 100644 MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_trigger.ini delete mode 100644 MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_trigger.ini delete mode 100644 MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_trigger.ini delete mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_PbPb5360_trigger.C delete mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp1360_trigger.C delete mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp900_trigger.C create mode 100644 MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini b/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini index 55262cb83..3535d7cbe 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini index b66e66584..529787320 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json", true, 4) # [GeneratorPythia8] # config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini index 89faa5413..5050d1760 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json", true, 4) # [GeneratorPythia8] # config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_trigger.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_trigger.ini deleted file mode 100644 index bffef0d39..000000000 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_trigger.ini +++ /dev/null @@ -1,10 +0,0 @@ -[GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json", true, 4) - -[GeneratorPythia8] -config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg - -[DecayerPythia8] # after for transport code! -config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini index e2e575af0..fb7869c66 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4) # [GeneratorPythia8] # config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini index 8e91af28b..4ba2a3fd9 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini index 8e91af28b..4ba2a3fd9 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini index 9e3d43470..cf103d147 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_trigger.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_trigger.ini deleted file mode 100644 index 0a4d58ca4..000000000 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_trigger.ini +++ /dev/null @@ -1,10 +0,0 @@ -[GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4) - -[GeneratorPythia8] # if triggered then this will be used as the background event -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg - -[DecayerPythia8] # after for transport code! -config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini index d23569e2a..a890a5531 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini index 4ef0a59b6..2e5c4a6d4 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_trigger.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_trigger.ini deleted file mode 100644 index 1f0328d6a..000000000 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_trigger.ini +++ /dev/null @@ -1,10 +0,0 @@ -[GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4) - -[GeneratorPythia8] # if triggered then this will be used as the background event -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg - -[DecayerPythia8] # after for transport code! -config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini index a49804cc8..7ec78bb39 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini @@ -1,6 +1,6 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_PbPb5360_trigger.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_PbPb5360_trigger.C deleted file mode 100644 index b6057017a..000000000 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_PbPb5360_trigger.C +++ /dev/null @@ -1,180 +0,0 @@ -int External() -{ - std::string path{"o2sim_Kine.root"}; - int numberOfInjectedSignalsPerEvent{1}; - int numberOfGapEvents{4}; - int numberOfEventsProcessed{0}; - int numberOfEventsProcessedWithoutInjection{0}; - std::vector injectedPDGs = { - 323, // K*+- - -323, // K*bar+- - 9010221, // f_0(980) - 113, // rho(770)0 - 213, // rho(770)+ - -213, // rho(770)bar- - 3224, // Sigma(1385)+ - -3224, // Sigma(1385)bar- - 3114, // Sigma(1385)- - -3114, // Sigma(1385)bar+ - 3124, // Lambda(1520)0 - -3124, // Lambda(1520)0bar - 3324, // Xi(1530)0 - -3324, // Xi(1530)0bar - 10323, // K1(1270)+ - -10323, // K1(1270)-bar - 2224, // Delta(1232)+ - -2224, // Delta(1232)bar- - 2114, // Delta(1232)0 - -2114, // Delta(1232)0bar - 123314, // Xi(1820)- - -123314, // Xi(1820)+ - 123324, // Xi(1820)0 - -123324 // Xi(1820)0bar - }; - std::vector> decayDaughters = { - {311, 211}, // K*+- - {-311, -211}, // K*bar+- - {211, -211}, // f_0(980) - {211, -211}, // rho(770)0 - {211, 111}, // rho(770)+ - {-211, 111}, // rho(770)bar- - {3122, 211}, // Sigma(1385)+ - {-3122, -211}, // Sigma(1385)bar- - {3122, -211}, // Sigma(1385)- - {-3122, 211}, // Sigma(1385)bar+ - {2212, -321}, // Lambda(1520)0 - {-2212, 321}, // Lambda(1520)0bar - {3312, 211}, // Xi(1530)0 - {-3312, -211}, // Xi(1530)0bar - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {-2212, -211}, // Delta(1232)bar- - {2212, -211}, // Delta(1232)- - {-2212, 211}, // Delta(1232)bar+ - {3122, -311}, // Xi(1820)- - {3122, 311}, // Xi(1820)+ - {3122, 310}, // Xi(1820)0 - {-3122, 310} // Xi(1820)0bar - }; - - auto nInjection = injectedPDGs.size(); - - TFile file(path.c_str(), "READ"); - if (file.IsZombie()) - { - std::cerr << "Cannot open ROOT file " << path << "\n"; - return 1; - } - - auto tree = (TTree *)file.Get("o2sim"); - if (!tree) - { - std::cerr << "Cannot find tree o2sim in file " << path << "\n"; - return 1; - } - std::vector *tracks{}; - tree->SetBranchAddress("MCTrack", &tracks); - - std::vector nSignal; - for (int i = 0; i < nInjection; i++) - { - nSignal.push_back(0); - } - std::vector> nDecays; - std::vector nNotDecayed; - for (int i = 0; i < nInjection; i++) - { - std::vector nDecay; - for (int j = 0; j < decayDaughters[i].size(); j++) - { - nDecay.push_back(0); - } - nDecays.push_back(nDecay); - nNotDecayed.push_back(0); - } - auto nEvents = tree->GetEntries(); - bool hasInjection = false; - for (int i = 0; i < nEvents; i++) - { - hasInjection = false; - numberOfEventsProcessed++; - auto check = tree->GetEntry(i); - for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) - { - auto track = tracks->at(idxMCTrack); - auto pdg = track.GetPdgCode(); - auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); - int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG - if (it != injectedPDGs.end()) // found - { - // count signal PDG - nSignal[index]++; - if(track.getFirstDaughterTrackId() < 0) - { - nNotDecayed[index]++; - continue; - } - for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) - { - auto pdgDau = tracks->at(j).GetPdgCode(); - bool foundDau= false; - // count decay PDGs - for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) - { - if (pdgDau == decayDaughters[index][idxDaughter]) - { - nDecays[index][idxDaughter]++; - foundDau= true; - hasInjection = true; - break; - } - } - if (!foundDau) { - std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; - } - } - } - } - if (!hasInjection) - { - numberOfEventsProcessedWithoutInjection++; - } - } - std::cout << "--------------------------------\n"; - std::cout << "# Events: " << nEvents << "\n"; - for (int i = 0; i < nInjection; i++) - { - std::cout << "# Mother \n"; - std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; - if (nSignal[i] == 0){ - std::cerr << "No generated: " << injectedPDGs[i] << "\n"; - // return 1; // At least one of the injected particles should be generated - } - for (int j = 0; j < decayDaughters[i].size(); j++) - { - std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; - } - // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) - // { - // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; - // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event - // } - } - std::cout << "--------------------------------\n"; - std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; - std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; - std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; - // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... - // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed - float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed; - if (ratioOfNormalEvents > 0.75) - { - std::cout << "The number of injected event is loo low!!" << std::endl; - return 1; - } - - return 0; -} - -void GeneratorLF_Resonances_PbPb5360_trigger() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp1360_trigger.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp1360_trigger.C deleted file mode 100644 index b4d5c81f2..000000000 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp1360_trigger.C +++ /dev/null @@ -1,182 +0,0 @@ -int External() -{ - std::string path{"o2sim_Kine.root"}; - int numberOfInjectedSignalsPerEvent{1}; - int numberOfGapEvents{4}; - int numberOfEventsProcessed{0}; - int numberOfEventsProcessedWithoutInjection{0}; - std::vector injectedPDGs = { - 323, // K*+- - -323, // K*bar+- - 9010221, // f_0(980) - 113, // rho(770)0 - 213, // rho(770)+ - -213, // rho(770)bar- - 3224, // Sigma(1385)+ - -3224, // Sigma(1385)bar- - 3114, // Sigma(1385)- - -3114, // Sigma(1385)bar+ - 3124, // Lambda(1520)0 - -3124, // Lambda(1520)0bar - 3324, // Xi(1530)0 - -3324, // Xi(1530)0bar - 10323, // K1(1270)+ - -10323, // K1(1270)-bar - 2224, // Delta(1232)+ - -2224, // Delta(1232)bar- - 2114, // Delta(1232)0 - -2114, // Delta(1232)0bar - 123314, // Xi(1820)- - -123314, // Xi(1820)+ - 123324, // Xi(1820)0 - -123324 // Xi(1820)0bar - }; - std::vector> decayDaughters = { - {311, 211}, // K*+- - {-311, -211}, // K*bar+- - {211, -211}, // f_0(980) - {211, -211}, // rho(770)0 - {211, 111}, // rho(770)+ - {-211, 111}, // rho(770)bar- - {3122, 211}, // Sigma(1385)+ - {-3122, -211}, // Sigma(1385)bar- - {3122, -211}, // Sigma(1385)- - {-3122, 211}, // Sigma(1385)bar+ - {2212, -321}, // Lambda(1520)0 - {-2212, 321}, // Lambda(1520)0bar - {3312, 211}, // Xi(1530)0 - {-3312, -211}, // Xi(1530)0bar - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {-2212, -211}, // Delta(1232)bar- - {2212, -211}, // Delta(1232)- - {-2212, 211}, // Delta(1232)bar+ - {3122, -311}, // Xi(1820)- - {3122, 311}, // Xi(1820)+ - {3122, 310}, // Xi(1820)0 - {-3122, 310} // Xi(1820)0bar - }; - - auto nInjection = injectedPDGs.size(); - - TFile file(path.c_str(), "READ"); - if (file.IsZombie()) - { - std::cerr << "Cannot open ROOT file " << path << "\n"; - return 1; - } - - auto tree = (TTree *)file.Get("o2sim"); - if (!tree) - { - std::cerr << "Cannot find tree o2sim in file " << path << "\n"; - return 1; - } - std::vector *tracks{}; - tree->SetBranchAddress("MCTrack", &tracks); - - std::vector nSignal; - for (int i = 0; i < nInjection; i++) - { - nSignal.push_back(0); - } - std::vector> nDecays; - std::vector nNotDecayed; - for (int i = 0; i < nInjection; i++) - { - std::vector nDecay; - for (int j = 0; j < decayDaughters[i].size(); j++) - { - nDecay.push_back(0); - } - nDecays.push_back(nDecay); - nNotDecayed.push_back(0); - } - auto nEvents = tree->GetEntries(); - bool hasInjection = false; - for (int i = 0; i < nEvents; i++) - { - hasInjection = false; - numberOfEventsProcessed++; - auto check = tree->GetEntry(i); - for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) - { - auto track = tracks->at(idxMCTrack); - auto pdg = track.GetPdgCode(); - auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); - int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG - if (it != injectedPDGs.end()) // found - { - // count signal PDG - nSignal[index]++; - if (track.getFirstDaughterTrackId() < 0) - { - nNotDecayed[index]++; - continue; - } - for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) - { - auto pdgDau = tracks->at(j).GetPdgCode(); - bool foundDau = false; - // count decay PDGs - for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) - { - if (pdgDau == decayDaughters[index][idxDaughter]) - { - nDecays[index][idxDaughter]++; - foundDau = true; - hasInjection = true; - break; - } - } - if (!foundDau) - { - std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; - } - } - } - } - if (!hasInjection) - { - numberOfEventsProcessedWithoutInjection++; - } - } - std::cout << "--------------------------------\n"; - std::cout << "# Events: " << nEvents << "\n"; - for (int i = 0; i < nInjection; i++) - { - std::cout << "# Mother \n"; - std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; - if (nSignal[i] == 0) - { - std::cerr << "No generated: " << injectedPDGs[i] << "\n"; - // return 1; // At least one of the injected particles should be generated - } - for (int j = 0; j < decayDaughters[i].size(); j++) - { - std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; - } - // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) - // { - // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; - // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event - // } - } - std::cout << "--------------------------------\n"; - std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; - std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; - std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; - // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... - // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed - float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; - if (ratioOfNormalEvents > 0.75) - { - std::cout << "The number of injected event is loo low!!" << std::endl; - return 1; - } - - return 0; -} - -void GeneratorLF_Resonances_pp1360_trigger() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp900_trigger.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp900_trigger.C deleted file mode 100644 index 701d018ad..000000000 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp900_trigger.C +++ /dev/null @@ -1,170 +0,0 @@ -int External() -{ - std::string path{"o2sim_Kine.root"}; - int numberOfInjectedSignalsPerEvent{1}; - int numberOfGapEvents{4}; - int numberOfEventsProcessed{0}; - int numberOfEventsProcessedWithoutInjection{0}; - std::vector injectedPDGs = { - 323, // K*+- - -323, // K*bar+- - 9010221, // f_0(980) - 113, // rho(770)0 - 213, // rho(770)+ - -213, // rho(770)bar- - 3224, // Sigma(1385)+ - -3224, // Sigma(1385)bar- - 3114, // Sigma(1385)- - -3114, // Sigma(1385)bar+ - 3324, // Xi(1530)0 - -3324, // Xi(1530)0bar - 10323, // K1(1270)+ - -10323, // K1(1270)-bar - 2224, // Delta(1232)+ - -2224, // Delta(1232)bar- - 2114, // Delta(1232)0 - -2114 // Delta(1232)0bar - }; - std::vector> decayDaughters = { - {311, 211}, // K*+- - {-311, -211}, // K*bar+- - {211, -211}, // f_0(980) - {211, -211}, // rho(770)0 - {211, 111}, // rho(770)+ - {-211, 111}, // rho(770)bar- - {3122, 211}, // Sigma(1385)+ - {-3122, -211}, // Sigma(1385)bar- - {3122, -211}, // Sigma(1385)- - {-3122, 211}, // Sigma(1385)bar+ - {3312, 211}, // Xi(1530)0 - {-3312, -211}, // Xi(1530)0bar - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {-2212, -211}, // Delta(1232)bar- - {2212, -211}, // Delta(1232)- - {-2212, 211} // Delta(1232)bar+ - }; - - auto nInjection = injectedPDGs.size(); - - TFile file(path.c_str(), "READ"); - if (file.IsZombie()) - { - std::cerr << "Cannot open ROOT file " << path << "\n"; - return 1; - } - - auto tree = (TTree *)file.Get("o2sim"); - if (!tree) - { - std::cerr << "Cannot find tree o2sim in file " << path << "\n"; - return 1; - } - std::vector *tracks{}; - tree->SetBranchAddress("MCTrack", &tracks); - - std::vector nSignal; - for (int i = 0; i < nInjection; i++) - { - nSignal.push_back(0); - } - std::vector> nDecays; - std::vector nNotDecayed; - for (int i = 0; i < nInjection; i++) - { - std::vector nDecay; - for (int j = 0; j < decayDaughters[i].size(); j++) - { - nDecay.push_back(0); - } - nDecays.push_back(nDecay); - nNotDecayed.push_back(0); - } - auto nEvents = tree->GetEntries(); - bool hasInjection = false; - for (int i = 0; i < nEvents; i++) - { - hasInjection = false; - numberOfEventsProcessed++; - auto check = tree->GetEntry(i); - for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) - { - auto track = tracks->at(idxMCTrack); - auto pdg = track.GetPdgCode(); - auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); - int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG - if (it != injectedPDGs.end()) // found - { - // count signal PDG - nSignal[index]++; - if (track.getFirstDaughterTrackId() < 0) - { - nNotDecayed[index]++; - continue; - } - for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) - { - auto pdgDau = tracks->at(j).GetPdgCode(); - bool foundDau = false; - // count decay PDGs - for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) - { - if (pdgDau == decayDaughters[index][idxDaughter]) - { - nDecays[index][idxDaughter]++; - foundDau = true; - hasInjection = true; - break; - } - } - if (!foundDau) - { - std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; - } - } - } - } - if (!hasInjection) - { - numberOfEventsProcessedWithoutInjection++; - } - } - std::cout << "--------------------------------\n"; - std::cout << "# Events: " << nEvents << "\n"; - for (int i = 0; i < nInjection; i++) - { - std::cout << "# Mother \n"; - std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; - if (nSignal[i] == 0) - { - std::cerr << "No generated: " << injectedPDGs[i] << "\n"; - // return 1; // At least one of the injected particles should be generated - } - for (int j = 0; j < decayDaughters[i].size(); j++) - { - std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; - } - // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) - // { - // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; - // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event - // } - } - std::cout << "--------------------------------\n"; - std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; - std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; - std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; - // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... - // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed - float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; - if (ratioOfNormalEvents > 0.75) - { - std::cout << "The number of injected event is loo low!!" << std::endl; - return 1; - } - - return 0; -} - -void GeneratorLF_Resonances_pp900_trigger() { External(); } diff --git a/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json b/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json index a2d964c1a..7043cd6d8 100644 --- a/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json +++ b/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_1(1420)" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1500)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1710)" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_2(1525)" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1370)" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun.json index b8c248b16..8fa6a5b4f 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Lambda(1520)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -159,6 +193,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -168,6 +204,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -177,6 +215,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -186,6 +226,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -195,6 +237,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -204,6 +248,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -213,6 +259,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json index 1d1f07fcb..8f6e78f1d 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1370)" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1500)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1710)" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_1(1285)" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_1(1420)" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_2(1525)" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "a_2(1230)" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json index 99b38064d..326752866 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1370)" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1500)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1710)" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_1(1285)" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_1(1420)" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_2(1525)" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "a_2(1230)" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json index e2ff3a233..c15acbf37 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json index 1de68db2e..005c8ca76 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json index 89413907a..d2f92f44d 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Lambda(1520)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -159,6 +193,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -168,6 +204,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -177,6 +215,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -186,6 +226,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -195,6 +237,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -204,6 +248,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -213,6 +259,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json index b8e19d235..de1ad01e1 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json index b778543df..f2c692e5a 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C new file mode 100644 index 000000000..f3c56f420 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C @@ -0,0 +1,631 @@ +/// +/// \file generator_pythia8_LF_rapidity.C +/// \author Bong-Hwi Lim bong-hwi.lim@cern.ch +/// \author Based on generator_pythia8_LF.C by Nicolò Jacazio +/// \since 2025/08/18 +/// \brief Implementation of a gun generator for multiple particles using rapidity instead of eta, built on generator_pythia8_longlived.C +/// Needs PDG, Number of injected, minimum and maximum pT, minimum and maximum rapidity. These can be provided in three ways, bundeling variables, particles or from input file +/// usage: +/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity({1000010020, 1000010030}, {10, 10}, {0.5, 0.5}, {10, 10}, {-1.0, -1.0}, {1.0, 1.0})'` +/// Here PDG, Number injected, pT limits, rapidity limits are separated and matched by index +/// or: +/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity({{1000010020, 10, 0.5, 10, -1.0, 1.0}, {1000010030, 10, 0.5, 10, -1.0, 1.0}})'` +/// Here PDG, Number injected, pT limits, rapidity limits are divided per particle +/// or: +/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/nuclei_rapidity.gun")'` +/// Here PDG, Number injected, pT limits, rapidity limits are provided via an intermediate configuration file +/// + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "Pythia8/Pythia.h" +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#if __has_include("SimulationDataFormat/MCGenStatus.h") +#include "SimulationDataFormat/MCGenStatus.h" +#else +#include "SimulationDataFormat/MCGenProperties.h" +#endif +#if __has_include("SimulationDataFormat/MCUtils.h") +#include "SimulationDataFormat/MCUtils.h" +#endif +#include "fairlogger/Logger.h" +#include "TSystem.h" +#include +#include "Generators/GeneratorPythia8Param.h" +#include +#endif +// DecayerPythia8Param needs to be included after the #endif to work with Cling +#include "Generators/DecayerPythia8Param.h" +#if defined(__CLING__) && !defined(__ROOTCLING__) +#if __has_include("SimulationDataFormat/MCGenStatus.h") +#include "SimulationDataFormat/MCGenStatus.h" +#elif __has_include("SimulationDataFormat/MCGenProperties.h") +#include "SimulationDataFormat/MCGenProperties.h" +#endif +#if __has_include("SimulationDataFormat/MCUtils.h") +#include "SimulationDataFormat/MCUtils.h" +#endif +#pragma cling load("libO2Generators") +#endif +#include "Generators/GeneratorPythia8.h" +#include + +using namespace Pythia8; +using namespace o2::mcgenstatus; + +// Helper function to get mass from PDG code (copied from generator_pythia8_longlived.C to avoid include issues) +namespace { +double getMassFromPDG(int input_pdg) +{ + double mass = 0; + if (TDatabasePDG::Instance()) + { + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg); + if (particle) { + mass = particle->Mass(); + } else { + LOG(warning) << "Unknown particle requested with PDG " << input_pdg << ", mass set to 0"; + } + } + return mass; +} +} + +class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 +{ + public: + /// Parametric constructor + GeneratorPythia8LFRapidity(bool injOnePerEvent /*= true*/, + int gapBetweenInjection /*= 0*/, + bool useTrigger /*= false*/, + std::string pythiaCfgMb /*= "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_minbias.cfg"*/, + std::string pythiaCfgSignal /*= "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_signal.cfg"*/) : GeneratorPythia8{}, + mOneInjectionPerEvent{injOnePerEvent}, + mGapBetweenInjection{gapBetweenInjection}, + mUseTriggering{useTrigger} + { + LOG(info) << "GeneratorPythia8LFRapidity constructor"; + LOG(info) << "++ mOneInjectionPerEvent: " << mOneInjectionPerEvent; + LOG(info) << "++ mGapBetweenInjection: " << mGapBetweenInjection; + LOG(info) << "++ mUseTriggering: " << mUseTriggering; + LOG(info) << "++ pythiaCfgMb: " << pythiaCfgMb; + LOG(info) << "++ pythiaCfgSignal: " << pythiaCfgSignal; + gRandom->SetSeed(0); + if (useTrigger) { + mPythia.readString("ProcessLevel:all off"); + if (pythiaCfgMb == "") { // If no configuration file is provided, use the one from the Pythia8Param + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Instance LFRapidity \'Pythia8\' generator with following parameters for MB event"; + LOG(info) << param; + pythiaCfgMb = param.config; + } + if (pythiaCfgSignal == "") { // If no configuration file is provided, use the one from the Pythia8Param + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Instance LFRapidity \'Pythia8\' generator with following parameters for signal event"; + LOG(info) << param; + pythiaCfgSignal = param.config; + } + pythiaCfgMb = gSystem->ExpandPathName(pythiaCfgMb.c_str()); + pythiaCfgSignal = gSystem->ExpandPathName(pythiaCfgSignal.c_str()); + LOG(info) << " ++ Using trigger, initializing Pythia8 for trigger"; + if (!pythiaObjectMinimumBias.readFile(pythiaCfgMb)) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.readFile(\"" << pythiaCfgMb << "\")"; + } + pythiaObjectMinimumBias.readString("Random:setSeed = on"); + pythiaObjectMinimumBias.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + + if (!pythiaObjectMinimumBias.init()) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; + } + if (!pythiaObjectSignal.readFile(pythiaCfgSignal)) { + LOG(fatal) << "Could not pythiaObjectSignal.readFile(\"" << pythiaCfgSignal << "\")"; + } + pythiaObjectSignal.readString("Random:setSeed = on"); + pythiaObjectSignal.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + if (!pythiaObjectSignal.init()) { + LOG(fatal) << "Could not pythiaObjectSignal.init() from " << pythiaCfgSignal; + } + } else { // Using simple injection with internal decay (if needed). Fetching the parameters from the configuration file of the PythiaDecayer + /** switch off process level **/ + mPythia.readString("ProcessLevel:all off"); + + /** config **/ + auto& paramGen = o2::eventgen::GeneratorPythia8Param::Instance(); + if (!paramGen.config.empty()) { + LOG(fatal) << "Configuration file provided for \'GeneratorPythia8\' should be empty for this injection scheme"; + return; + } + auto& param = o2::eventgen::DecayerPythia8Param::Instance(); + LOG(info) << "Init \'GeneratorPythia8LFRapidity\' with following parameters"; + LOG(info) << param; + for (int i = 0; i < 8; ++i) { + if (param.config[i].empty()) { + continue; + } + std::string config = gSystem->ExpandPathName(param.config[i].c_str()); + LOG(info) << "GeneratorPythia8LFRapidity Reading configuration from file: " << config; + if (!mPythia.readFile(config, true)) { + LOG(fatal) << "Failed to init \'DecayerPythia8\': problems with configuration file " + << config; + return; + } + } + + /** show changed particle data **/ + if (param.showChanged) { + mPythia.readString(std::string("Init:showChangedParticleData on")); + } else { + mPythia.readString(std::string("Init:showChangedParticleData off")); + } + + /** initialise **/ + if (!mPythia.init()) { + LOG(fatal) << "Failed to init \'DecayerPythia8\': init returned with error"; + return; + } + if (pythiaCfgSignal != "") { + LOG(fatal) << "Cannot use simple injection and have a configuration file. pythiaCfgSignal= `" << pythiaCfgSignal << "` must be empty"; + } + } + } + + /// Destructor + ~GeneratorPythia8LFRapidity() = default; + + //__________________________________________________________________ + Bool_t generateEvent() override + { + if (!mUseTriggering) { // If the triggering is used we handle the the gap when generating the signal + if (mGapBetweenInjection > 0) { + if (mGapBetweenInjection == 1 && mEventCounter % 2 == 0) { + LOG(info) << "Skipping event " << mEventCounter; + return true; + } else if (mEventCounter % mGapBetweenInjection != 0) { + LOG(info) << "Skipping event " << mEventCounter; + return true; + } + } + } + LOG(info) << "generateEvent " << mEventCounter; + mPythia.event.reset(); + + mConfigToUse = mOneInjectionPerEvent ? static_cast(gRandom->Uniform(0.f, getNGuns())) : -1; + LOG(info) << "Using configuration " << mConfigToUse << " out of " << getNGuns() << ", of which " << mGunConfigs.size() << " are transport decayed and " << mGunConfigsGenDecayed.size() << " are generator decayed"; + + bool injectedForThisEvent = false; + int nConfig = mGunConfigs.size(); // We start counting from the configurations of the transport decayed particles + for (const ConfigContainer& cfg : mGunConfigsGenDecayed) { + nConfig++; + if (mConfigToUse >= 0 && (nConfig - 1) != mConfigToUse) { + continue; + } + LOG(info) << "Using config container "; + cfg.print(); + if (mUseTriggering) { // Do the triggering + bool doSignal{mEventCounter % (mGapBetweenInjection + 1) == 0}; // Do signal or gap + + if (doSignal) { + LOG(info) << "Generating triggered signal event for particle"; + cfg.print(); + bool satisfiesTrigger = false; + int nTries = 0; + while (!satisfiesTrigger) { + if (!pythiaObjectSignal.next()) { + continue; + } + // Check if triggered condition satisfied - using rapidity instead of eta + for (Long_t j = 0; j < pythiaObjectSignal.event.size(); j++) { + const int& pypid = pythiaObjectSignal.event[j].id(); + const float& pyrapidity = pythiaObjectSignal.event[j].y(); // Using rapidity (y) instead of eta + const float& pypt = pythiaObjectSignal.event[j].pT(); + if (pypid == cfg.mPdg && cfg.mRapidityMin < pyrapidity && pyrapidity < cfg.mRapidityMax && pypt > cfg.mPtMin && pypt < cfg.mPtMax) { + LOG(info) << "Found particle " << j << " " << pypid << " with rapidity " << pyrapidity << " and pT " << pypt << " in event " << mEventCounter << " after " << nTries << " tries"; + satisfiesTrigger = true; + break; + } + } + nTries++; + } + mPythia.event = pythiaObjectSignal.event; + } else { + LOG(info) << "Generating background event " << mEventCounter; + // Generate minimum-bias event + bool lGenerationOK = false; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + } + continue; + } + // Do the injection - using rapidity instead of eta + for (int i{0}; i < cfg.mNInject; ++i) { + const double pt = gRandom->Uniform(cfg.mPtMin, cfg.mPtMax); + const double rapidity = gRandom->Uniform(cfg.mRapidityMin, cfg.mRapidityMax); + const double phi = gRandom->Uniform(0, TMath::TwoPi()); + const double px{pt * std::cos(phi)}; + const double py{pt * std::sin(phi)}; + // Convert rapidity to pz using the relation: pz = pt * sinh(rapidity) + const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); + const double pz{mT * std::sinh(rapidity)}; + const double et{mT * std::cosh(rapidity)}; // Energy E = mT * cosh(y) + + Particle particle; + particle.id(cfg.mPdg); + particle.status(11); + particle.m(cfg.mMass); + particle.px(px); + particle.py(py); + particle.pz(pz); + particle.e(et); + particle.xProd(0.f); + particle.yProd(0.f); + particle.zProd(0.f); + mPythia.particleData.mayDecay(cfg.mPdg, true); // force decay + mPythia.event.append(particle); + } + injectedForThisEvent = true; + } + if (injectedForThisEvent) { + LOG(info) << "Calling next!"; + mPythia.moreDecays(); + mPythia.next(); + if (mPythia.event.size() <= 2) { + LOG(fatal) << "Event size is " << mPythia.event.size() << ", this is not good! Check that the decay actually happened or consider not using the generator decayed particles!"; + } else { + LOG(info) << "Event size is " << mPythia.event.size() << " particles"; + } + } + + if (mVerbose) { + LOG(info) << "Eventlisting"; + mPythia.event.list(1); + mPythia.stat(); + } + return true; + } + + //__________________________________________________________________ + Bool_t importParticles() override + { + if (!mUseTriggering) { // If the triggering is used we handle the the gap when generating the signal + if (mGapBetweenInjection > 0) { + if (mGapBetweenInjection == 1 && mEventCounter % 2 == 0) { + LOG(info) << "Skipping importParticles event " << mEventCounter++; + return true; + } else if (mEventCounter % mGapBetweenInjection != 0) { + LOG(info) << "Skipping importParticles event " << mEventCounter++; + return true; + } + } + } + LOG(info) << "importParticles " << mEventCounter++; + GeneratorPythia8::importParticles(); + int nConfig = 0; + for (const ConfigContainer& cfg : mGunConfigs) { + nConfig++; + if (mConfigToUse >= 0 && (nConfig - 1) != mConfigToUse) { + continue; + } + LOGF(info, "Injecting %i particles with PDG %i, pT in [%f, %f], rapidity in [%f, %f]", cfg.mNInject, cfg.mPdg, cfg.mPtMin, cfg.mPtMax, cfg.mRapidityMin, cfg.mRapidityMax); + + for (int i{0}; i < cfg.mNInject; ++i) { + const double pt = gRandom->Uniform(cfg.mPtMin, cfg.mPtMax); + const double rapidity = gRandom->Uniform(cfg.mRapidityMin, cfg.mRapidityMax); + const double phi = gRandom->Uniform(0, TMath::TwoPi()); + const double px{pt * std::cos(phi)}; + const double py{pt * std::sin(phi)}; + const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); + const double pz{mT * std::sinh(rapidity)}; + const double et{mT * std::cosh(rapidity)}; + + // TParticle::TParticle(Int_t pdg, + // Int_t status, + // Int_t mother1, Int_t mother2, + // Int_t daughter1, Int_t daughter2, + // Double_t px, Double_t py, Double_t pz, Double_t etot, + // Double_t vx, Double_t vy, Double_t vz, Double_t time) + + mParticles.push_back(TParticle(cfg.mPdg, + MCGenStatusEncoding(1, 1).fullEncoding, + -1, -1, + -1, -1, + px, py, pz, et, + 0., 0., 0., 0.)); + // make sure status code is encoded properly. Transport flag will be set by default and we have nothing + // to do since all pushed particles should be tracked. + o2::mcutils::MCGenHelper::encodeParticleStatusAndTracking(mParticles.back()); + } + nConfig++; + } + if (mVerbose) { + LOG(info) << "Printing particles that are appended"; + int n = 0; + for (const auto& p : mParticles) { + LOG(info) << "Particle " << n++ << " is a " << p.GetPdgCode() << " with status " << p.GetStatusCode() << " and px = " << p.Px() << " py = " << p.Py() << " pz = " << p.Pz(); + } + } + return true; + } + + struct ConfigContainer { + ConfigContainer(int input_pdg = 0, int n = 1, + float ptMin = 1, float ptMax = 10, + float rapidityMin = -1, float rapidityMax = 1) : mPdg{input_pdg}, + mNInject{n}, + mPtMin{ptMin}, + mPtMax{ptMax}, + mRapidityMin{rapidityMin}, + mRapidityMax{rapidityMax} + { + mMass = getMassFromPDG(mPdg); + if (mMass <= 0) { + LOG(fatal) << "Could not find mass for mPdg " << mPdg; + } + LOGF(info, "ConfigContainer: mPdg = %i, mNInject = %i, mPtMin = %f, mPtMax = %f, mRapidityMin = %f, mRapidityMax = %f, mMass = %f", + mPdg, mNInject, mPtMin, mPtMax, mRapidityMin, mRapidityMax, mMass); + }; + + ConfigContainer(TObjArray* arr) : ConfigContainer(atoi(arr->At(0)->GetName()), + atoi(arr->At(1)->GetName()), + atof(arr->At(2)->GetName()), + atof(arr->At(3)->GetName()), + atof(arr->At(4)->GetName()), + atof(arr->At(5)->GetName())) + { + bool hasGenDecayed = false; + for (int i = 0; i < arr->GetEntries(); i++) { + const TString n = arr->At(i)->GetName(); + std::cout << n << std::endl; + if (n == "genDecayed") { + hasGenDecayed = true; + break; + } + } + if (hasGenDecayed) { + if (arr->GetEntries() != 7) { + LOG(fatal) << "Wrong number of entries in the configuration array, should be 7, is " << arr->GetEntries(); + } + } else { + if (arr->GetEntries() != 6) { + LOG(fatal) << "Wrong number of entries in the configuration array, should be 6, is " << arr->GetEntries(); + } + } + }; + ConfigContainer(TString line) : ConfigContainer(line.Tokenize(" ")){}; + ConfigContainer(const nlohmann::json& jsonParams) : ConfigContainer(jsonParams["pdg"], + jsonParams["n"], + jsonParams["ptMin"], + jsonParams["ptMax"], + jsonParams["rapidityMin"], + jsonParams["rapidityMax"]){}; + + // Data Members + const int mPdg = 0; + const int mNInject = 1; + const float mPtMin = 1; + const float mPtMax = 10; + const float mRapidityMin = -1.f; + const float mRapidityMax = 1.f; + double mMass = 0.f; + + void print() const + { + LOGF(info, "int mPdg = %i", mPdg); + LOGF(info, "int mNInject = %i", mNInject); + LOGF(info, "float mPtMin = %f", mPtMin); + LOGF(info, "float mPtMax = %f", mPtMax); + LOGF(info, "float mRapidityMin = %f", mRapidityMin); + LOGF(info, "float mRapidityMax = %f", mRapidityMax); + LOGF(info, "double mMass = %f", mMass); + } + }; + + //__________________________________________________________________ + ConfigContainer addGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float rapidityMin = 1, float rapidityMax = 10) + { + if (mUseTriggering) { // If in trigger mode, every particle needs to be generated from pythia + return addGunGenDecayed(input_pdg, nInject, ptMin, ptMax, rapidityMin, rapidityMax); + } + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, rapidityMin, rapidityMax}; + mGunConfigs.push_back(cfg); + return cfg; + } + + //__________________________________________________________________ + ConfigContainer addGun(ConfigContainer cfg) { return addGun(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mRapidityMin, cfg.mRapidityMax); } + + //__________________________________________________________________ + ConfigContainer addGunGenDecayed(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float rapidityMin = 1, float rapidityMax = 10) + { + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, rapidityMin, rapidityMax}; + mGunConfigsGenDecayed.push_back(cfg); + return cfg; + } + + //__________________________________________________________________ + ConfigContainer addGunGenDecayed(ConfigContainer cfg) { return addGunGenDecayed(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mRapidityMin, cfg.mRapidityMax); } + + //__________________________________________________________________ + long int getNGuns() const { return mGunConfigs.size() + mGunConfigsGenDecayed.size(); } + + //__________________________________________________________________ + void print() + { + LOG(info) << "GeneratorPythia8LFRapidity configuration with " << getNGuns() << " guns:"; + LOG(info) << "Particles decayed by the transport:"; + int n = 0; + for (const auto& cfg : mGunConfigs) { + LOG(info) << n++ << "/" << mGunConfigs.size() << ":"; + cfg.print(); + } + n = 0; + LOG(info) << "Particles decayed by the generator:"; + for (const auto& cfg : mGunConfigsGenDecayed) { + LOG(info) << n++ << "/" << mGunConfigs.size() << ":"; + cfg.print(); + } + } + + void setVerbose(bool verbose = true) { mVerbose = verbose; } + + private: + // Configuration + const bool mOneInjectionPerEvent = true; // if true, only one injection per event is performed, i.e. if multiple PDG (including antiparticles) are requested to be injected only one will be done per event + const bool mUseTriggering = false; // if true, use triggering instead of injection + const int mGapBetweenInjection = 0; // Gap between two signal events. 0 means injection at every event + + // Running variables + int mConfigToUse = -1; // Index of the configuration to use + int mEventCounter = 0; // Event counter + bool mVerbose = true; // Verbosity flag + + std::vector mGunConfigs; // List of gun configurations to use + std::vector mGunConfigsGenDecayed; // List of gun configurations to use that will be decayed by the generator + Pythia8::Pythia pythiaObjectSignal; // Signal collision generator + Pythia8::Pythia pythiaObjectMinimumBias; // Minimum bias collision generator +}; + +///___________________________________________________________ +/// Create generator via arrays of entries. By default injecting in every event and all particles +FairGenerator* generateLFRapidity(std::vector PDGs, std::vector nInject, std::vector ptMin, std::vector ptMax, std::vector rapidityMin, std::vector rapidityMax) +{ + const std::vector entries = {PDGs.size(), nInject.size(), ptMin.size(), ptMax.size(), rapidityMin.size(), rapidityMax.size()}; + if (!std::equal(entries.begin() + 1, entries.end(), entries.begin())) { + LOGF(fatal, "Not equal number of entries, check configuration"); + return nullptr; + } + GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(false, 0, false, "", ""); + for (unsigned long i = 0; i < entries[0]; i++) { + multiGun->addGun(PDGs[i], nInject[i], ptMin[i], ptMax[i], rapidityMin[i], rapidityMax[i]); + } + return multiGun; +} + +///___________________________________________________________ +/// Create generator via an array of configurations +FairGenerator* generateLFRapidity(std::vector cfg, + std::vector cfgGenDecayed, + bool injectOnePDGPerEvent = true, + int gapBetweenInjection = 0, + bool useTrigger = false, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") +{ + GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(injectOnePDGPerEvent, gapBetweenInjection, useTrigger, pythiaCfgMb, pythiaCfgSignal); + for (const auto& c : cfg) { + LOGF(info, "Adding gun %i", multiGun->getNGuns()); + c.print(); + multiGun->addGun(c); + } + for (const auto& c : cfgGenDecayed) { + LOGF(info, "Adding gun %i, particle will be decayed by the generator", multiGun->getNGuns()); + c.print(); + multiGun->addGunGenDecayed(c); + } + multiGun->print(); + return multiGun; +} + +///___________________________________________________________ +/// Create generator via input file +FairGenerator* generateLFRapidity(std::string configuration = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/nuclei_rapidity.gun", + bool injectOnePDGPerEvent = true, + int gapBetweenInjection = 0, + bool useTrigger = false, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") +{ + configuration = gSystem->ExpandPathName(configuration.c_str()); + LOGF(info, "Using configuration file '%s'", configuration.c_str()); + std::ifstream inputFile(configuration.c_str(), ios::in); + std::vector cfgVec; + std::vector cfgVecGenDecayed; + if (!inputFile.is_open()) { + LOGF(fatal, "Can't open '%s' !", configuration.c_str()); + return nullptr; + } + if (TString(configuration.c_str()).EndsWith(".json")) { // read from JSON file + nlohmann::json paramfile = nlohmann::json::parse(inputFile); + std::cout << "paramfile " << paramfile << std::endl; + for (const auto& param : paramfile) { + std::cout << param << std::endl; + // cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{paramfile[n].template get(), param}); + if (param["genDecayed"]) { + cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param}); + } else { + cfgVec.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param}); + } + } + } else { + std::string l; + int n = 0; + while (getline(inputFile, l)) { + TString line = l; + line.Strip(TString::kBoth, ' '); + std::cout << n++ << " '" << line << "'" << endl; + if (line.IsNull() || line.IsWhitespace()) { + continue; + } + if (line.BeginsWith("#")) { + std::cout << "Skipping\n"; + continue; + } + if (line.Contains("genDecayed")) { + cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{line}); + } else { + cfgVec.push_back(GeneratorPythia8LFRapidity::ConfigContainer{line}); + } + } + } + return generateLFRapidity(cfgVec, cfgVecGenDecayed, injectOnePDGPerEvent, gapBetweenInjection, useTrigger, pythiaCfgMb, pythiaCfgSignal); +} + +///___________________________________________________________ +/// Create generator via input file for the triggered mode +FairGenerator* generateLFRapidityTriggered(std::string configuration = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/nuclei_rapidity.gun", + int gapBetweenInjection = 0, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") +{ + return generateLFRapidity(configuration, /*injectOnePDGPerEvent=*/true, gapBetweenInjection, /*useTrigger=*/true, pythiaCfgMb, pythiaCfgSignal); +} + +///___________________________________________________________ +void generator_pythia8_LF_rapidity(bool testInj = true, bool testTrg = false, const char* particleListFile = "cfg_rapidity.json") +{ + LOG(info) << "Compiled correctly!"; + if (!testInj && !testTrg) { + return; + } + // Injected mode + if (testInj) { + LOG(info) << "Testing the injected mode"; + auto* gen = static_cast(generateLFRapidity(particleListFile)); + gen->setVerbose(); + gen->Print(); + gen->print(); + gen->Init(); + gen->generateEvent(); + gen->importParticles(); + } + + // Triggered mode + if (testTrg) { + LOG(info) << "Testing the triggered mode"; + GeneratorPythia8LFRapidity* gen = static_cast(generateLFRapidityTriggered(particleListFile, + /*gapBetweenInjection=*/0, + /*pythiaCfgMb=*/"inel136tev.cfg", + /*pythiaCfgSignal=*/"inel136tev.cfg")); + gen->setVerbose(); + gen->Print(); + gen->print(); + gen->Init(); + gen->generateEvent(); + gen->importParticles(); + } +} From d59baadf41fcb12c0c0bd2f67422447f8e73437a Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 7 Oct 2025 15:41:55 +0200 Subject: [PATCH 144/362] Fix name of ITS QC tasks Should contain 'QC' for regex filtering --- MC/bin/o2dpg_qc_finalization_workflow.py | 4 ++-- MC/bin/o2dpg_sim_workflow.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MC/bin/o2dpg_qc_finalization_workflow.py b/MC/bin/o2dpg_qc_finalization_workflow.py index 31f0b48a3..3576d1fc9 100755 --- a/MC/bin/o2dpg_qc_finalization_workflow.py +++ b/MC/bin/o2dpg_qc_finalization_workflow.py @@ -102,8 +102,8 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif add_QC_finalization('TOFMatchQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tofMatchedTracks_ITSTPCTOF_TPCTOF_direct_MC.json') add_QC_finalization('tofDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tofdigits.json') add_QC_finalization('TOFMatchWithTRDQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tofMatchedTracks_AllTypes_direct_MC.json') - add_QC_finalization('ITSTrackSimTask', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-mc-tracks-qc.json') - add_QC_finalization('ITSTracksClusters', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-clusters-tracks-qc.json') + add_QC_finalization('ITSTrackSimTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-mc-tracks-qc.json') + add_QC_finalization('ITSTracksClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-clusters-tracks-qc.json') if isActive('MID'): add_QC_finalization('MIDTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mid-task.json') if isActive('MCH'): diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 5431429a3..ca236d2a3 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1938,12 +1938,12 @@ def remove_json_prefix(path): readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC,ITS-TPC-TRD,ITS-TPC-TRD-TOF,TPC-TRD,TPC-TRD-TOF" --cluster-types none', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tofMatchedTracks_AllTypes_direct_MC.json') ### ITS - addQCPerTF(taskName='ITSTrackSimTask', + addQCPerTF(taskName='ITSTrackSimTaskQC', needs=[ITSRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS" --cluster-types "ITS"', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/its-mc-tracks-qc.json') - addQCPerTF(taskName='ITSTracksClusters', + addQCPerTF(taskName='ITSTracksClustersQC', needs=[ITSRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS" --cluster-types "ITS"', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/its-clusters-tracks-qc.json') From 29a51c56be6be9c7318046a78ab70a15af6d0e57 Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 4 Nov 2025 15:53:34 +0100 Subject: [PATCH 145/362] Optionally add sync TPC reco mode TPC sync. reco. mode with clusters rejection is added is if ALIEN_JDL_DOTPCSYNCMODE=1 env.var is defined. In this case the original tpc-native-clusters.root file is used as an input to TPC sync. reco. and overwritten by it. --- MC/bin/o2dpg_sim_workflow.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index ca236d2a3..b2eebf835 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -491,14 +491,17 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): includeLocalQC=args.include_local_qc=='True' or args.include_local_qc==True includeAnalysis = args.include_analysis includeTPCResiduals=True if environ.get('ALIEN_JDL_DOTPCRESIDUALEXTRACTION') == '1' else False +includeTPCSyncMode=True if environ.get('ALIEN_JDL_DOTPCSYNCMODE') == '1' else False ccdbRemap = environ.get('ALIEN_JDL_REMAPPINGS') qcdir = "QC" if (includeLocalQC or includeFullQC) and not isdir(qcdir): mkdir(qcdir) -def getDPL_global_options(bigshm=False, ccdbbackend=True): - common=" -b --run " +def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): + common=" " + if runcommand: + common=common + ' -b --run ' if len(args.dpl_child_driver) > 0: common=common + ' --child-driver ' + str(args.dpl_child_driver) if ccdbbackend: @@ -1015,15 +1018,15 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): if (args.sor != -1): globalTFConfigValues["HBFUtils.startTime"] = args.sor - def putConfigValues(listOfMainKeys=[], localCF = {}): + def putConfigValues(listOfMainKeys=[], localCF = {}, globalTFConfig = True): """ Creates the final --configValues string to be passed to the workflows. Uses the globalTFConfigValues and applies other parameters on top listOfMainKeys : list of keys to be applied from the global configuration object localCF: a dictionary mapping key to param - possibly overrides settings taken from global config """ - returnstring = ' --configKeyValues "' - cf = globalTFConfigValues.copy() + returnstring = ' --configKeyValues "' + cf = globalTFConfigValues.copy() if globalTFConfig else {} isfirst=True # now bring in the relevant keys @@ -1284,6 +1287,27 @@ def getDigiTaskName(det): # tpc_corr_scaling_options = ('--lumi-type 1', '')[tpcDistortionType != 0] #<--------- TPC reco task + if includeTPCSyncMode: + tpcSyncreconeeds = tpcreconeeds.copy() + TPCSyncRECOtask=createTask(name='tpcSyncreco_'+str(tf), needs=tpcSyncreconeeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], relative_cpu=3/8, mem='16000') + TPCSyncRECOtask['cmd'] = '${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options(bigshm=True, ccdbbackend=False, runcommand=False) \ + + '--input-type clusters --output-type clusters,disable-writer ' \ + + putConfigValues() + TPCSyncRECOtask['cmd'] += ' | ${O2_ROOT}/bin/o2-gpu-reco-workflow' + getDPL_global_options(bigshm=True, ccdbbackend=True, runcommand=False) \ + + '--input-type clusters --output-type compressed-clusters-flat,clusters,send-clusters-per-sector --filtered-output-specs ' \ + + tpc_corr_scaling_options + ' ' + tpc_corr_options_mc \ + + putConfigValues(["TPCGasParam", "TPCCorrMap", "trackTuneParams"], + localCF={"GPU_proc.ompThreads":NWORKERS_TF, \ + "GPU_proc.tpcWriteClustersAfterRejection":1, \ + "GPU_rec_tpc.compressionTypeMask":0, \ + "GPU_global.synchronousProcessing":1, \ + "GPU_proc.tpcIncreasedMinClustersPerRow":500000}, + globalTFConfig=False) + TPCSyncRECOtask['cmd'] += ' | ${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options(bigshm=True, ccdbbackend=False, runcommand=True) + ' --filtered-input --input-type pass-through --output-type clusters,send-clusters-per-sector ' + TPCSyncRECOtask['cmd'] += ' ; mv tpc-filtered-native-clusters.root tpc-native-clusters.root' + workflow['stages'].append(TPCSyncRECOtask) + tpcreconeeds.append(TPCSyncRECOtask['name']) + TPCRECOtask=createTask(name='tpcreco_'+str(tf), needs=tpcreconeeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], relative_cpu=3/8, mem='16000') TPCRECOtask['cmd'] = task_finalizer([ '${O2_ROOT}/bin/o2-tpc-reco-workflow', From 9abc9395cd3a5c8ff271c99e007ebba120a7a465 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 6 Nov 2025 18:31:24 +0100 Subject: [PATCH 146/362] Make TRD optional; Anchoring improvements * respect ALIEN_JDL_WORKFLOWDETECTORS in anchoring python script * take out TRD from workflow when not readout * bugfix for fetching options from anchoring JSON (was lacking '--') --- MC/bin/o2dpg_dpl_config_tools.py | 6 ++- MC/bin/o2dpg_qc_finalization_workflow.py | 5 ++- MC/bin/o2dpg_sim_workflow.py | 49 ++++++++++++++---------- MC/bin/o2dpg_sim_workflow_anchored.py | 14 +++++++ 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/MC/bin/o2dpg_dpl_config_tools.py b/MC/bin/o2dpg_dpl_config_tools.py index 388e4306f..6849ea3dc 100755 --- a/MC/bin/o2dpg_dpl_config_tools.py +++ b/MC/bin/o2dpg_dpl_config_tools.py @@ -309,7 +309,11 @@ def dpl_option_from_config(config, dpl_workflow, key, section = "filtered", defa """ if "Executables" in config: # new standard - return config["Executables"].get(dpl_workflow,{}).get(section,{}).get(key, default_value) + value = config["Executables"].get(dpl_workflow,{}).get(section,{}).get(key, None) + if value == None: + print (f"Could not lookup key/option {key} from {dpl_workflow}") + value = default_value + return value else: # backward compatible versions dpl_workflow_key = dpl_workflow + '-options' diff --git a/MC/bin/o2dpg_qc_finalization_workflow.py b/MC/bin/o2dpg_qc_finalization_workflow.py index 3576d1fc9..45d4ffd77 100755 --- a/MC/bin/o2dpg_qc_finalization_workflow.py +++ b/MC/bin/o2dpg_qc_finalization_workflow.py @@ -95,8 +95,9 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif add_QC_finalization('emcBCQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') #add_QC_finalization('tpcTrackingQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-tracking-direct.json') add_QC_finalization('tpcStandardQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-standard-direct.json') - add_QC_finalization('trdDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') - add_QC_finalization('trdTrackingQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-tracking-task.json') + if isActive('TRD'): + add_QC_finalization('trdDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') + add_QC_finalization('trdTrackingQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-tracking-task.json') add_QC_finalization('vertexQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/vertexing-qc-direct-mc.json') add_QC_finalization('ITSTPCmatchQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/ITSTPCmatchedTracks_direct_MC.json') add_QC_finalization('TOFMatchQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tofMatchedTracks_ITSTPCTOF_TPCTOF_direct_MC.json') diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index b2eebf835..39235f6c2 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -261,7 +261,7 @@ def load_external_config(configfile): # these are all detectors that should be assumed active readout_detectors = args.readoutDets # here are all detectors that have been set in an anchored script -activeDetectors = dpl_option_from_config(anchorConfig, 'o2-ctf-reader-workflow', key='onlyDet', default_value='all') +activeDetectors = dpl_option_from_config(anchorConfig, 'o2-ctf-reader-workflow', key='--onlyDet', default_value='all') if activeDetectors == 'all': # if "all" here, there was in fact nothing in the anchored script, set to what is passed to this script (which it either also "all" or a subset) activeDetectors = readout_detectors @@ -1125,7 +1125,8 @@ def putConfigValues(listOfMainKeys=[], localCF = {}, globalTFConfig = True): + ' --onlyDet TRD --interactionRate ' + str(INTRATE) + ' --incontext ' + str(CONTEXTFILE) + ' --disable-write-ini' \ + putConfigValues(localCF={"TRDSimParams.digithreads" : NWORKERS_TF, "DigiParams.seed" : str(TFSEED)}) + " --forceSelectedDets" TRDDigitask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(TRDDigitask) + if isActive("TRD"): + workflow['stages'].append(TRDDigitask) # these are digitizers which are single threaded def createRestDigiTask(name, det='ALLSMALLER'): @@ -1385,12 +1386,13 @@ def getDigiTaskName(det): getDPL_global_options(), putConfigValues(), ('',' --disable-mc')[args.no_mc_labels]]) - workflow['stages'].append(TRDTRACKINGtask) + if isActive("TRD"): + workflow['stages'].append(TRDTRACKINGtask) #<--------- TRD global tracking # FIXME This is so far a workaround to avoud a race condition for trdcalibratedtracklets.root TRDTRACKINGtask2 = createTask(name='trdreco2_'+str(tf), needs=[TRDTRACKINGtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem='2000') - trd_track_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-trd-global-tracking', 'track-sources', default_value='TPC,ITS-TPC')) + trd_track_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-trd-global-tracking', '--track-sources', default_value='TPC,ITS-TPC')) TRDTRACKINGtask2['cmd'] = task_finalizer([ '${O2_ROOT}/bin/o2-trd-global-tracking', getDPL_global_options(bigshm=True), @@ -1405,7 +1407,8 @@ def getDigiTaskName(det): '--track-sources ' + trd_track_sources, tpc_corr_scaling_options, tpc_corr_options_mc]) - workflow['stages'].append(TRDTRACKINGtask2) + if isActive("TRD"): + workflow['stages'].append(TRDTRACKINGtask2) #<--------- TOF reco task TOFRECOtask = createTask(name='tofmatch_'+str(tf), needs=[ITSTPCMATCHtask['name'], getDigiTaskName("TOF")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') @@ -1420,8 +1423,11 @@ def getDigiTaskName(det): workflow['stages'].append(TOFRECOtask) #<--------- TOF-TPC(-ITS) global track matcher workflow - toftpcmatchneeds = [TOFRECOtask['name'], TPCRECOtask['name'], ITSTPCMATCHtask['name'], TRDTRACKINGtask2['name']] - toftracksrcdefault = dpl_option_from_config(anchorConfig, 'o2-tof-matcher-workflow', 'track-sources', default_value='TPC,ITS-TPC,TPC-TRD,ITS-TPC-TRD') + toftpcmatchneeds = [TOFRECOtask['name'], + TPCRECOtask['name'], + ITSTPCMATCHtask['name'], + TRDTRACKINGtask2['name'] if isActive("TRD") else None] + toftracksrcdefault = dpl_option_from_config(anchorConfig, 'o2-tof-matcher-workflow', '--track-sources', default_value='TPC,ITS-TPC,TPC-TRD,ITS-TPC-TRD') tofusefit = option_if_available('o2-tof-matcher-workflow', '--use-fit', envfile=async_envfile) TOFTPCMATCHERtask = createTask(name='toftpcmatch_'+str(tf), needs=toftpcmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') tofmatcher_cmd_parts = [ @@ -1615,9 +1621,9 @@ def getDigiTaskName(det): hmpmatchneeds = [HMPRECOtask['name'], ITSTPCMATCHtask['name'], TOFTPCMATCHERtask['name'] if isActive("TOF") else None, - TRDTRACKINGtask2['name']] + TRDTRACKINGtask2['name'] if isActive("TRD") else None] hmpmatchneeds = [ n for n in hmpmatchneeds if n != None ] - hmp_match_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-hmpid-matcher-workflow', 'track-sources', default_value='ITS-TPC,ITS-TPC-TRD,TPC-TRD')) + hmp_match_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-hmpid-matcher-workflow', '--track-sources', default_value='ITS-TPC,ITS-TPC-TRD,TPC-TRD')) HMPMATCHtask = createTask(name='hmpmatch_'+str(tf), needs=hmpmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') HMPMATCHtask['cmd'] = task_finalizer( ['${O2_ROOT}/bin/o2-hmpid-matcher-workflow', @@ -1630,17 +1636,17 @@ def getDigiTaskName(det): #<---------- primary vertex finding pvfinder_sources = dpl_option_from_config(anchorConfig, 'o2-primary-vertexing-workflow', - 'vertexing-sources', + '--vertexing-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') pvfinder_sources = cleanDetectorInputList(pvfinder_sources) pvfinder_matching_sources = dpl_option_from_config(anchorConfig, 'o2-primary-vertexing-workflow', - 'vertex-track-matching-sources', + '--vertex-track-matching-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') pvfinder_matching_sources = cleanDetectorInputList(pvfinder_matching_sources) - pvfinderneeds = [TRDTRACKINGtask2['name'], + pvfinderneeds = [TRDTRACKINGtask2['name'] if isActive("TRD") else None, FT0RECOtask['name'] if isActive("FT0") else None, FV0RECOtask['name'] if isActive("FV0") else None, EMCRECOtask['name'] if isActive("EMC") else None, @@ -1682,7 +1688,7 @@ def getDigiTaskName(det): svfinder_sources = dpl_option_from_config(anchorConfig, 'o2-primary-vertexing-workflow', - 'vertex-track-matching-sources', + '--vertex-track-matching-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP') svfinder_sources = cleanDetectorInputList(svfinder_sources) SVFINDERtask = createTask(name='svfinder_'+str(tf), needs=[PVFINDERtask['name'], FT0FV0EMCCTPDIGItask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=svfinder_cpu, mem='5000') @@ -1703,7 +1709,7 @@ def getDigiTaskName(det): #<------------- AOD producer # TODO This needs further refinement, sources and dependencies should be constructed dynamically aod_info_souces_default = 'ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP' - aodinfosources = dpl_option_from_config(anchorConfig, 'o2-aod-producer-workflow', 'info-sources', default_value=aod_info_souces_default) + aodinfosources = dpl_option_from_config(anchorConfig, 'o2-aod-producer-workflow', '--info-sources', default_value=aod_info_souces_default) aodinfosources = cleanDetectorInputList(aodinfosources) aodneeds = [PVFINDERtask['name'], SVFINDERtask['name']] @@ -1760,17 +1766,17 @@ def getDigiTaskName(det): #<------------- TPC residuals extraction scdcalib_vertex_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tpc-scdcalib-interpolation-workflow', - 'vtx-sources', + '--vtx-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP')) scdcalib_track_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tpc-scdcalib-interpolation-workflow', - 'tracking-sources', + '--tracking-sources', default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP')) scdcalib_track_extraction = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tpc-scdcalib-interpolation-workflow', - 'tracking-sources-map-extraction', + '--tracking-sources-map-extraction', default_value='ITS-TPC')) SCDCALIBtask = createTask(name='scdcalib_'+str(tf), needs=[PVFINDERtask['name']], tf=tf, cwd=timeframeworkdir, lab=["CALIB"], mem='4000') @@ -1789,11 +1795,11 @@ def getDigiTaskName(det): #<------------- TPC residuals aggregator scdaggreg_secperslot = dpl_option_from_config(anchorConfig, 'o2-calibration-residual-aggregator', - 'sec-per-slot', + '--sec-per-slot', default_value='600') scdaggreg_outputtype = dpl_option_from_config(anchorConfig, 'o2-calibration-residual-aggregator', - 'output-type', + '--output-type', default_value='trackParams,unbinnedResid') SCDAGGREGtask = createTask(name='scdaggreg_'+str(tf), needs=[SCDCALIBtask['name']], tf=tf, cwd=timeframeworkdir, lab=["CALIB"], mem='1500') @@ -1873,12 +1879,13 @@ def remove_json_prefix(path): ### TRD # TODO: check if the readerCommand also reperforms tracklet construction (which already done in digitization) - addQCPerTF(taskName='trdDigitsQC', + if isActive('TRD'): + addQCPerTF(taskName='trdDigitsQC', needs=[TRDDigitask['name']], readerCommand='o2-trd-trap-sim --disable-root-output true', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') - addQCPerTF(taskName='trdTrackingQC', + addQCPerTF(taskName='trdTrackingQC', needs=[TRDTRACKINGtask2['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TRD,TPC-TRD" --cluster-types none', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/trd-tracking-task.json') diff --git a/MC/bin/o2dpg_sim_workflow_anchored.py b/MC/bin/o2dpg_sim_workflow_anchored.py index 57e6676b6..9a7002bf2 100755 --- a/MC/bin/o2dpg_sim_workflow_anchored.py +++ b/MC/bin/o2dpg_sim_workflow_anchored.py @@ -122,6 +122,14 @@ def retrieve_Aggregated_RunInfos(run_number): detList = o2.detectors.DetID.getNames(runInfo.grpECS.getDetsReadOut()) assert (run_number == runInfo.runNumber) assert (run_number == runInfo.grpECS.getRun()) + + print (f"Detector list from RunInfo/GRPECS is {detList}") + # potential overwrite in detector list if special env variable ALIEN_JDL_WORKFLOWDETECTORS is set + detlist_overwrite = os.getenv("ALIEN_JDL_WORKFLOWDETECTORS") + if detlist_overwrite: + detList = detlist_overwrite + print (f"Detector list is overwritten to {detList} via JDL") + return {"SOR" : runInfo.sor, "EOR" : runInfo.eor, "FirstOrbit" : runInfo.orbitSOR, @@ -218,6 +226,12 @@ def retrieve_params_fromGRPECS_and_OrbitReset(ccdbreader, run_number, run_start, detList = o2.detectors.DetID.getNames(grp["mDetsReadout"]['v']) print ("Detector list is ", detList) + # potential reduction in detector list if special env variable ALIEN_JDL_WORKFLOWDETECTORS is set + detlist_overwrite = os.getenv("ALIEN_JDL_WORKFLOWDETECTORS") + if detlist_overwrite: + detList = detlist_overwrite + print ("Detector list is overwritten to ", detList) + # orbitReset.get(run_number) return {"FirstOrbit" : orbitFirst, "LastOrbit" : orbitLast, "OrbitsPerTF" : int(grp["mNHBFPerTF"]), "detList" : detList} From 13773b58bbb69c7afec4cc94522c031d06f8d67e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Mon, 10 Nov 2025 13:01:47 +0100 Subject: [PATCH 147/362] EPOS: add pp 13.6 TeV (#2176) * EPOS: Increase number of freeze out events to 10 * Create 13.6 epos configuration * Fix * Fix --- .../generator/pp_136TeV_hydro_cascade.optns | 32 +++++++++++++++++++ .../examples/ini/GeneratorEPOS4_pp136TeV.ini | 12 +++++++ 2 files changed, 44 insertions(+) create mode 100644 MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns create mode 100644 MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini diff --git a/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns new file mode 100644 index 000000000..1e4b8ea66 --- /dev/null +++ b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 13.6 TeV with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13600 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 10 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini new file mode 100644 index 000000000..8375cb7f3 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini @@ -0,0 +1,12 @@ +#---> GeneratorEPOS4 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 From b8289dc47aecec7a15ba2f1f7e3b4635e6fdd23c Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Tue, 11 Nov 2025 13:46:56 +0100 Subject: [PATCH 148/362] MC/PWGEM: add cfg and ini for VM2ll (#2172) * MC/PWGEM: add cfg and ini for VM2ll * Comment out Pythia8 function Comment out the Pythia8 function to disable it. * Update pythia8_OO_536_VM2ll.C --- MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini | 9 +++ .../PWGEM/ini/tests/pythia8_OO_536_VM2ll.C | 56 +++++++++++++++++++ .../generator/pythia8_OO_536_VM2ll.cfg | 21 +++++++ 3 files changed, 86 insertions(+) create mode 100644 MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini create mode 100644 MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini new file mode 100644 index 000000000..953d909ce --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C new file mode 100644 index 000000000..9250232c0 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} + +//int Pythia8() +//{ +// return External(); +//} diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg new file mode 100644 index 000000000..596a85beb --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg @@ -0,0 +1,21 @@ +### OO beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +Random:setSeed = on + +# change omega, phi meson's BR below +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 From ccb9ff34f6eb205885f62033a89f256697c4a0a1 Mon Sep 17 00:00:00 2001 From: mbroz84 Date: Thu, 13 Nov 2025 15:08:37 +0100 Subject: [PATCH 149/362] Adjustments for new STARlight version (#2173) * Adjustments for new STARlight version * Kstar decay --- .../generator/DecayTablesEvtGen/OPENCHARM.DEC | 8 ++++ .../external/generator/GeneratorStarlight.C | 48 ++++++++++--------- .../generator/GeneratorStarlightToEvtGen.C | 9 ++-- .../PWGUD/trigger/triggerDpmjetParticle.C | 18 +++---- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC index d35930c4a..c8e964d75 100644 --- a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC @@ -42,4 +42,12 @@ Decay phi 1.0 K+ K- VSS; #[Reconstructed PDG2011] Enddecay +Decay K*0 +1.0 K+ pi- VSS; +Enddecay + +Decay anti-K*0 +1.0 K- pi+ VSS; +Enddecay + End diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlight.C b/MC/config/PWGUD/external/generator/GeneratorStarlight.C index 91a6d2776..1cf323ff9 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlight.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlight.C @@ -77,14 +77,14 @@ class GeneratorStarlight_class : public Generator bool Init() override { Generator::Init(); - + float beam1energy = TMath::Sqrt(Double_t(projZ)/projA*targA/targZ)*eCM/2; float beam2energy = TMath::Sqrt(Double_t(projA)/projZ*targZ/targA)*eCM/2; float gamma1 = beam1energy/0.938272; float gamma2 = beam2energy/0.938272; float rapMax = 4.1 + 0.5*(TMath::ACosH(gamma2)-TMath::ACosH(gamma1)); float dy = 0.01; - + const struct SLConfig { const char* name; int prod_mode; @@ -166,14 +166,14 @@ class GeneratorStarlight_class : public Generator break; } } - + if (idx == -1) { std::cout << "STARLIGHT process "<< mSelectedConfiguration <<" is not supported" << std::endl; return false; } - + mPdgMother = slConfig[idx].pdg_mother; - mDecayEvtGen = slConfig[idx].decay_EvtGen; + mDecayEvtGen = slConfig[idx].decay_EvtGen; unsigned int random_seed = generateRandomSeed(); @@ -211,6 +211,8 @@ class GeneratorStarlight_class : public Generator if(slConfig[idx].prod_mode == 5 || slConfig[idx].prod_mode == 6 || slConfig[idx].prod_mode == 7){ setParameter("MIN_GAMMA_ENERGY = 1000.0"); setParameter("MAX_GAMMA_ENERGY = 600000.0"); + setParameter("KEEP_PHI = 1"); + setParameter("KEEP_KSTAR = 1"); } TString extraPars(mExtraParams); @@ -221,18 +223,18 @@ class GeneratorStarlight_class : public Generator if (not mInputParameters.init()) { std::cout << "InitStarLight parameter initialization has failed" << std::endl; return false; - } - + } + mStarLight = new starlight; mStarLight->setInputParameters(&mInputParameters); mRandomGenerator.SetSeed(mInputParameters.randomSeed()); - mStarLight->setRandomGenerator(&mRandomGenerator); - return mStarLight->init(); - + mStarLight->setRandomGenerator(&mRandomGenerator); + return mStarLight->init(); + }; - - bool generateEvent() override { - + + bool generateEvent() override { + if (!mStarLight) { std::cout <<"GenerateEvent: StarLight class/object not properly constructed"<produceEvent(); // boost event to the experiment CM frame mEvent.boost(0.5*(TMath::ACosH(mInputParameters.beam1LorentzGamma()) - TMath::ACosH(mInputParameters.beam2LorentzGamma()))); - - return true; - + + return true; + }; // at importParticles we add particles to the output particle vector // according to the selected configuration bool importParticles() override - { + { int nVtx(0); float vtx(0), vty(0), vtz(0), vtt(0); const std::vector* slVtx; @@ -327,9 +329,9 @@ class GeneratorStarlight_class : public Generator //particle.Print(); mParticles.push_back(particle); o2::mcutils::MCGenHelper::encodeParticleStatusAndTracking(mParticles.back(), true); - } + } } - return true; + return true; } protected: @@ -340,7 +342,7 @@ class GeneratorStarlight_class : public Generator int targZ=82; private: - starlight *mStarLight = 0x0; + starlight *mStarLight = 0x0; inputParameters mInputParameters; // simulation input information. randomGenerator mRandomGenerator; // STARLIGHT's own random generator upcXEvent mEvent; // object holding STARlight simulated event. @@ -350,12 +352,12 @@ class GeneratorStarlight_class : public Generator int mPdgMother = -1; bool mDecayEvtGen = 0; - + }; - + } // namespace eventgen } // namespace o2 - + FairGenerator* GeneratorStarlight(std::string configuration = "empty",float energyCM = 5020, int beam1Z = 82, int beam1A = 208, int beam2Z = 82, int beam2A = 208, std::string extrapars = "",std::string dpmjetconf = "") diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C b/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C index 3bf3afaa6..dcb9a967f 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C @@ -18,7 +18,7 @@ FairGenerator* gen->AddPdg(-15,1); } else if(configuration.find("kDpmjet") != std::string::npos){ - gen->SetSizePdg(11); + gen->SetSizePdg(14); gen->AddPdg( 411,0); gen->AddPdg(-411,1); gen->AddPdg( 421,2); @@ -30,6 +30,9 @@ FairGenerator* gen->AddPdg( 4122,8); gen->AddPdg(-4122,9); gen->AddPdg( 333,10); + gen->AddPdg(-333,11); + gen->AddPdg( 313,12); + gen->AddPdg(-313,13); } else{ gen->SetPolarization(1); //Transversal @@ -38,7 +41,7 @@ FairGenerator* gen->AddPdg(100443,1); gen->AddPdg(223,2); } - + TString pathO2 = gSystem->ExpandPathName("$O2DPG_MC_CONFIG_ROOT/MC/config/PWGUD/external/generator/DecayTablesEvtGen"); if (configuration.find("Psi2sToMuPi") != std::string::npos) gen->SetDecayTable(Form("%s/PSI2S.MUMUPIPI.DEC",pathO2.Data())); else if (configuration.find("Psi2sToElPi") != std::string::npos) gen->SetDecayTable(Form("%s/PSI2S.EEPIPI.DEC",pathO2.Data())); @@ -53,6 +56,6 @@ FairGenerator* else if (configuration.find("Jpsi4Prong") != std::string::npos) gen->SetDecayTable(Form("%s/JPSI.4PRONG.DEC",pathO2.Data())); else if (configuration.find("Jpsi6Prong") != std::string::npos) gen->SetDecayTable(Form("%s/JPSI.6PRONG.DEC",pathO2.Data())); else if (configuration.find("Dpmjet") != std::string::npos) gen->SetDecayTable(Form("%s/OPENCHARM.DEC",pathO2.Data())); - + return gen; } diff --git a/MC/config/PWGUD/trigger/triggerDpmjetParticle.C b/MC/config/PWGUD/trigger/triggerDpmjetParticle.C index 9d3a99c00..ada196467 100644 --- a/MC/config/PWGUD/trigger/triggerDpmjetParticle.C +++ b/MC/config/PWGUD/trigger/triggerDpmjetParticle.C @@ -14,7 +14,7 @@ o2::eventgen::Trigger triggerDzero(double rapidityMin = -1., double rapidityMax if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) return kTRUE; } - return kFALSE; + return kFALSE; }; } @@ -45,10 +45,10 @@ o2::eventgen::Trigger triggerDstar(double rapidityMin = -1., double rapidityMax o2::eventgen::Trigger triggerPhi(double rapidityMin = -1., double rapidityMax = -1.) { return [rapidityMin, rapidityMax](const std::vector& particles) -> bool { - for (std::vector::size_type i = 0; i != (particles.size()-1); i++) { - if ((particles[i].GetPdgCode() == 321 && particles[i+1].GetPdgCode() == -321) || (particles[i].GetPdgCode() == -321 && particles[i+1].GetPdgCode() == 321)) - if ((particles[i].Eta() > rapidityMin) && (particles[i].Eta() < rapidityMax) && (particles[i+1].Eta() > rapidityMin) && (particles[i+1].Eta() < rapidityMax)) - return kTRUE; + for (const auto& particle : particles) { + if (TMath::Abs(particle.GetPdgCode()) == 333) + if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) + return kTRUE; } return kFALSE; }; @@ -57,10 +57,10 @@ o2::eventgen::Trigger triggerPhi(double rapidityMin = -1., double rapidityMax = o2::eventgen::Trigger triggerKstar(double rapidityMin = -1., double rapidityMax = -1.) { return [rapidityMin, rapidityMax](const std::vector& particles) -> bool { - for (std::vector::size_type i = 0; i != (particles.size()-1); i++) { - if ((particles[i].GetPdgCode() == 321 && particles[i+1].GetPdgCode() == -211) || (particles[i].GetPdgCode() == -211 && particles[i+1].GetPdgCode() == 321)) - if ((particles[i].Eta() > rapidityMin) && (particles[i].Eta() < rapidityMax) && (particles[i+1].Eta() > rapidityMin) && (particles[i+1].Eta() < rapidityMax)) - return kTRUE; + for (const auto& particle : particles) { + if (TMath::Abs(particle.GetPdgCode()) == 313) + if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) + return kTRUE; } return kFALSE; }; From 14a6c0547467d646c19cc1d6c9bb4d82308aca3a Mon Sep 17 00:00:00 2001 From: sawan <124118453+sawankumawat@users.noreply.github.com> Date: Sun, 16 Nov 2025 09:42:21 +0530 Subject: [PATCH 150/362] added f2(1270), a2(1320) resonances (#2182) --- .../generator/resonancelistgun_exotic.json | 37 ++++++++++++------- .../resonancelistgun_exotic_pbpb.json | 37 ++++++++++++------- .../PWGLF/pythia8/generator/resonances.cfg | 18 +++++++-- 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json index 8f6e78f1d..870beacdf 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json @@ -1,5 +1,5 @@ { - "f_0(980)" : { + "f_0(980)": { "pdg": 9010221, "n": 1, "ptMin": 0.0, @@ -10,7 +10,18 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1370)" : { + "f_2(1270)": { + "pdg": 225, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, + "f_0(1370)": { "pdg": 10221, "n": 1, "ptMin": 0.0, @@ -21,7 +32,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1500)" : { + "f_0(1500)": { "pdg": 9030221, "n": 1, "ptMin": 0.0, @@ -32,7 +43,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1710)" : { + "f_0(1710)": { "pdg": 10331, "n": 1, "ptMin": 0.0, @@ -43,7 +54,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_1(1285)" : { + "f_1(1285)": { "pdg": 20223, "n": 1, "ptMin": 0.0, @@ -54,7 +65,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_1(1420)" : { + "f_1(1420)": { "pdg": 20333, "n": 1, "ptMin": 0.0, @@ -65,7 +76,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_2(1525)" : { + "f_2(1525)": { "pdg": 335, "n": 1, "ptMin": 0.0, @@ -76,7 +87,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "a_2(1230)" : { + "a_2(1230)": { "pdg": 115, "n": 1, "ptMin": 0.0, @@ -109,7 +120,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)0" : { + "Xi(1820)0": { "pdg": 123314, "n": 1, "ptMin": 0.0, @@ -120,7 +131,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Anti-Xi(1820)0" : { + "Anti-Xi(1820)0": { "pdg": -123314, "n": 1, "ptMin": 0.0, @@ -131,7 +142,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)-" : { + "Xi(1820)-": { "pdg": 123324, "n": 1, "ptMin": 0.0, @@ -142,7 +153,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)+" : { + "Xi(1820)+": { "pdg": -123324, "n": 1, "ptMin": 0.0, @@ -153,4 +164,4 @@ "rapidityMax": 1.2, "genDecayed": true } -} +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json index 326752866..780b2969a 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json @@ -1,5 +1,5 @@ { - "f_0(980)" : { + "f_0(980)": { "pdg": 9010221, "n": 10, "ptMin": 0.0, @@ -10,7 +10,18 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1370)" : { + "f_2(1270)": { + "pdg": 225, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, + "f_0(1370)": { "pdg": 10221, "n": 10, "ptMin": 0.0, @@ -21,7 +32,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1500)" : { + "f_0(1500)": { "pdg": 9030221, "n": 10, "ptMin": 0.0, @@ -32,7 +43,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1710)" : { + "f_0(1710)": { "pdg": 10331, "n": 10, "ptMin": 0.0, @@ -43,7 +54,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_1(1285)" : { + "f_1(1285)": { "pdg": 20223, "n": 10, "ptMin": 0.0, @@ -54,7 +65,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_1(1420)" : { + "f_1(1420)": { "pdg": 20333, "n": 10, "ptMin": 0.0, @@ -65,7 +76,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "f_2(1525)" : { + "f_2(1525)": { "pdg": 335, "n": 10, "ptMin": 0.0, @@ -76,7 +87,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "a_2(1230)" : { + "a_2(1230)": { "pdg": 115, "n": 1, "ptMin": 0.0, @@ -109,7 +120,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)0" : { + "Xi(1820)0": { "pdg": 123314, "n": 10, "ptMin": 0.0, @@ -120,7 +131,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Anti-Xi(1820)0" : { + "Anti-Xi(1820)0": { "pdg": -123314, "n": 10, "ptMin": 0.0, @@ -131,7 +142,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)-" : { + "Xi(1820)-": { "pdg": 123324, "n": 10, "ptMin": 0.0, @@ -142,7 +153,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)+" : { + "Xi(1820)+": { "pdg": -123324, "n": 10, "ptMin": 0.0, @@ -153,4 +164,4 @@ "rapidityMax": 1.2, "genDecayed": true } -} +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/resonances.cfg b/MC/config/PWGLF/pythia8/generator/resonances.cfg index 1058a9488..b9d2750eb 100644 --- a/MC/config/PWGLF/pythia8/generator/resonances.cfg +++ b/MC/config/PWGLF/pythia8/generator/resonances.cfg @@ -60,22 +60,32 @@ ProcessLevel:all = off # will not look for the 'process' 20333:onIfMatch = 310 321 -211 ### glueball hunting -9030221:all = f_0(1500) f_0(1500) 3 0 0 1.50600 0.11200 1.40000 1.60000 0 +9030221:all = f_0(1500) f_0(1500) 0 0 0 1.50600 0.11200 1.40000 1.60000 0 9030221:oneChannel = 1 1.000 0 310 310 9030221:onMode = off 9030221:onIfMatch = 310 310 -10331:all = f_0(1710) f_0(1710) 3 0 0 1.72000 0.13500 1.10000 2.40000 0 +10331:all = f_0(1710) f_0(1710) 0 0 0 1.71000 0.15000 1.10000 2.40000 0 10331:oneChannel = 1 1.000 0 310 310 10331:onMode = off 10331:onIfMatch = 310 310 -335:all = f_2(1525) f_2(1525) 5 0 0 1.52500 0.07300 1.10000 2.00000 0 +335:all = f_2(1525) f_2(1525) 4 0 0 1.52500 0.08400 1.10000 2.00000 0 335:oneChannel = 1 1.000 0 310 310 335:onMode = off 335:onIfMatch = 310 310 -10221:all = f_0(1370) f_0(1370) 3 0 0 1.35000 0.20000 0.80000 2.00000 0 +10221:all = f_0(1370) f_0(1370) 0 0 0 1.35000 0.20000 0.80000 2.00000 0 10221:oneChannel = 1 1.000 0 310 310 10221:onMode = off 10221:onIfMatch = 310 310 + +225:all = f_2(1270) f_2(1270) 4 0 0 1.27500 0.1860 1.10000 1.50000 0 +225:oneChannel = 1 1.000 0 310 310 +225:onMode = off +225:onIfMatch = 310 310 + +115:all = a_2(1320) a_2(1320) 4 0 0 1.31820 0.10780 1.10000 1.50000 0 +115:oneChannel = 1 1.000 0 310 310 +115:onMode = off +115:onIfMatch = 310 310 From 63d61be3dc782d662318c593f23bb00eb6f68f8a Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Mon, 17 Nov 2025 09:07:09 +0100 Subject: [PATCH 151/362] Reduction of nEvents (#2183) This is to account for the hybro events multiplication in EPOS4 configuration, otherwise the generator will crash at the first generated event. --- MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini index 8375cb7f3..96bf37247 100644 --- a/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini +++ b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini @@ -1,7 +1,7 @@ #---> GeneratorEPOS4 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C -funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns", 2147483647) +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns", 214748364) [GeneratorFileOrCmd] cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh From eb866f3805a989c2e270ac3a0e1cdd1cb23d62b2 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Tue, 18 Nov 2025 17:10:21 +0100 Subject: [PATCH 152/362] Automatic IR (#2184) --- .../common/external/generator/TPCLoopers.C | 36 ++++++++++++++++--- .../common/ini/GeneratorLoopersFlatFile.ini | 4 +-- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/MC/config/common/external/generator/TPCLoopers.C b/MC/config/common/external/generator/TPCLoopers.C index 98785732d..eb7916af8 100644 --- a/MC/config/common/external/generator/TPCLoopers.C +++ b/MC/config/common/external/generator/TPCLoopers.C @@ -420,8 +420,15 @@ class GenTPCLoopers : public Generator } } if (mFlatGas){ - mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr; - mCollisionContext = mContextFile ? (o2::steer::DigitizationContext *)mContextFile->Get("DigitizationContext") : nullptr; + // Check if mContextFile is already opened + if(!mContextFile) + { + mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr; + } + if(!mCollisionContext) + { + mCollisionContext = mContextFile ? (o2::steer::DigitizationContext *)mContextFile->Get("DigitizationContext") : nullptr; + } mInteractionTimeRecords = mCollisionContext ? mCollisionContext->getEventRecords() : std::vector{}; if (mInteractionTimeRecords.empty()) { @@ -476,14 +483,32 @@ class GenTPCLoopers : public Generator LOG(fatal) << "Error: Could not find fit function '" << fitName << "' in rate file!"; exit(1); } - auto ref = static_cast(std::floor(fit->Eval(intRate / 1000.))); // fit expects rate in kHz + mInteractionRate = intRate; + if(mInteractionRate < 0) + { + mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr; + if(!mContextFile || mContextFile->IsZombie()) + { + LOG(fatal) << "Error: Interaction rate not provided and collision context file not found!"; + exit(1); + } + mCollisionContext = (o2::steer::DigitizationContext *)mContextFile->Get("DigitizationContext"); + mInteractionRate = std::floor(mCollisionContext->getDigitizerInteractionRate()); + LOG(info) << "Interaction rate retrieved from collision context: " << mInteractionRate << " Hz"; + if (mInteractionRate < 0) + { + LOG(fatal) << "Error: Invalid interaction rate retrieved from collision context!"; + exit(1); + } + } + auto ref = static_cast(std::floor(fit->Eval(mInteractionRate / 1000.))); // fit expects rate in kHz rate_file.Close(); if (ref <= 0) { LOG(fatal) << "Computed flat gas number reference per orbit is <=0"; exit(1); } else { - LOG(info) << "Set flat gas number to " << ref << " loopers per orbit using " << fitName << " from " << intRate << " Hz interaction rate."; + LOG(info) << "Set flat gas number to " << ref << " loopers per orbit using " << fitName << " from " << mInteractionRate << " Hz interaction rate."; auto flat = true; setFlatGas(flat, -1, ref); } @@ -531,6 +556,7 @@ class GenTPCLoopers : public Generator double mTimeEnd = 0.0; // Time limit for the last event float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs std::string mRateFile = ""; // File with clusters/rate information per orbit + int mInteractionRate = 38000; // Interaction rate in Hz }; } // namespace eventgen @@ -684,7 +710,7 @@ Generator_TPCLoopersFlat(std::string model_pairs = "tpcloopmodel.onnx", std::str FairGenerator * Generator_TPCLoopersOrbitRef(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", std::string scaler_pair = "scaler_pair.json", std::string scaler_compton = "scaler_compton.json", - std::string nclxrate = "nclxrate.root", bool isPbPb = true, const int intrate = 38000, const float adjust = 0.f) + std::string nclxrate = "nclxrate.root", bool isPbPb = true, const int intrate = -1, const float adjust = 0.f) { // Expand all environment paths model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); diff --git a/MC/config/common/ini/GeneratorLoopersFlatFile.ini b/MC/config/common/ini/GeneratorLoopersFlatFile.ini index 285a7cb5b..4143989ab 100644 --- a/MC/config/common/ini/GeneratorLoopersFlatFile.ini +++ b/MC/config/common/ini/GeneratorLoopersFlatFile.ini @@ -1,6 +1,6 @@ # TPC loopers injector using fit to calculate reference loopers number per orbit. File with fit function is pulled from the CCDB. -# Three additional parameters are available in the function: (isPbPb = true, intRate = 38000, adjust = 0.) -# isPbPb and intRate must be set in case the collision system is not PbPb at 38 kHz, while adjust can be used to decrease/increase +# Three additional parameters are available in the function: (isPbPb = true, intRate = -1, adjust = 0.) +# isPbPb and intRate must be set in case the collision system is not PbPb and the IR is not taken from collisioncontext, while adjust can be used to decrease/increase # the number of loopers per orbit obtained from the reference (e.g. -0.1 reduces the loopers by 10%) #---> GeneratorTPCloopers [GeneratorExternal] From a00eaf1e45fcefe02a030dd0344490219aa71b14 Mon Sep 17 00:00:00 2001 From: jaimenorman Date: Thu, 20 Nov 2025 08:01:29 +0000 Subject: [PATCH 153/362] add POWHEG jet configuration and ini file, pp 13.6 TeV (#2178) * add POWHEG jet configuration and ini file, pp 13.6 TeV * select dijet POWHEG process --- .../external/powheg/powheg_jetjet_13600.input | 90 +++++++++++++++++++ .../GeneratorPythia8POWHEG_jetjet_13600.ini | 10 +++ 2 files changed, 100 insertions(+) create mode 100755 MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input create mode 100644 MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600.ini diff --git a/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input new file mode 100755 index 000000000..c51aebbe8 --- /dev/null +++ b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input @@ -0,0 +1,90 @@ +numevts 10 ! number of events to be generated +ih1 1 ! hadron 1 (1 for protons, -1 for antiprotons) +ih2 1 ! hadron 2 (1 for protons, -1 for antiprotons) +ebeam1 6800d0 ! energy of beam 1 +ebeam2 6800d0 ! energy of beam 2 + +bornktmin 1d0 ! (default 0d0) Generation cut: minimum kt in underlying Born +bornsuppfact 120d0 ! (default 0d0) Mass parameter for Born suppression factor. + ! If < 0 suppfact = 1. + + +! To be set only if using internal (mlm) pdfs +! 131 cteq6m +! ndns1 131 ! pdf set for hadron 1 (mlm numbering) +! ndns2 131 ! pdf set for hadron 2 (mlm numbering) + +! To be set only if using LHA pdfs +! 10050 cteq6m +! 10550 cteq66 +! 13100 CT14nlo +! 14400 CT18nlo +lhans1 14400 ! pdf set for hadron 1 (LHA numbering) +lhans2 14400 ! pdf set for hadron 2 (LHA numbering) + +! To be set only if using different pdf sets for the two incoming hadrons +# QCDLambda5 0.25 ! for not equal pdf sets + +#renscfact 1d0 ! (default 1d0) ren scale factor: muren = muref * renscfact +#facscfact 1d0 ! (default 1d0) fac scale factor: mufact = muref * facscfact + +! Parameters to allow or not the use of stored data +use-old-grid 1 ! If 1 use old grid if file pwggrids.dat is present (<> 1 regenerate) +use-old-ubound 1 ! If 1 use norm of upper bounding function stored + ! in pwgubound.dat, if present; <> 1 regenerate + +! A typical call uses 1/1400 seconds (1400 calls per second) +ncall1 20000 ! No. calls for the construction of the importance sampling grid +itmx1 5 ! No. iterations for grid: total 100000 calls ~ 70 seconds +ncall2 20000 ! No. calls for the computation of the upper bounding + ! envelope for the generation of radiation +itmx2 5 ! No. iterations for the above + +! Notice: the total number of calls is ncall2*itmx2*foldcsi*foldy*foldphi +! these folding numbers yield a negative fraction of 0.5% with bornktmin=10 GeV. +! With these settings: ncall2*itmx2*foldcsi*foldy*foldphi=5M, 60 minutes +foldcsi 5 ! No. folds on csi integration +foldy 5 ! No. folds on y integration +foldphi 2 ! No. folds on phi integration + +nubound 500000 ! No. calls to set up the upper bounding norms for radiation. + ! This is performed using only the Born cross section (fast) + +! OPTIONAL PARAMETERS + +withnegweights 0 ! (default 0). If 1 use negative weights. +#bornonly 1 ! (default 0). If 1 compute underlying Born using LO + ! cross section only. + +#ptsqmin 0.8 ! (default 0.8 GeV) minimum pt for generation of radiation +#charmthr 1.5 ! (default 1.5 GeV) charm treshold for gluon splitting +#bottomthr 5.0 ! (default 5.0 GeV) bottom treshold for gluon splitting +#testplots 1 ! (default 0, do not) do NLO and PWHG distributions +#charmthrpdf 1.5 ! (default 1.5 GeV) pdf charm treshold +#bottomthrpdf 5.0 ! (default 5.0 GeV) pdf bottom treshold + +#xupbound 2d0 ! increase upper bound for radiation generation + +#iseed 5421 ! Start the random number generator with seed iseed +#rand1 0 ! skipping rand2*100000000+rand1 numbers (see RM48 +#rand2 0 ! short writeup in CERNLIB). +#manyseeds 1 ! Used to perform multiple runs with different random + ! seeds in the same directory. + ! If set to 1, the program asks for an integer j; + ! The file pwgseeds.dat at line j is read, and the + ! integer at line j is used to initialize the random + ! sequence for the generation of the event. + ! The event file is called pwgevents-'j'.lhe + +doublefsr 1 ! Default 0; if 1 use new mechanism to generate regions + ! such that the emitted harder than the + ! emitter in FSR is suppressed. If doublefsr=0 this is + ! only the case for emitted gluons (old behaviour). If + ! 1 it is also applied to emitted quarks. + ! If set, it strongly reduces spikes on showered output. + + + +par_diexp 4 ! default is 2. With 4 there is a stronger separation +par_dijexp 4 ! of regions, it may help to reduce spikes when generating +par_2gsupp 4 ! weighted events. diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600.ini new file mode 100644 index 000000000..201e7a734 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600.ini @@ -0,0 +1,10 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +## The option '3' which is given to getGeneratorJEPythia8POWHEG selects the pwhg_main_dijet process +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input","",3) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg From 9197b2f8494255ebf528e4015f10c992cd6faa12 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 21 Nov 2025 10:57:26 +0100 Subject: [PATCH 154/362] Reference particle --- MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C b/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C index 18abd5ddf..1f6d6b867 100644 --- a/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C +++ b/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C @@ -106,10 +106,10 @@ class GeneratorEvtGen : public T { auto nparticles = T::mParticles.size(); for (Int_t iparticle = 0; iparticle < nparticles; ++iparticle) { - auto particle = (TParticle)T::mParticles.at(iparticle); + const auto& particle = T::mParticles.at(iparticle); if (checkPdg(particle.GetPdgCode())) { if (mDebug) - std::cout << "particles in the array (before decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array" << iparticle << " First daughter" << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; + std::cout << "particles in the array (before decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array " << iparticle << " First daughter " << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; TLorentzVector* momentum = new TLorentzVector(); momentum->SetPxPyPzE(particle.Px(), particle.Py(), particle.Pz(), particle.Energy()); DecayEvtGen(particle.GetPdgCode(), momentum, mPolarization); @@ -118,7 +118,7 @@ class GeneratorEvtGen : public T return kFALSE; } if (mDebug) - std::cout << "particles in the array (after decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array" << iparticle << " First daughter" << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; + std::cout << "particles in the array (after decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array " << iparticle << " First daughter " << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; } } return kTRUE; From 8ac59922702185650801e252e59191e1a7f95436 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 3 Oct 2025 07:00:52 +0200 Subject: [PATCH 155/362] ability to take external collision context for the mc-on-data embedding effort --- MC/bin/o2dpg_sim_workflow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 39235f6c2..39af5c9a5 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -124,6 +124,7 @@ # power features (for playing) --> does not appear in help message # help='Treat smaller sensors in a single digitization') parser.add_argument('--pregenCollContext', action='store_true', help=argparse.SUPPRESS) # Now the default, giving this option or not makes not difference. We keep it for backward compatibility +parser.add_argument('--data-anchoring', type=str, default='', help="Take collision contexts (from data) stored in this path") parser.add_argument('--no-combine-smaller-digi', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--no-combine-dpl-devices', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--no-mc-labels', action='store_true', default=False, help=argparse.SUPPRESS) @@ -623,7 +624,8 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): + ' --extract-per-timeframe tf:sgn' \ + ' --with-vertices ' + vtxmode_precoll \ + ' --maxCollsPerTF ' + str(args.ns) \ - + ' --orbitsEarly ' + str(args.orbits_early) + + ' --orbitsEarly ' + str(args.orbits_early) \ + + ('',f" --import-external {args.data_anchoring}")[len(args.data_anchoring) > 0] PreCollContextTask['cmd'] += ' --bcPatternFile ccdb' # <--- the object should have been set in (local) CCDB if includeQED: From 545fc72c6c52e26fb7f32f350a5c08be79d0390d Mon Sep 17 00:00:00 2001 From: sawan <124118453+sawankumawat@users.noreply.github.com> Date: Mon, 24 Nov 2025 20:37:35 +0530 Subject: [PATCH 156/362] Fix LF_rapidity generator by including generator_pythia8_longlived.C (#2190) * added exotic particles in the gun * added exotic particles in the gun * rolled back to generator_pythia8_longlived.C script to get mass from PDG * removed formatting changes --- .../pythia8/generator/exotic_nuclei_pp.gun | 5 ++ .../pythia8/generator_pythia8_LF_rapidity.C | 46 ++++++++++--------- 2 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun diff --git a/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun b/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun new file mode 100644 index 000000000..6174a13c4 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun @@ -0,0 +1,5 @@ +# PDG N ptMin ptMax yMin yMax +225 10 0.2 10 -1 1 +115 10 0.2 10 -1 1 +335 10 0.2 10 -1 1 +10331 10 0.2 10 -1 1 diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C index f3c56f420..12191584a 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C @@ -12,7 +12,7 @@ /// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity({{1000010020, 10, 0.5, 10, -1.0, 1.0}, {1000010030, 10, 0.5, 10, -1.0, 1.0}})'` /// Here PDG, Number injected, pT limits, rapidity limits are divided per particle /// or: -/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/nuclei_rapidity.gun")'` +/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun")'` /// Here PDG, Number injected, pT limits, rapidity limits are provided via an intermediate configuration file /// @@ -51,29 +51,30 @@ #endif #pragma cling load("libO2Generators") #endif -#include "Generators/GeneratorPythia8.h" +// #include "Generators/GeneratorPythia8.h" +#include "generator_pythia8_longlived.C" #include using namespace Pythia8; using namespace o2::mcgenstatus; -// Helper function to get mass from PDG code (copied from generator_pythia8_longlived.C to avoid include issues) -namespace { -double getMassFromPDG(int input_pdg) -{ - double mass = 0; - if (TDatabasePDG::Instance()) - { - TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg); - if (particle) { - mass = particle->Mass(); - } else { - LOG(warning) << "Unknown particle requested with PDG " << input_pdg << ", mass set to 0"; - } - } - return mass; -} -} +// // Helper function to get mass from PDG code (copied from generator_pythia8_longlived.C to avoid include issues) +// namespace { +// double getMassFromPDG(int input_pdg) +// { +// double mass = 0; +// if (TDatabasePDG::Instance()) +// { +// TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg); +// if (particle) { +// mass = particle->Mass(); +// } else { +// LOG(warning) << "Unknown particle requested with PDG " << input_pdg << ", mass set to 0"; +// } +// } +// return mass; +// } +// } class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 { @@ -362,7 +363,8 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 mRapidityMin{rapidityMin}, mRapidityMax{rapidityMax} { - mMass = getMassFromPDG(mPdg); + // mMass = getMassFromPDG(mPdg); + mMass = GeneratorPythia8LongLivedGun::getMass(mPdg); if (mMass <= 0) { LOG(fatal) << "Could not find mass for mPdg " << mPdg; } @@ -533,7 +535,7 @@ FairGenerator* generateLFRapidity(std::vector Date: Tue, 25 Nov 2025 15:06:56 +0100 Subject: [PATCH 157/362] Implemented Performance Generator (#2159) * Implemented Performance Generator --- .../common/external/generator/perfConf.json | 23 + .../external/generator/performanceGenerator.C | 398 ++++++++++++++++++ .../common/ini/GeneratorPerformanceFix.ini | 8 + .../ini/tests/GeneratorPerformanceFix.C | 43 ++ 4 files changed, 472 insertions(+) create mode 100644 MC/config/common/external/generator/perfConf.json create mode 100644 MC/config/common/external/generator/performanceGenerator.C create mode 100644 MC/config/common/ini/GeneratorPerformanceFix.ini create mode 100644 MC/config/common/ini/tests/GeneratorPerformanceFix.C diff --git a/MC/config/common/external/generator/perfConf.json b/MC/config/common/external/generator/perfConf.json new file mode 100644 index 000000000..c3bdfae0b --- /dev/null +++ b/MC/config/common/external/generator/perfConf.json @@ -0,0 +1,23 @@ +{ + "generators": [ + { + "cocktail": [ + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "external", + "config": { + "fileName": "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/performanceGenerator.C", + "funcName": "Generator_Performance()", + "iniFile": "" + } + } + ] + } + ], + "fractions": [ + 1 + ] +} diff --git a/MC/config/common/external/generator/performanceGenerator.C b/MC/config/common/external/generator/performanceGenerator.C new file mode 100644 index 000000000..ce59cdfaa --- /dev/null +++ b/MC/config/common/external/generator/performanceGenerator.C @@ -0,0 +1,398 @@ +// External generator requested in https://its.cern.ch/jira/browse/O2-6235 +// for multidimensional performance studies +// Example usage: +// o2-sim -j 8 -o test -n 100 --seed 612 -g hybrid --configKeyValues "GeneratorHybrid.configFile=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/perfConf.json" +namespace o2 +{ + namespace eventgen + { + + class GenPerf : public Generator + { + public: + GenPerf(float fraction = 0.03f, unsigned short int nsig = 100, unsigned short int tag = 1) + { + if (fraction == -1) { + LOG(info) << nsig << " Signal particles will be generated in each event"; + mNSig = nsig; + mFraction = -1.f; + } else if (fraction >= 0) { + LOG(info) << "Fraction based signal generation is enabled"; + LOG(info) << fraction << "*nUE tracks per event will be generated"; + mFraction = fraction; + } else { + LOG(fatal) << "Wrong fraction selected. Accepted values are:"; + LOG(fatal) << "\t -1 => fixed number of tracks per event"; + LOG(fatal) << ">=0 => fraction based signal generation over the number of UE tracks per event"; + exit(1); + } + initGenMap(); + if (genMap.find(tag) == genMap.end()) { + LOG(fatal) << "Wrong tag selected. Accepted values are:"; + for (const auto& [key, _] : genMap) { + LOG(fatal) << "\t" << key; + } + exit(1); + } else { + mTag = tag; + LOG(info) << "Generator with tag " << mTag << " is selected"; + } + LOG(info) << "Z0 decays are handled with Pythia8"; + mPythia = std::make_unique(); + // Turn off all event generation - we only want to decay our Z0 + mPythia->readString("ProcessLevel:all = off"); + // Disable standard event checks since we're manually building the event + mPythia->readString("Check:event = off"); + mPythia->init(); // Initialize + Generator::setTimeUnit(1.0); + Generator::setPositionUnit(1.0); + } + + Bool_t generateEvent() override + { + return kTRUE; + } + + Bool_t importParticles() override + { + mNUE = 0; + if ( mFraction != -1) { + // This line assumes that the current generator is run in a cocktail with another generator + // which is run before the current one in a sequential way + if (!mGenList) { + auto &hybridInstance = GeneratorHybrid::Instance(); + mGenList = &hybridInstance.getGenerators(); + } + if (!mGenList->empty()) { + mNUE = mGenList->front()->getParticles().size(); + LOG(debug) << "Number of tracks from UE is " << mNUE; + } + } + unsigned short nSig = (mFraction == -1) ? mNSig : std::lround(mFraction * mNUE); + LOG(debug) << "Generating additional " << nSig << " particles"; + for (int k = 0; k < nSig; k++){ + auto part = genMap[mTag](); + if(part.GetPdgCode() == 23) { + auto daughters = decayZ0(part); + for (auto &dau : daughters) + { + mParticles.push_back(dau); + } + } else { + mParticles.push_back(part); + } + } + return kTRUE; + } + + private: + float mFraction = 0.03f; // Fraction based generation + unsigned short int mNSig = 0; // Number of particles to generate + unsigned int mNUE = 0; // Number of tracks in the Underlying event + unsigned short int mTag = 1; // Tag to select the generation function + std::unique_ptr mPythia; // Pythia8 instance for particle decays not present in the physics list of Geant4 (like Z0) + const std::vector>* mGenList = nullptr; // Cached generators list + std::map> genMap; + UInt_t mGenID = 42; + + // This is performance test generator with uniform weighting for PDG + TParticle generateParticle0() + { + // 1. Get the singleton instances + TDatabasePDG *pdg = TDatabasePDG::Instance(); + // 2. Define the list of PDG codes + const int ncodes = 13; + const int pdgCodes[ncodes] = { + 310, // K0_s + 421, // D0 + 3122, // Lambda + -3122, // Anti-Lambda + 443, // J/psi + 13, // mu- + 22, // gamma + 23, // Z0 + 1, 2, 3, 4, 5 // Quarks: d, u, s, c, b (t-quark is 6, often excluded for kinematics) + }; + // 3. Randomly select and validate a PDG code + // TMath::Nint(gRandom->Rndm() * ncodes) selects an index from 0 to ncodes-1 safely. + int index = TMath::Nint(gRandom->Rndm() * (ncodes - 1)); + int pdgCode = pdgCodes[index]; + // Check if the particle exists and switch to antiparticle if needed + if (pdg->GetParticle(pdgCode) == nullptr) + { + if (pdg->GetParticle(-pdgCode) != nullptr) + { + pdgCode *= -1; // Use the negative code (antiparticle) + } + else + { + LOG(error) << "Error: PDG code " << pdgCode << " not found in TDatabasePDG. Using Muon (13)."; + pdgCode = 13; + } + } + // 4. Generate Kinematics (p_T, phi, eta) + float pt = 1 / (gRandom->Rndm()); // flat 1/pt distribution + float phi = gRandom->Rndm() * 2.0f * TMath::Pi(); + float eta = 3.0f * (gRandom->Rndm() - 0.5f); // eta from -1.5 to 1.5 + // Initial position (origin) + float xyz[3] = {0.0f, 0.0f, 0.0f}; + // if cosmic, you might want to randomize the vertex position + if (pdgCode == 13 || pdgCode == -13) + { + xyz[0] = (gRandom->Rndm() - 0.5) * 300.0f; // x from -100 to 100 cm + xyz[1] = (gRandom->Rndm() - 0.5) * 300.0f; // y from -100 to 100 cm + xyz[2] = 400; + pt = 1 / (gRandom->Rndm() + 0.01); + eta = gRandom->Gaus() * 0.2; + } + // + // Convert spherical coordinates (pt, phi, eta) to Cartesian (px, py, pz) + float pz = pt * TMath::SinH(eta); + float px = pt * TMath::Cos(phi); + float py = pt * TMath::Sin(phi); + // 5. Calculate Energy (E) from Mass (M) + TParticlePDG *particleInfo = pdg->GetParticle(pdgCode); + double mass = particleInfo ? particleInfo->Mass() : 0.1056; // Default to muon mass if lookup fails + double energy = TMath::Sqrt(px * px + py * py + pz * pz + mass * mass); + + // 6. Create and return the TParticle object by value + // TParticle(pdgCode, trackIndex, Mother, Daughter1, Daughter2, Px, Py, Pz, E, Vx, Vy, Vz, Time) + int status = -1; // Status code, -1 for undefined + // Set your custom performance generator ID (e.g., ID 42) + TParticle generatedParticle(pdgCode, status, -1, -1, -1, -1, px, py, pz, energy, xyz[0], xyz[1], xyz[2], 0.0); + generatedParticle.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(generatedParticle.GetStatusCode(), 0).fullEncoding); + generatedParticle.SetUniqueID(mGenID); + if (pdgCode == 23) { + generatedParticle.SetBit(ParticleStatus::kToBeDone, false); // Force Z0 to be decayed by the transport + } else { + generatedParticle.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(generatedParticle.GetStatusCode()) == 1); + } + return generatedParticle; + } + + // Particle configuration for ALICE O2 performance testing + struct ParticleSpec + { + int pdgCode; + float fraction; // Relative probability for probe statistics + float pTScale; // Scales pt + }; + + // Optimized for rare probes (J/psi, D0, jets) with flat distributions + const std::vector g_particle_specs = { + // PDG | Fraction | pTScale + {22, 1.0f, 1.0f}, // Photon: High yield for PID/calo + {13, 1.f, 1.0f}, // Muon: Cosmic override applied + {-13, 1.f, 1.0f}, // Anti-muon + {23, 0.1f, 10.0f}, // Z0: Rare, + {310, 1.f, 1.0f}, // K0_s: Common hadron + {421, 0.2f, 1.5f}, // D0 + {443, 0.1f, 5.0f}, // J/psi: Boosted for candle + {3122, 0.5f, 1.0f}, // Lambda + {-3122, 0.5f, 1.0f}, // Anti-Lambda + {211, 1.0f, 1.0f}, // Pi+ + {-211, 1.0f, 1.0f}, // Pi-: + // + {21, 0.1f, 3.0f}, // Gluon: Jet proxy (status=11) + {1, 0.1f, 3.0f}, // d quark: Jet proxy + {-1, 0.1f, 3.0f}, // anti-d + {2, 0.1f, 3.0f}, // u quark: Jet proxy + {-2, 0.1f, 3.0f}, // anti-u + {3, 0.1f, 5.0f}, // s quark: Strange + {-3, 0.1f, 5.0f}, // anti-s + {4, 0.1f, 5.0f}, // c quark: Heavy flavor + {-4, 0.1f, 5.0f}, // anti-c + {5, 0.1f, 8.0f}, // b quark: Very hard + {-5, 0.1f, 8.0f} // anti-b + }; + + // pT bounds: Max pT ~5 TeV (ALICE Pb-Pb energy) + const float kMaxInvPt = 1.0f; // Min pT = 1 GeV + const float kBaseMinInvPt = 2e-4f; // Max pT = 5000 GeV (unscaled) + + // Check if particle is a parton (quark/gluon, status=11) + bool isParton(int& pdgCode) + { + int absCode = TMath::Abs(pdgCode); + return (absCode >= 1 && absCode <= 5) || absCode == 21; + } + + // Generator for flat distributions in pT, eta for calibration + TParticle generateParticle1() + { + TDatabasePDG *pdg = TDatabasePDG::Instance(); + // 1. Weighted Random Selection + static float totalWeight = 0.0f; + if (totalWeight == 0.0f) + { + totalWeight = std::accumulate(g_particle_specs.begin(), g_particle_specs.end(), 0.0f, + [](float sum, const ParticleSpec &spec) + { return sum + spec.fraction; }); + } + float randVal = gRandom->Rndm() * totalWeight; + float cumulativeWeight = 0.0f; + const ParticleSpec *selectedSpec = nullptr; + for (const auto &spec : g_particle_specs) + { + cumulativeWeight += spec.fraction; + if (randVal <= cumulativeWeight) + { + selectedSpec = &spec; + break; + } + } + if (!selectedSpec) + selectedSpec = &g_particle_specs.back(); + int pdgCode = selectedSpec->pdgCode; + float pTScale = selectedSpec->pTScale; + // 2. PDG Validation + if (!pdg->GetParticle(pdgCode)) + { + if (pdg->GetParticle(-pdgCode)) + pdgCode *= -1; + else + { + LOG(error) << "Error: PDG " << pdgCode << " not found. Using muon (13).\n"; + pdgCode = 13; + pTScale = 1.0f; + } + } + // 3. Status: 11 for partons (jets), 1 for final-state + int status = isParton(pdgCode) ? 11 : 1; + // 4. Kinematics (flat 1/pT, max ~5000 GeV / pTScale) + float min_inv_pt = kBaseMinInvPt / pTScale; // E.g., max pT=40,000 GeV for b quarks + float inv_pt = (gRandom->Rndm() / pTScale) * (kMaxInvPt - min_inv_pt) + min_inv_pt; + float pt = 1.0f / inv_pt; + float phi = gRandom->Rndm() * 2.0f * TMath::Pi(); + float eta = gRandom->Rndm() * 3.0f - 1.5f; // ALICE TPC: -1.5 to 1.5 + // Vertex: Delta (embedding handles smearing) + float xyz[3] = {0.0f, 0.0f, 0.0f}; + // 5. Cosmic Muon Override + if (TMath::Abs(pdgCode) == 13) + { + xyz[0] = (gRandom->Rndm() - 0.5f) * 300.0f; + xyz[1] = (gRandom->Rndm() - 0.5f) * 300.0f; + xyz[2] = 400.0f; + inv_pt = (gRandom->Rndm() + 0.01f) / pTScale; // Apply pTScale + pt = 1.0f / inv_pt; + eta = TMath::Max(-4.0, TMath::Min(4.0, gRandom->Gaus(0.0, 0.2))); + status = 1; + } + // 6. Momentum and Energy + float pz = pt * TMath::SinH(eta); + float px = pt * TMath::Cos(phi); + float py = pt * TMath::Sin(phi); + TParticlePDG *particleInfo = pdg->GetParticle(pdgCode); + double mass = particleInfo ? particleInfo->Mass() : 0.1056; + double energy = TMath::Sqrt(px * px + py * py + pz * pz + mass * mass); + // 7. TParticle Creation (quarks/gluons need fragmentation in O2) + TParticle generatedParticle(pdgCode, status, -1, -1, -1, -1, px, py, pz, energy, xyz[0], xyz[1], xyz[2], 0.0); + generatedParticle.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(generatedParticle.GetStatusCode(), 0).fullEncoding); + generatedParticle.SetUniqueID(mGenID); + if (pdgCode == 23) { + generatedParticle.SetBit(ParticleStatus::kToBeDone, false); + // Z0 will follow another decay procedure + } else { + generatedParticle.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(generatedParticle.GetStatusCode()) == 1); + } + return generatedParticle; + } + + void initGenMap() + { + genMap[0] = [this]() + { return generateParticle0(); }; + genMap[1] = [this]() + { return generateParticle1(); }; + } + + std::vector decayZ0(TParticle &z0) + { + std::vector subparts; + auto &event = mPythia->event; + // Reset event record for new decay + event.reset(); + // Add the Z0 particle to the event record + // Arguments: id, status, mother1, mother2, daughter1, daughter2, + // col, acol, px, py, pz, e, m, scale, pol + // Status code: 91 = incoming particles (needed for proper decay handling) + int iZ0 = event.append(23, 91, 0, 0, 0, 0, 0, 0, + z0.Px(), z0.Py(), z0.Pz(), z0.Energy(), z0.GetMass()); + // Set production vertex + event[iZ0].vProd(z0.Vx(), z0.Vy(), z0.Vz(), 0.0); + // Forcing decay by calling hadron level function + if (!mPythia->forceHadronLevel()) + { + cout << "Warning: Z0 decay failed!" << endl; + } + for (int j = 0; j < event.size(); ++j) + { + const Pythia8::Particle &p = event[j]; + if (p.id() == 23) // PDG code for Z0 + { + // Push Z0 itself + subparts.push_back(TParticle(p.id(), p.status(), + -1, -1, -1, -1, + p.px(), p.py(), + p.pz(), p.e(), + z0.Vx(), z0.Vy(), z0.Vz(), 0.0)); + subparts.back().SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(p.status(), 0).fullEncoding); + subparts.back().SetUniqueID(mGenID); + subparts.back().SetBit(ParticleStatus::kToBeDone, false); + // Navigate through intermediate Z0s to find final decay products + int iZ0 = j; + while (event[iZ0].daughter1() != 0 && + event[event[iZ0].daughter1()].id() == 23) + { + iZ0 = event[iZ0].daughter1(); + } + // Recursively collect all final-state descendants + std::function collectAllDescendants = [&](int idx) + { + const Pythia8::Particle &particle = event[idx]; + subparts.push_back(TParticle(particle.id(), particle.status(), + -1, -1, -1, -1, + particle.px(), particle.py(), + particle.pz(), particle.e(), + p.xProd(), p.yProd(), p.zProd(), p.tProd())); + subparts.back().SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(particle.status(), 0).fullEncoding); + subparts.back().SetUniqueID(mGenID + 1); + subparts.back().SetBit(ParticleStatus::kToBeDone, + o2::mcgenstatus::getHepMCStatusCode(subparts.back().GetStatusCode()) == 1); + // Not final-state, recurse through daughters + if (!particle.isFinal()) + { + int d1 = particle.daughter1(); + int d2 = particle.daughter2(); + if (d1 > 0) + { + for (int k = d1; k <= d2; ++k) + { + collectAllDescendants(k); + } + } + } + }; + // Start collecting from the final Z0 + collectAllDescendants(iZ0); + break; // Found and processed the Z0 + } + } + return subparts; + } + }; + + } // namespace eventgen +} // namespace o2 + +// Performance test generator +// fraction == -1 enables the fixed number of signal particles per event (nsig) +// tag selects the generator type to be used +FairGenerator * +Generator_Performance(const float fraction = 0.03f, const unsigned short int nsig = 100, unsigned short int tag = 1) +{ + auto generator = new o2::eventgen::GenPerf(fraction, nsig, tag); + return generator; +} \ No newline at end of file diff --git a/MC/config/common/ini/GeneratorPerformanceFix.ini b/MC/config/common/ini/GeneratorPerformanceFix.ini new file mode 100644 index 000000000..b92b2300c --- /dev/null +++ b/MC/config/common/ini/GeneratorPerformanceFix.ini @@ -0,0 +1,8 @@ +# Test performance generator for multidimensional studies using fix number of signal particles per event +# Parameters are in order: fraction of signal particles, fixed number of signal particles per event, tag to select the generator type +# Setting fraction = -1 enables the fixed number of signal particles per event (nsig). +# An hybrid configuration JSON file is provided in ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/perfConf.json to run the generator +# in fraction based mode +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/performanceGenerator.C +funcName = Generator_Performance(-1, 100, 1) diff --git a/MC/config/common/ini/tests/GeneratorPerformanceFix.C b/MC/config/common/ini/tests/GeneratorPerformanceFix.C new file mode 100644 index 000000000..ffda1fb6e --- /dev/null +++ b/MC/config/common/ini/tests/GeneratorPerformanceFix.C @@ -0,0 +1,43 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree 'o2sim' in file " << path << "\n"; + return 1; + } + // Get the MCTrack branch + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + // Check if processes with ID 42 are available + // And are 100 per event + const int processID = 42; // Performance test particle custom process ID + int nEvents = tree->GetEntries(); + short int count_perf = 0; + unsigned short int expSig = 100; // set by default in the ini file + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nTracks = tracks->size(); + count_perf = 0; + for (auto &track : *tracks) + { + const auto& process = track.getProcess(); + if (process == 42) + { + count_perf++; + } + } + if (count_perf != expSig) + { + std::cerr << "Event " << i << ": Expected " << expSig << " performance test particles, found " << count_perf << "\n"; + return 1; + } + } + + file.Close(); + return 0; +} \ No newline at end of file From 2fe012d4d14acbaa58e477107fe70b152051d175 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Wed, 26 Nov 2025 20:07:55 +0100 Subject: [PATCH 158/362] MC/PWGEM: add MC files for HFll in OO (#2188) * MC/PWGEM: add MC files for HFll in OO * Rename GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_Electron.ini to lowercase * Add pdgLepton parameter to generator functions * Add NEV_TEST condition to generator config * Add NEV_TEST condition to ini configuration * Add NEV_TEST configuration to generator ini file * Add NEV_TEST condition to generator config * Add NEV_TEST condition to generator config * Add NEV_TEST condition to generator config * Fix formatting of NEV_TEST line in config file * Fix formatting of NEV_TEST line in ini file * Fix formatting of NEV_TEST line in ini file * Fix formatting of NEV_TEST line in config file * Fix formatting of NEV_TEST in ini file * Update GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini * Fix function parameters in generator configuration --- ...nerator_pythia8_GapTriggered_HFLepton_OO.C | 234 ++++++++++++++++++ ...red_BeautyForcedDecay_Gap2_OO_electron.ini | 8 + ...iggered_BeautyForcedDecay_Gap2_OO_muon.ini | 8 + ...d_BeautyNoForcedDecay_Gap2_OO_electron.ini | 8 + ...gered_BeautyNoForcedDecay_Gap2_OO_muon.ini | 8 + ...rHFGapTriggered_Charm_Gap2_OO_electron.ini | 8 + ...ratorHFGapTriggered_Charm_Gap2_OO_muon.ini | 8 + ...gered_BeautyForcedDecay_Gap2_OO_electron.C | 117 +++++++++ ...Triggered_BeautyForcedDecay_Gap2_OO_muon.C | 117 +++++++++ ...red_BeautyNoForcedDecay_Gap2_OO_electron.C | 112 +++++++++ ...iggered_BeautyNoForcedDecay_Gap2_OO_muon.C | 112 +++++++++ ...torHFGapTriggered_Charm_Gap2_OO_electron.C | 117 +++++++++ ...neratorHFGapTriggered_Charm_Gap2_OO_muon.C | 116 +++++++++ 13 files changed, 973 insertions(+) create mode 100644 MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.C diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C new file mode 100644 index 000000000..55a23a437 --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C @@ -0,0 +1,234 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include +//#include // for std::pair + +using namespace Pythia8; + +class GeneratorPythia8GapTriggeredHFLeptonOO : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapTriggeredHFLeptonOO() = default; + + /// constructor + GeneratorPythia8GapTriggeredHFLeptonOO(TString configsignal, int quarkPdg = 4, int lInputTriggerRatio = 5, int lInputExternalID = 0) + { + + lGeneratedEvents = 0; + lInverseTriggerRatio = lInputTriggerRatio; + lExternalID = lInputExternalID; + mQuarkPdg = quarkPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(lInverseTriggerRatio)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}//MC/config/common/pythia8/generator/pythia8_OO_536.cfg"); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization of gap event is complete" << endl; + + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.readString("Beams:idA = 1000080160"); + pythiaObjectSignal.readString("Beams:idB = 1000080160"); + pythiaObjectSignal.readString("Beams:eCM = 5360.0"); + pythiaObjectSignal.readString("Beams:frameType = 1"); + pythiaObjectSignal.readString("ParticleDecays:limitTau0 = on"); + pythiaObjectSignal.readString("ParticleDecays:tau0Max = 10."); + pythiaObjectSignal.readString("HeavyIon:SigFitNGen = 0"); + pythiaObjectSignal.readString("HeavyIon:SigFitDefPar = 2.15,18.42,0.33"); + pythiaObjectSignal.init(); + cout << "Initalization of signal event is complete" << endl; + + // flag the generators using type + // addCocktailConstituent(type, "interesting"); + // addCocktailConstitent(0, "minbias"); + // Add Sub generators + addSubGenerator(0, "default generator"); + addSubGenerator(1, "charm lepton"); + addSubGenerator(2, "beauty forced decay"); + addSubGenerator(3, "beauty no foced decay"); + } + + /// Destructor + ~GeneratorPythia8GapTriggeredHFLeptonOO() = default; + + void addTriggerOnDaughter(int nb, int pdg) + { + mNbDaughter = nb; + mPdgDaughter = pdg; + }; + void setQuarkRapidity(float yMin, float yMax) + { + mQuarkRapidityMin = yMin; + mQuarkRapidityMax = yMax; + }; + void setDaughterRapidity(float yMin, float yMax) + { + mDaughterRapidityMin = yMin; + mDaughterRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Simple straightforward check to alternate generators + if (lGeneratedEvents % lInverseTriggerRatio == 0) { + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + } else { + // Generate minimum-bias event + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + notifySubGenerator(0); + } + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + bool isGoodAtPartonLevel = false, isGoodAtDaughterLevel = (mPdgDaughter != 0) ? false : true; + int nbDaughter = 0; + for (auto iPart{0}; iPart < event.size(); ++iPart) { + // search for Q-Qbar mother with at least one Q in rapidity window + if (!isGoodAtPartonLevel) { + auto daughterList = event[iPart].daughterList(); + bool hasQ = false, hasQbar = false, atSelectedY = false; + for (auto iDau : daughterList) { + if (event[iDau].id() == mQuarkPdg) { + hasQ = true; + } + if (event[iDau].id() == -mQuarkPdg) { + hasQbar = true; + } + if ((std::abs(event[iDau].id()) == mQuarkPdg) && (event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + atSelectedY = true; + } + if (hasQ && hasQbar && atSelectedY) { + isGoodAtPartonLevel = true; + } + } + // search for mNbDaughter daughters of type mPdgDaughter in rapidity window + if (!isGoodAtDaughterLevel) { + int id = std::abs(event[iPart].id()); + float rap = event[iPart].y(); + if (id == mPdgDaughter) { + int motherindexa = event[iPart].mother1(); + if (motherindexa > 0) { + int idmother = std::abs(event[motherindexa].id()); + if (int(std::abs(idmother) / 100.) == 4 || int(std::abs(idmother) / 1000.) == 4 || int(std::abs(idmother) / 100.) == 5 || int(std::abs(idmother) / 1000.) == 5) { + if (rap > mDaughterRapidityMin && rap < mDaughterRapidityMax) { + nbDaughter++; + if (nbDaughter >= mNbDaughter) isGoodAtDaughterLevel = true; + } + } + } + } + } + // we send the trigger + if (isGoodAtPartonLevel && isGoodAtDaughterLevel) { + return true; + } + } + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mQuarkPdg; + float mQuarkRapidityMin; + float mQuarkRapidityMax; + int mPdgDaughter; + int mNbDaughter; + float mDaughterRapidityMin; + float mDaughterRapidityMax; + + // Control gap-triggering + Long64_t lGeneratedEvents; + int lInverseTriggerRatio; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectMinimumBias; ///Minimum bias collision generator + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +// Charm-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredCharmLepton(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_cr2_forceddecayscharm.cfg", 4, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + +// Beauty-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyForcedDecays(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_forceddecayscharmbeauty.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + +// Beauty-enriched no forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyNoForcedDecays(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.ini new file mode 100644 index 000000000..f25401e61 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyForcedDecays(2, 2, 11, -1.5, +1.5, -1.2, +1.2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.ini new file mode 100644 index 000000000..b129f9fe8 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyForcedDecays(2, 2, 13, -6, 0, -5, -1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini new file mode 100644 index 000000000..8cd7e5ab6 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyNoForcedDecays(2, 3, 11, -1.5, +1.5, -1.2, +1.2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.ini new file mode 100644 index 000000000..97741b31b --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyNoForcedDecays(2, 3, 13, -6, 0, -5, -1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini new file mode 100644 index 000000000..9691afc04 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredCharmLepton(2, 1, 11, -1.5, +1.5, -1.2, +1.2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini new file mode 100644 index 000000000..59d5babf4 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredCharmLepton(2, 1, 13, -6, 0, -5, -1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.C new file mode 100644 index 000000000..d4c7056e4 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.C @@ -0,0 +1,117 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + printf("Event %d\n",i); + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.C new file mode 100644 index 000000000..dea67792e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.C @@ -0,0 +1,117 @@ +int External() +{ + int checkPdgDecay = 13; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + printf("Event %d\n",i); + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.C new file mode 100644 index 000000000..ac2a627cf --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.C @@ -0,0 +1,112 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.C new file mode 100644 index 000000000..ac2a627cf --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.C @@ -0,0 +1,112 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.C new file mode 100644 index 000000000..ed19c336e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.C @@ -0,0 +1,117 @@ +int External() +{ + + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3.; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.C new file mode 100644 index 000000000..0b837b413 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.C @@ -0,0 +1,116 @@ +int External() +{ + int checkPdgDecay = 13; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3.; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} From 338d1be23cec048eebd3b9b30ed8cdef2a18bf2a Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 27 Nov 2025 21:26:23 +0100 Subject: [PATCH 159/362] grid_submit.sh: Basic support to split in InputFileCollections --- GRID/utils/grid_submit.sh | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/GRID/utils/grid_submit.sh b/GRID/utils/grid_submit.sh index 1d1bf8b5d..430026963 100755 --- a/GRID/utils/grid_submit.sh +++ b/GRID/utils/grid_submit.sh @@ -208,7 +208,7 @@ while [ $# -gt 0 ] ; do --cores) CPUCORES=$2; shift 2 ;; # allow to specify the CPU cores (check compatibility with partition !) --dry) DRYRUN="ON"; shift 1 ;; # do a try run and not actually interact with the GRID (just produce local jdl file) --o2tag) O2TAG=$2; shift 2 ;; # - --packagespec) PACKAGESPEC=$2; shift 2 ;; # the alisw, cvmfs package list (command separated - example: '"VO_ALICE@FLUKA_VMC::4-1.1-vmc3-1","VO_ALICE@O2::daily-20230628-0200-1"') + --packagespec) PACKAGESPEC=$2; shift 2 ;; # the alisw, cvmfs package list (command separated - example: '"VO_ALICE@FLUKA_VMC::4-1.1-vmc3-1","VO_ALICE@O2::daily-20230628-0200-1"') --asuser) ASUSER=$2; shift 2 ;; # --label) JOBLABEL=$2; shift 2 ;; # label identifying the production (e.g. as a production identifier) --mattermost) MATTERMOSTHOOK=$2; shift 2 ;; # if given, status and metric information about the job will be sent to this hook @@ -218,7 +218,8 @@ while [ $# -gt 0 ] ; do --wait) WAITFORALIEN=ON; shift 1 ;; #wait for alien jobs to finish --wait-any) WAITFORALIENANY=ON; WAITFORALIEN=ON; shift 1 ;; #wait for any good==done alien jobs to return --outputspec) OUTPUTSPEC=$2; shift 2 ;; #provide comma separate list of JDL file specs to be put as part of JDL Output field (example '"*.log@disk=1","*.root@disk=2"') - -h) Usage ; exit ;; + --split-on-collection) DATACOLLECTION=$2; shift 2 ;; # this will split the jobs on InputDataCollection and "file" mode + -h) Usage ; exit ;; --help) Usage ; exit ;; --fetch-output) FETCHOUTPUT=ON; shift 1 ;; # if to fetch all JOB output locally (to make this job as if it ran locally); only works when we block until all JOBS EXIT *) break ;; @@ -355,13 +356,21 @@ if [[ "${IS_ALIEN_JOB_SUBMITTER}" ]]; then cd "${GRID_SUBMIT_WORKDIR}" QUOT='"' + SPLITMODE="production:1-${PRODSPLIT}" + if [ "${DATACOLLECTION}" ]; then + SPLITMODE="file" + fi # ---- Generate JDL ---------------- # TODO: Make this configurable or read from a preamble section in the jobfile cat > "${MY_JOBNAMEDATE}.jdl" < collection.xml + if [ "$?" != "0" ]; then + per "Problem with data collection preparation" + exit 1 + fi + fi + pok "Preparing job \"$MY_JOBNAMEDATE\"" ( # assemble all GRID interaction in a single script / transaction @@ -396,6 +414,9 @@ EOF echo "rm ${MY_BINDIR}/${MY_JOBNAMEDATE}.sh" >> ${command_file} # remove current job script echo "cp file:${PWD}/${MY_JOBNAMEDATE}.jdl alien://${MY_JOBWORKDIR}/${MY_JOBNAMEDATE}.jdl@DISK=1" >> ${command_file} # copy the jdl echo "cp file:${THIS_SCRIPT} alien://${MY_BINDIR}/${MY_JOBNAMEDATE}.sh@DISK=1" >> ${command_file} # copy current job script to AliEn + if [ "${DATACOLLECTION}" ]; then + echo "cp file:collection.xml alien://${MY_JOBWORKDIR}/collection.xml" >> ${command_file} + fi [ ! "${CONTINUE_WORKDIR}" ] && echo "cp file:${MY_JOBSCRIPT} alien://${MY_JOBWORKDIR}/alien_jobscript.sh" >> ${command_file} ) > alienlog.txt 2>&1 From 0b96a90b1abbfa2da63c338210dedc1a190b7a59 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Sat, 29 Nov 2025 19:48:06 +0100 Subject: [PATCH 160/362] Add generator for strangeness in jets (#2194) --- ...ratorLFStrangenessInJetsTriggered_gap4.ini | 9 +++ ...neratorLFStrangenessInJetsTriggered_gap4.C | 58 +++++++++++++++++++ .../generator/pythia8_jet_ropes_136tev.cfg | 29 ++++++++++ 3 files changed, 96 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLFStrangenessInJetsTriggered_gap4.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLFStrangenessInJetsTriggered_gap4.C create mode 100644 MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFStrangenessInJetsTriggered_gap4.ini b/MC/config/PWGLF/ini/GeneratorLFStrangenessInJetsTriggered_gap4.ini new file mode 100644 index 000000000..0e4746183 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFStrangenessInJetsTriggered_gap4.ini @@ -0,0 +1,9 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C +funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 4) + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessInJetsTriggered_gap4.C b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessInJetsTriggered_gap4.C new file mode 100644 index 000000000..50b579161 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessInJetsTriggered_gap4.C @@ -0,0 +1,58 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + std::vector injectedPDGs = { + 3334, + -3334, + 3312, + -3312}; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) { + nSignal.push_back(0); + } + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) { + std::cout << "# Injected nuclei \n"; + std::cout << injectedPDGs[i] << ": " << nSignal[i] << "\n"; + if (nSignal[i] == 0) { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + return 1; // At least one of the injected particles should be generated + } + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg new file mode 100644 index 000000000..c198e1db6 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg @@ -0,0 +1,29 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 13600. # GeV + +### processes +SoftQCD:inelastic = off +HardQCD:all = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 8 +PhaseSpace:pTHatMax = 600 +PhaseSpace:bias2Selection = on +PhaseSpace:bias2SelectionPow = 4 + +Random:setSeed = on +Random:seed = 0 + +Ropewalk:RopeHadronization = on +Ropewalk:doShoving = off +Ropewalk:doFlavour = on +Ropewalk:r0 = 0.5 +Ropewalk:m0 = 0.2 +Ropewalk:beta = 0.1 +PartonVertex:setVertex = on \ No newline at end of file From f483261e5abac436bc720c255f5e7427453683cd Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Sat, 29 Nov 2025 18:09:30 +0100 Subject: [PATCH 161/362] Remove deprecated workflow option from scripts didn't have any effect in any case --- MC/bin/o2dpg_sim_workflow.py | 4 ++-- MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh | 2 +- MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh | 2 +- MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh | 2 +- MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh | 2 +- MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh | 2 +- MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh | 2 +- MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh | 2 +- MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh | 2 +- MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh | 2 +- MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh | 2 +- MC/run/PWGDQ/runFwdMuBoxGen_pp.sh | 2 +- MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh | 2 +- MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh | 2 +- MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh | 2 +- .../PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh | 2 +- MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh | 2 +- MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh | 2 +- MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh | 2 +- MC/run/PWGDQ/runPromptJpsi_midy_pp.sh | 2 +- MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh | 2 +- MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh | 2 +- MC/run/PWGEM/runHFFullToDielectrons_pp.sh | 2 +- MC/run/PWGEM/runHFGapToDielectrons_pp.sh | 2 +- MC/run/PWGEM/runHFToDielectrons_pp.sh | 2 +- MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh | 2 +- MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh | 2 +- MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh | 4 ++-- MC/run/PWGGAJE/run_decaygammajets.sh | 2 +- MC/run/PWGGAJE/run_dirgamma.sh | 2 +- MC/run/PWGGAJE/run_dirgamma_embedding.sh | 2 +- MC/run/PWGGAJE/run_dirgamma_hook.sh | 2 +- MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh | 2 +- MC/run/PWGGAJE/run_jets.sh | 2 +- MC/run/PWGGAJE/run_jets_HF_bbbar.sh | 2 +- MC/run/PWGGAJE/run_jets_HF_ccbar.sh | 2 +- MC/run/PWGGAJE/run_jets_embedding.sh | 2 +- MC/run/PWGGAJE/run_jets_hook.sh | 2 +- MC/run/PWGHF/run_OmegaCInjected.sh | 2 +- MC/run/PWGHF/run_OmegaCToXiPiInjected.sh | 2 +- MC/run/PWGHF/run_XiCToXiPiInjected.sh | 2 +- MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh | 2 +- MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh | 2 +- MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh | 2 +- MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh | 2 +- MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh | 2 +- MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh | 2 +- MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh | 2 +- MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh | 2 +- MC/run/PWGLF/run_Coalescence_pp.sh | 2 +- MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh | 2 +- MC/run/PWGLF/run_GeneratorLF_highpt.sh | 2 +- MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh | 2 +- MC/run/PWGLF/run_HyperInjectedGap.sh | 2 +- MC/run/PWGLF/run_HyperNucleiInjectedGap.sh | 2 +- MC/run/PWGLF/run_HypertritonInjected.sh | 2 +- MC/run/PWGLF/run_HypertritonInjectedGap.sh | 2 +- MC/run/PWGLF/run_NucleiFwdInjectedGap.sh | 2 +- MC/run/PWGLF/run_OmegaInjected.sh | 2 +- MC/run/PWGLF/run_XSectionVariation.sh | 2 +- 60 files changed, 62 insertions(+), 62 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 39af5c9a5..d93406e41 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -8,12 +8,12 @@ # # Execution examples: # - pp PYTHIA jets, 2 events, triggered on high pT decay photons on all barrel calorimeters acceptance, eCMS 13 TeV -# ./o2dpg_sim_workflow.py -e TGeant3 -ns 2 -j 8 -tf 1 -mod "--skipModules ZDC" -col pp -eCM 13000 \ +# ./o2dpg_sim_workflow.py -e TGeant3 -ns 2 -j 8 -tf 1 -col pp -eCM 13000 \ # -proc "jets" -ptHatBin 3 \ # -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_decay_gamma_allcalo_TrigPt3_5.ini" # # - pp PYTHIA ccbar events embedded into heavy-ion environment, 2 PYTHIA events into 1 bkg event, beams energy 2.510 -# ./o2dpg_sim_workflow.py -e TGeant3 -nb 1 -ns 2 -j 8 -tf 1 -mod "--skipModules ZDC" \ +# ./o2dpg_sim_workflow.py -e TGeant3 -nb 1 -ns 2 -j 8 -tf 1 \ # -col pp -eA 2.510 -proc "ccbar" --embedding # diff --git a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh index a02dd7bfd..e15940a53 100644 --- a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh +++ b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg "heavy_ion" -colBkg PbPb --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full --fwdmatching-save-trainingdata diff --git a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh index 8b86a4e82..2becd0cc5 100755 --- a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --fwdmatching-4-param --fwdmatching-cut-4-param diff --git a/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh b/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh index a57e92393..4d44a6853 100755 --- a/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_midy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} diff --git a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh index 2b791f223..a1d2f9f57 100755 --- a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh index 66a70fd86..0dad5b4a5 100755 --- a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap.ini -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh b/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh index 5ae445278..38dd22686 100755 --- a/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh +++ b/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-2} NWORKERS=${NWORKERS:-4} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_Psi2S_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg "heavy_ion" -colBkg PbPb --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh b/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh index 5adec6ade..9bd9b125a 100755 --- a/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_Psi2S_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} diff --git a/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh b/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh index 4a869def0..58e9cb74e 100755 --- a/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_Psi2S_midy.ini \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} -interactionRate 500000 diff --git a/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh b/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh index 1065708f9..5c43fda51 100755 --- a/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh +++ b/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToBplus_midy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} diff --git a/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh b/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh index 1daadceb9..46aed6068 100755 --- a/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToBplus_midy_triggerGap.ini -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh b/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh index b594c80af..396530969 100755 --- a/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh +++ b/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh @@ -14,7 +14,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} NBOXMUONS=${NBOXMUONS:-2} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorBoxFwd.C;GeneratorExternal.funcName=fwdMuBoxGen()" -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full --fwdmatching-save-trainingdata diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh index 7cc4e0c69..e8d2462d3 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_PbPb5TeV.C;GeneratorExternal.funcName=GeneratorCocktailPromptCharmoniaToMuonEvtGen_PbPb5TeV()" \ -genBkg pythia8 -procBkg "heavy_ion" -colBkg PbPb --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full --fwdmatching-save-trainingdata -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh index cd8e490ae..7dbe40c4c 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh @@ -13,7 +13,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} TARGETTASK=${TARGETTASK:+-tt ${TARGETTASK}} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorParamPromptJpsiToMuonEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorParamPromptJpsiToMuonEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --fwdmatching-4-param --fwdmatching-cut-4-param -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh index b4149c096..7b6d2f294 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh index bcb3092b9..fb1a8ca90 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh b/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh index a4a7d2f69..e2e9ec057 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh b/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh index 92d057a33..ed549861a 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -interactionRate 500000 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -interactionRate 500000 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap.ini # run workflow diff --git a/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh b/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh index 1c4ecb771..3634d30d2 100755 --- a/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiFwdy_TriggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh b/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh index c3708c471..203aa4048 100755 --- a/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh +++ b/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh b/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh index 6f2b55ba3..caf085726 100755 --- a/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh @@ -12,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptPsi2SFwdy_TriggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh b/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh index 91ed27299..b18ba13cd 100755 --- a/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh +++ b/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh @@ -20,7 +20,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorJPsiHFCorr_ccbar.ini \ # run workflow diff --git a/MC/run/PWGEM/runHFFullToDielectrons_pp.sh b/MC/run/PWGEM/runHFFullToDielectrons_pp.sh index 4520dc008..e17ba6516 100644 --- a/MC/run/PWGEM/runHFFullToDielectrons_pp.sh +++ b/MC/run/PWGEM/runHFFullToDielectrons_pp.sh @@ -34,7 +34,7 @@ fi -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ ${SEED} \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runHFGapToDielectrons_pp.sh b/MC/run/PWGEM/runHFGapToDielectrons_pp.sh index 16fb2a9cb..9cf1b5556 100644 --- a/MC/run/PWGEM/runHFGapToDielectrons_pp.sh +++ b/MC/run/PWGEM/runHFGapToDielectrons_pp.sh @@ -35,7 +35,7 @@ fi -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runHFToDielectrons_pp.sh b/MC/run/PWGEM/runHFToDielectrons_pp.sh index a31658185..ab41fe0ac 100644 --- a/MC/run/PWGEM/runHFToDielectrons_pp.sh +++ b/MC/run/PWGEM/runHFToDielectrons_pp.sh @@ -33,7 +33,7 @@ fi -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 500000 diff --git a/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh b/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh index d369c9cb3..8b34e2b78 100644 --- a/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh +++ b/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh @@ -18,7 +18,7 @@ NP=${NP:-1} CONFIGNAME="Generator_GapTriggered_LFee_all_np${NP}_gap${GAP}.ini" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh b/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh index 1b6ae8b45..76a456f2f 100644 --- a/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh +++ b/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh @@ -18,7 +18,7 @@ NP=${NP:-1} CONFIGNAME="Generator_GapTriggered_LFgamma_np${NP}_gap${GAP}.ini" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh b/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh index f1a6251cd..85642a50c 100644 --- a/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh +++ b/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh @@ -16,7 +16,7 @@ #CONFIGNAME="Generator_GapTriggered_LFmumu_np1_gap5.ini" -#${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +#${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ #-ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ #-confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} @@ -41,7 +41,7 @@ INTRATE=${INTRATE:-500000} CONFIGNAME="Generator_GapTriggered_LFmumu.ini" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGGAJE/run_decaygammajets.sh b/MC/run/PWGGAJE/run_decaygammajets.sh index 56dd69b46..039b6ac5b 100755 --- a/MC/run/PWGGAJE/run_decaygammajets.sh +++ b/MC/run/PWGGAJE/run_decaygammajets.sh @@ -77,7 +77,7 @@ echo 'Detector acceptance option ' $PARTICLE_ACCEPTANCE ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_decay_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma.sh b/MC/run/PWGGAJE/run_dirgamma.sh index 688da9f87..daca947f2 100755 --- a/MC/run/PWGGAJE/run_dirgamma.sh +++ b/MC/run/PWGGAJE/run_dirgamma.sh @@ -61,7 +61,7 @@ echo 'Parton PDG option ' $CONFIG_OUTPARTON_PDG ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma_embedding.sh b/MC/run/PWGGAJE/run_dirgamma_embedding.sh index 6a116e7c7..c867a3759 100755 --- a/MC/run/PWGGAJE/run_dirgamma_embedding.sh +++ b/MC/run/PWGGAJE/run_dirgamma_embedding.sh @@ -59,7 +59,7 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma_hook.sh b/MC/run/PWGGAJE/run_dirgamma_hook.sh index c42c58aeb..8b108f4d7 100755 --- a/MC/run/PWGGAJE/run_dirgamma_hook.sh +++ b/MC/run/PWGGAJE/run_dirgamma_hook.sh @@ -61,7 +61,7 @@ echo 'Parton PDG option ' $CONFIG_OUTPARTON_PDG ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/hook_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh b/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh index 07a3c2737..8d6a37b83 100755 --- a/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh +++ b/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh @@ -65,7 +65,7 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/hook_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_jets.sh b/MC/run/PWGGAJE/run_jets.sh index 9cb65704e..9e31cbcd0 100755 --- a/MC/run/PWGGAJE/run_jets.sh +++ b/MC/run/PWGGAJE/run_jets.sh @@ -40,7 +40,7 @@ fi ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} -interactionRate 500000 # run workflow diff --git a/MC/run/PWGGAJE/run_jets_HF_bbbar.sh b/MC/run/PWGGAJE/run_jets_HF_bbbar.sh index 8f5f10770..d9749d300 100644 --- a/MC/run/PWGGAJE/run_jets_HF_bbbar.sh +++ b/MC/run/PWGGAJE/run_jets_HF_bbbar.sh @@ -45,7 +45,7 @@ fi ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen external -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -interactionRate 500000 -confKey "Diamond.width[2]=6." ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini \ -weightPow ${WEIGHTPOW} diff --git a/MC/run/PWGGAJE/run_jets_HF_ccbar.sh b/MC/run/PWGGAJE/run_jets_HF_ccbar.sh index 972464d0b..22aece831 100644 --- a/MC/run/PWGGAJE/run_jets_HF_ccbar.sh +++ b/MC/run/PWGGAJE/run_jets_HF_ccbar.sh @@ -24,7 +24,7 @@ SIMENGINE=${SIMENGINE:-TGeant4} #ccbar filter and bias2SelectionPow and PtHat settings are in the ini file given below ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen external -proc "jets" \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -interactionRate 500000 -confKey "Diamond.width[2]=6." ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGGAJE/ini/GeneratorHFJETrigger_ccbar.ini diff --git a/MC/run/PWGGAJE/run_jets_embedding.sh b/MC/run/PWGGAJE/run_jets_embedding.sh index bf7a8f433..d58ed2aca 100755 --- a/MC/run/PWGGAJE/run_jets_embedding.sh +++ b/MC/run/PWGGAJE/run_jets_embedding.sh @@ -45,7 +45,7 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} \ -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} -interactionRate 500000 # run workflow ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json diff --git a/MC/run/PWGGAJE/run_jets_hook.sh b/MC/run/PWGGAJE/run_jets_hook.sh index d54deed66..66a557813 100755 --- a/MC/run/PWGGAJE/run_jets_hook.sh +++ b/MC/run/PWGGAJE/run_jets_hook.sh @@ -57,7 +57,7 @@ echo 'Parton PDG option ' $CONFIG_OUTPARTON_PDG ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/hook_jets.ini" \ -weightPow ${WEIGHTPOW} # run workflow diff --git a/MC/run/PWGHF/run_OmegaCInjected.sh b/MC/run/PWGHF/run_OmegaCInjected.sh index 1e6ca8994..924f4b3e7 100755 --- a/MC/run/PWGHF/run_OmegaCInjected.sh +++ b/MC/run/PWGHF/run_OmegaCInjected.sh @@ -25,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini diff --git a/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh b/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh index dc1ca3e13..0584ebe13 100755 --- a/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh +++ b/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh @@ -25,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini diff --git a/MC/run/PWGHF/run_XiCToXiPiInjected.sh b/MC/run/PWGHF/run_XiCToXiPiInjected.sh index c1ef01567..112eb49a6 100755 --- a/MC/run/PWGHF/run_XiCToXiPiInjected.sh +++ b/MC/run/PWGHF/run_XiCToXiPiInjected.sh @@ -25,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini diff --git a/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh index c81be1706..ccec3bbb9 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh @@ -21,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh index c392034c2..d5c2973d4 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh @@ -20,7 +20,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh index 964d91638..c84fa121d 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh @@ -20,7 +20,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh index 8c78832fe..9a2e71c96 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh @@ -22,7 +22,7 @@ NBKGEVENTS=$(($NSIGEVENTS * $NBKGEVENTSPERSIGNALEVENT)) # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen pythia8 -genBkg pythia8 -procBkg "" -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen pythia8 -genBkg pythia8 -procBkg "" -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding --embeddPattern r0:e${NBKGEVENTSPERSIGNALEVENT} -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini -iniBkg $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_bkg.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh index b273ab2b4..44c50816f 100644 --- a/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh @@ -21,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh index 7d933a8bb..71cee05dd 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh @@ -21,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh index 5f4be71d1..b51b22859 100644 --- a/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh @@ -21,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh b/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh index 59024dfae..1267296bb 100644 --- a/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh +++ b/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh @@ -21,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -col pp -gen pythia8 -proc "inel" -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 10000 -confKey "Diamond.width[2]=6." -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -col pp -gen pythia8 -proc "inel" -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 10000 -confKey "Diamond.width[2]=6." -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHF_ccbar.ini \ # run workflow diff --git a/MC/run/PWGLF/run_Coalescence_pp.sh b/MC/run/PWGLF/run_Coalescence_pp.sh index 747bd029f..c01ac6ac6 100755 --- a/MC/run/PWGLF/run_Coalescence_pp.sh +++ b/MC/run/PWGLF/run_Coalescence_pp.sh @@ -22,7 +22,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_Coalescence.ini # run workflow diff --git a/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh b/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh index ca12b3bd3..49f7ca958 100644 --- a/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh +++ b/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh @@ -19,7 +19,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_antid_and_highpt.ini # run workflow diff --git a/MC/run/PWGLF/run_GeneratorLF_highpt.sh b/MC/run/PWGLF/run_GeneratorLF_highpt.sh index e6d839983..817cd3303 100644 --- a/MC/run/PWGLF/run_GeneratorLF_highpt.sh +++ b/MC/run/PWGLF/run_GeneratorLF_highpt.sh @@ -19,7 +19,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_HighPt.ini # run workflow diff --git a/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh b/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh index bb0c3d779..ebf598e24 100644 --- a/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh +++ b/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh @@ -19,7 +19,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_highpt_strangeness.ini # run workflow diff --git a/MC/run/PWGLF/run_HyperInjectedGap.sh b/MC/run/PWGLF/run_HyperInjectedGap.sh index 1dc365b1a..2b408891a 100644 --- a/MC/run/PWGLF/run_HyperInjectedGap.sh +++ b/MC/run/PWGLF/run_HyperInjectedGap.sh @@ -23,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHyper${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh b/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh index 2797d120b..d53659f9a 100644 --- a/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh +++ b/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh @@ -23,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHyperNuclei${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_HypertritonInjected.sh b/MC/run/PWGLF/run_HypertritonInjected.sh index 80f8f3cd2..27ed61b17 100644 --- a/MC/run/PWGLF/run_HypertritonInjected.sh +++ b/MC/run/PWGLF/run_HypertritonInjected.sh @@ -23,7 +23,7 @@ ENERGY=${ENERGY:-5520} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHypertriton${SYSTEM}.ini # run workflow diff --git a/MC/run/PWGLF/run_HypertritonInjectedGap.sh b/MC/run/PWGLF/run_HypertritonInjectedGap.sh index 9c0a13739..2802e2186 100644 --- a/MC/run/PWGLF/run_HypertritonInjectedGap.sh +++ b/MC/run/PWGLF/run_HypertritonInjectedGap.sh @@ -23,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHypertriton${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh b/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh index 18faf215a..faef33201 100755 --- a/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh +++ b/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh @@ -23,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFNucleiFwd${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_OmegaInjected.sh b/MC/run/PWGLF/run_OmegaInjected.sh index cd7f21936..7c97201dc 100755 --- a/MC/run/PWGLF/run_OmegaInjected.sh +++ b/MC/run/PWGLF/run_OmegaInjected.sh @@ -25,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLFOmegaEmb.ini diff --git a/MC/run/PWGLF/run_XSectionVariation.sh b/MC/run/PWGLF/run_XSectionVariation.sh index bd5ce7e94..96fb19571 100644 --- a/MC/run/PWGLF/run_XSectionVariation.sh +++ b/MC/run/PWGLF/run_XSectionVariation.sh @@ -23,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # 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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${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[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHyperNuclei${SYSTEM}Gap.ini # run workflow From 798980183ca4d3a33493cc0a7c557a219654503a Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Sat, 29 Nov 2025 18:21:10 +0100 Subject: [PATCH 162/362] Cleaner --skipModules treatment / remove deprecated -mod Remove usage of old `-mod` usage, which in fact didn't have any effect. Now offer a --skipModules option to explicitely disable modules in material budget of o2-sim as a more clear solution. (This will not influence the material budget LUT, so be careful) --- MC/bin/o2dpg_sim_workflow.py | 22 +++++++++++++++---- MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh | 2 +- .../PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh | 2 +- MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh | 2 +- MC/run/PWGLF/runLFInjector.sh | 6 ++--- MC/run/PWGUD/runDiffEvents.sh | 2 -- MC/run/PWGUD/runPythiaAndDiffEvents.sh | 3 --- 7 files changed, 23 insertions(+), 16 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index d93406e41..376ae8ac8 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -108,7 +108,7 @@ parser.add_argument('--force-n-workers', dest='force_n_workers', action='store_true', help='by default, number of workers is re-computed ' 'for given interaction rate; ' 'pass this to avoid that') -parser.add_argument('-mod',help='Active modules (deprecated)', default='--skipModules ZDC') +parser.add_argument('--skipModules',nargs="*", help="List of modules to skip in geometry budget (and therefore processing)", default=["ZDC"]) parser.add_argument('--with-ZDC', action='store_true', help='Enable ZDC in workflow') parser.add_argument('-seed',help='random seed number', default=None) parser.add_argument('-o',help='output workflow file', default='workflow.json') @@ -408,7 +408,21 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): NTIMEFRAMES=int(args.tf) NWORKERS=args.n_workers -MODULES = "--skipModules ZDC" if not isActive("ZDC") else "" + +# Processing skipped material budget (modules): +# - If user did NOT specify --with-ZDC +# - AND ZDC is not already in the list +# --> append ZDC automatically +if args.with_ZDC: + # User wants ZDC to *not* be skipped → ensure it's removed + args.skipModules = [m for m in args.skipModules if m != "ZDC"] +else: + # If user did not request --with-ZDC, + # auto-append ZDC unless already present + if "ZDC" not in args.skipModules: + args.skipModules.append("ZDC") + +SKIPMODULES = " ".join(["--skipModules"] + args.skipModules) if len(args.skipModules) > 0 else "" SIMENGINE=args.e BFIELD=args.field RNDSEED=args.seed # typically the argument should be the jobid, but if we get None the current time is used for the initialisation @@ -716,7 +730,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): bkgsimneeds = [BKG_CONFIG_task['name'], GRP_TASK['name'], PreCollContextTask['name']] BKGtask=createTask(name='bkgsim', lab=["GEANT"], needs=bkgsimneeds, cpu=NWORKERS) BKGtask['cmd']='${O2_ROOT}/bin/o2-sim -e ' + SIMENGINE + ' -j ' + str(NWORKERS) + ' -n ' + str(NBKGEVENTS) \ - + ' -g ' + str(GENBKG) + ' ' + str(MODULES) + ' -o bkg ' + str(INIBKG) \ + + ' -g ' + str(GENBKG) + ' ' + str(SKIPMODULES) + ' -o bkg ' + str(INIBKG) \ + ' --field ccdb ' + str(CONFKEYBKG) \ + ('',' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) \ + ' --vertexMode ' + vtxmode_sgngen \ @@ -947,7 +961,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): sgnmem = 6000 if COLTYPE == 'PbPb' else 4000 SGNtask=createTask(name='sgnsim_'+str(tf), needs=signalneeds, tf=tf, cwd='tf'+str(tf), lab=["GEANT"], relative_cpu=7/8, n_workers=NWORKERS_TF, mem=str(sgnmem)) - sgncmdbase = '${O2_ROOT}/bin/o2-sim -e ' + str(SIMENGINE) + ' ' + str(MODULES) + ' -n ' + str(NSIGEVENTS) + ' --seed ' + str(TFSEED) \ + sgncmdbase = '${O2_ROOT}/bin/o2-sim -e ' + str(SIMENGINE) + ' ' + str(SKIPMODULES) + ' -n ' + str(NSIGEVENTS) + ' --seed ' + str(TFSEED) \ + ' --field ccdb -j ' + str(NWORKERS_TF) + ' ' + str(CONFKEY) + ' ' + str(INIFILE) + ' -o ' + signalprefix + ' ' + embeddinto \ + ' --detectorList ' + args.detectorList \ + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) diff --git a/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh b/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh index 7875aa9c7..cd5209ab2 100644 --- a/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh +++ b/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh @@ -16,7 +16,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "MCH MFT MID ITS" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToMuonsSemileptonic_fwdy.ini \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 2000 --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh b/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh index 97bdb73bb..69f363b23 100644 --- a/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh +++ b/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh @@ -16,7 +16,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "MCH MFT MID ITS" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToDDbarToMuons_fwdy.ini \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 2000 --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh b/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh index 96759e011..58cf706e3 100644 --- a/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh +++ b/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh @@ -16,7 +16,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "MCH MFT MID ITS" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_ccbarToMuonsSemileptonic_fwdy.ini \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 2000 --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGLF/runLFInjector.sh b/MC/run/PWGLF/runLFInjector.sh index 9e91dc07a..16a62602e 100755 --- a/MC/run/PWGLF/runLFInjector.sh +++ b/MC/run/PWGLF/runLFInjector.sh @@ -6,7 +6,6 @@ # The following variables can be set from the outside: # - NWORKERS: number of workers to use (default 8) -# - MODULES: modules to be run (default "--skipModules ZDC") # - SIMENGINE: simulation engine (default TGeant4) # - NSIGEVENTS: number of signal events (default 1) # - NBKGEVENTS: number of background events (default 1) @@ -40,7 +39,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 # ----------- START ACTUAL JOB ------------------------------- NWORKERS=${NWORKERS:-8} -MODULES=${MODULES:---skipModules ZDC} SIMENGINE=${SIMENGINE:-TGeant4} NSIGEVENTS=${NSIGEVENTS:-1} NBKGEVENTS=${NBKGEVENTS:-1} @@ -63,9 +61,9 @@ echo "ENERGY = $ENERGY" echo "CFGINIFILE = $CFGINIFILE" # 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}" \ +${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} \ -ini ${CFGINIFILE} # run workflow O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} -$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS \ No newline at end of file +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS diff --git a/MC/run/PWGUD/runDiffEvents.sh b/MC/run/PWGUD/runDiffEvents.sh index 9d4bd065d..632742730 100755 --- a/MC/run/PWGUD/runDiffEvents.sh +++ b/MC/run/PWGUD/runDiffEvents.sh @@ -26,7 +26,6 @@ DVX=0.01 DVY=0.01 DVZ=6.00 -MODULES="--skipModules ZDC" # create workflow ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py \ @@ -37,7 +36,6 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py \ -ns ${NSIGPTF} \ -tf ${NTIMEFRAMES} \ -e TGeant4 \ - -mod "${MODULES}" \ -interactionRate ${SIGINTRATE} \ -confKey "HepMC.fileName="${FHEPMC}";HepMC.version=3;Diamond.width[0]="${DVX}";Diamond.width[1]="${DVY}";Diamond.width[2]="${DVZ}"" diff --git a/MC/run/PWGUD/runPythiaAndDiffEvents.sh b/MC/run/PWGUD/runPythiaAndDiffEvents.sh index 57928cee7..6484cbb8c 100755 --- a/MC/run/PWGUD/runPythiaAndDiffEvents.sh +++ b/MC/run/PWGUD/runPythiaAndDiffEvents.sh @@ -27,8 +27,6 @@ DVX=0.01 DVY=0.01 DVZ=6.00 -MODULES="--skipModules ZDC" - # create workflow SIGINTRATE=`echo "${BKGINTRATE}*${NSIGPTF}/${NBKGPTF}" | bc` NBKG=`echo "${NBKGPTF}*${NTIMEFRAMES}" | bc` @@ -38,7 +36,6 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py \ -eCM ${ECM} \ -j ${NWORKERS} \ -e TGeant4 \ - -mod "${MODULES}" \ -tf ${NTIMEFRAMES} \ -interactionRate ${BKGINTRATE} \ -gen hepmc \ From 5b59f73dd0e593938ff53b6ef116132ab705705d Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 2 Dec 2025 13:09:42 +0100 Subject: [PATCH 163/362] Improvement for --skipModules/--skipReadout --- MC/bin/o2dpg_sim_workflow.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 376ae8ac8..db33b2f8e 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -109,6 +109,7 @@ 'for given interaction rate; ' 'pass this to avoid that') parser.add_argument('--skipModules',nargs="*", help="List of modules to skip in geometry budget (and therefore processing)", default=["ZDC"]) +parser.add_argument('--skipReadout',nargs="*", help="List of modules to take out from readout", default=[""]) parser.add_argument('--with-ZDC', action='store_true', help='Enable ZDC in workflow') parser.add_argument('-seed',help='random seed number', default=None) parser.add_argument('-o',help='output workflow file', default='workflow.json') @@ -257,6 +258,19 @@ def load_external_config(configfile): print(f"INFO: Written additional config key parameters to JSON {config_key_param_path}") json.dump(anchorConfig, f, indent=2) +# Processing skipped material budget (modules): +# - If user did NOT specify --with-ZDC +# - AND ZDC is not already in the list +# --> append ZDC automatically +if args.with_ZDC: + # User wants ZDC to *not* be skipped → ensure it's removed + args.skipModules = [m for m in args.skipModules if m != "ZDC"] +else: + # If user did not request --with-ZDC, + # auto-append ZDC unless already present + if "ZDC" not in args.skipModules: + args.skipModules.append("ZDC") + # with this we can tailor the workflow to the presence of # certain detectors # these are all detectors that should be assumed active @@ -267,14 +281,14 @@ def load_external_config(configfile): # if "all" here, there was in fact nothing in the anchored script, set to what is passed to this script (which it either also "all" or a subset) activeDetectors = readout_detectors elif readout_detectors != 'all' and activeDetectors != 'all': - # in this case both are comma-seperated lists. Take intersection + # in this case both are comma-separated lists. Take intersection r = set(readout_detectors.split(',')) a = set(activeDetectors.split(',')) activeDetectors = ','.join(r & a) # the last case: simply take what comes from the anchored config # convert to set/hashmap -activeDetectors = { det:1 for det in activeDetectors.split(',') } +activeDetectors = { det:1 for det in activeDetectors.split(',') if det not in args.skipModules and det not in args.skipReadout} for det in activeDetectors: activate_detector(det) @@ -409,18 +423,6 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): NTIMEFRAMES=int(args.tf) NWORKERS=args.n_workers -# Processing skipped material budget (modules): -# - If user did NOT specify --with-ZDC -# - AND ZDC is not already in the list -# --> append ZDC automatically -if args.with_ZDC: - # User wants ZDC to *not* be skipped → ensure it's removed - args.skipModules = [m for m in args.skipModules if m != "ZDC"] -else: - # If user did not request --with-ZDC, - # auto-append ZDC unless already present - if "ZDC" not in args.skipModules: - args.skipModules.append("ZDC") SKIPMODULES = " ".join(["--skipModules"] + args.skipModules) if len(args.skipModules) > 0 else "" SIMENGINE=args.e @@ -1443,7 +1445,7 @@ def getDigiTaskName(det): TPCRECOtask['name'], ITSTPCMATCHtask['name'], TRDTRACKINGtask2['name'] if isActive("TRD") else None] - toftracksrcdefault = dpl_option_from_config(anchorConfig, 'o2-tof-matcher-workflow', '--track-sources', default_value='TPC,ITS-TPC,TPC-TRD,ITS-TPC-TRD') + toftracksrcdefault = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tof-matcher-workflow', '--track-sources', default_value='TPC,ITS-TPC,TPC-TRD,ITS-TPC-TRD')) tofusefit = option_if_available('o2-tof-matcher-workflow', '--use-fit', envfile=async_envfile) TOFTPCMATCHERtask = createTask(name='toftpcmatch_'+str(tf), needs=toftpcmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') tofmatcher_cmd_parts = [ From 0e607be0e46afa8751df21d15ce870e04caa10b9 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Wed, 3 Dec 2025 16:41:23 +0100 Subject: [PATCH 164/362] Make enhancement factor of Xi and Omega configurable (#2198) --- ...neratorLF_Strangeness_OO5360_injection.ini | 2 +- ..._Strangeness_OO5360_injection_omega100.ini | 6 ++++ ...F_Strangeness_OO5360_injection_omega30.ini | 6 ++++ ..._Strangeness_OO5360_injection_omega300.ini | 6 ++++ ...F_Strangeness_OO5360_injection_omega50.ini | 6 ++++ ..._Strangeness_OO5360_injection_omega500.ini | 6 ++++ ...LF_Strangeness_OO5360_injection_omega100.C | 1 + ...rLF_Strangeness_OO5360_injection_omega30.C | 1 + ...LF_Strangeness_OO5360_injection_omega300.C | 1 + ...rLF_Strangeness_OO5360_injection_omega50.C | 1 + ...LF_Strangeness_OO5360_injection_omega500.C | 1 + .../generator_pythia8_extraStrangeness.C | 29 ++++++++++++------- 12 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega100.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega30.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega300.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega50.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega500.ini create mode 120000 MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega100.C create mode 120000 MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega30.C create mode 120000 MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega300.C create mode 120000 MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega50.C create mode 120000 MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega500.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini index edb6a5626..33df39f1b 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C -funcName=generator_extraStrangeness() +funcName=generator_extraStrangeness(5,30) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega100.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega100.ini new file mode 100644 index 000000000..326f7e6c8 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega100.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,100) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega30.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega30.ini new file mode 100644 index 000000000..ea7fa77a8 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega30.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,30) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega300.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega300.ini new file mode 100644 index 000000000..2d7273ab3 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega300.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,300) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega50.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega50.ini new file mode 100644 index 000000000..9b9b041ac --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega50.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,50) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega500.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega500.ini new file mode 100644 index 000000000..d3b36a244 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega500.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,500) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega100.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega100.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega100.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega30.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega30.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega30.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega300.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega300.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega300.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega50.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega50.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega50.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega500.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega500.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega500.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C b/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C index a43612ca5..f518c1d7b 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C @@ -10,13 +10,14 @@ #include "TDatabasePDG.h" #include +#include #include class GeneratorPythia8ExtraStrangeness : public o2::eventgen::GeneratorPythia8 { public: /// Constructor - GeneratorPythia8ExtraStrangeness() { + GeneratorPythia8ExtraStrangeness(double enhancementXi, double enhancementOmega) { genMinPt=0.0; genMaxPt=20.0; genminY=-1.0; @@ -35,8 +36,10 @@ public: xProd=0; yProd=0; zProd=0; - xProd=0.; yProd=0.; zProd=0.; - + + fEnhancementXi = enhancementXi; + fEnhancementOmega = enhancementOmega; + fLVHelper = std::make_unique(); fSpectrumXi = std::make_unique("fSpectrumXi", this, &GeneratorPythia8ExtraStrangeness::boltzPlusPower, 0., genMaxPt, 5, "GeneratorPythia8ExtraStrangeness", "boltzPlusPower"); @@ -60,7 +63,7 @@ public: Double_t mt = TMath::Sqrt(mass * mass + pt * pt); return TMath::ASinH(mt / pt * TMath::SinH(y)); } - + /// set 4-momentum void set4momentum(double input_px, double input_py, double input_pz){ px = input_px; @@ -206,7 +209,7 @@ Double_t boltzPlusPower(const Double_t *x, const Double_t *p) // Info in : created default TCanvas with name c1 //Adjust relative abundance of multi-strange particles by injecting some Double_t lExpectedXiToPion = TMath::Max(4.74929e-03 - 4.08255e-03*TMath::Exp(-nChargedParticlesAtMidRap/4.76660e+00) - 0.00211334,0.); - Double_t lExpectedXi = 5.0*nPionsAtMidRap*lExpectedXiToPion; // extra rich, factor 5 + Double_t lExpectedXi = fEnhancementXi*nPionsAtMidRap*lExpectedXiToPion; // extra rich, factor 5 Int_t lXiYield = gRandom->Poisson(3*lExpectedXi); //factor 3: fix the rapidity acceptance m = 1.32171; pdg = 3312; @@ -227,7 +230,7 @@ Double_t boltzPlusPower(const Double_t *x, const Double_t *p) // OMEGA ABUNDANCE FIX //Adjust relative abundance of multi-strange particles by injecting some Double_t lExpectedOmegaToPion = TMath::Max(8.55057e-04 - 7.38732e-04*TMath::Exp(-nChargedParticlesAtMidRap/2.40545e+01) - 6.56785e-05,0.); - Double_t lExpectedOmega = 30.0*nPionsAtMidRap*lExpectedOmegaToPion; // extra rich, factor 30 (omega -> rarer -> smaller Nch bias -> ok to enrich more) + Double_t lExpectedOmega = fEnhancementOmega*nPionsAtMidRap*lExpectedOmegaToPion; // extra rich, factor 30 (omega -> rarer -> smaller Nch bias -> ok to enrich more) Int_t lOmegaYield = gRandom->Poisson(3*lExpectedOmega); //factor 3: fix the rapidity acceptance m = 1.67245; pdg = 3334; @@ -270,16 +273,22 @@ private: double xProd; /// x-coordinate position production vertex [cm] double yProd; /// y-coordinate position production vertex [cm] double zProd; /// z-coordinate position production vertex [cm] - + + double fEnhancementXi; /// Enhancement factor for Xi + double fEnhancementOmega; /// Enhancement factor for Omega + std::unique_ptr fLVHelper; std::unique_ptr fSpectrumXi; std::unique_ptr fSpectrumOm; }; - FairGenerator *generator_extraStrangeness() + FairGenerator *generator_extraStrangeness(double enhancementXi = 5.0, double enhancementOmega = 30.0) { - auto generator = new GeneratorPythia8ExtraStrangeness(); - gRandom->SetSeed(0); + auto generator = new GeneratorPythia8ExtraStrangeness(enhancementXi,enhancementOmega); + //gRandom->SetSeed(0); + + // Initialize ROOT random number generator with a time-dependent seed to get different sequences each run + gRandom->SetSeed(static_cast(time(nullptr))); generator->readString("Random:setSeed = on"); generator->readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); return generator; From 9dc9ea3d9ab509830100c255d259847a711b8682 Mon Sep 17 00:00:00 2001 From: klsmith15k Date: Thu, 4 Dec 2025 18:02:25 +0900 Subject: [PATCH 165/362] Add files via upload (#2199) missing test macro for PR#2186 --- ...and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C new file mode 100644 index 000000000..6f13ae05e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C @@ -0,0 +1,190 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./5; // one event triggered out of 5 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {211, 333}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = float(nSignalGoodDecay) / nSignals; + if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} From 57566cc38c8d4b016d31c9cd69f19fbcbfce576c Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 12 Nov 2025 15:46:45 +0100 Subject: [PATCH 166/362] Move SVERTEXING_SOURCES definition to dpl-workflow to allow special online mode --- DATA/common/setenv.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/DATA/common/setenv.sh b/DATA/common/setenv.sh index 574f42739..637476a0c 100755 --- a/DATA/common/setenv.sh +++ b/DATA/common/setenv.sh @@ -195,6 +195,7 @@ TRD_SOURCES= TOF_SOURCES= HMP_SOURCES= TRACK_SOURCES= +: ${TRACK_SOURCES_GLO:=} has_detectors_reco ITS TPC && has_detector_matching ITSTPC && add_comma_separated TRACK_SOURCES "ITS-TPC" has_detectors_reco TPC TRD && has_detector_matching TPCTRD && { add_comma_separated TRD_SOURCES TPC; add_comma_separated TRACK_SOURCES "TPC-TRD"; } has_detectors_reco ITS TPC TRD && has_detector_matching ITSTPC && has_detector_matching ITSTPCTRD && { add_comma_separated TRD_SOURCES ITS-TPC; add_comma_separated TRACK_SOURCES "ITS-TPC-TRD"; } @@ -211,6 +212,8 @@ has_detectors_reco HMP TPC TOF && has_detector_matching TPCTOF && add_comma_sepa has_detectors_reco HMP TPC TRD TOF && has_detector_matching TPCTRD && has_detector_matching TPCTRDTOF && add_comma_separated HMP_SOURCES "TPC-TRD-TOF" has_detectors_reco MFT MCH && has_detector_matching MFTMCH && add_comma_separated TRACK_SOURCES "MFT-MCH" has_detectors_reco MCH MID && has_detector_matching MCHMID && add_comma_separated TRACK_SOURCES "MCH-MID" +[[ "0$TRACK_SOURCES_GLO" == "0" ]] && TRACK_SOURCES_GLO=$TRACK_SOURCES + for det in `echo $LIST_OF_DETECTORS | sed "s/,/ /g"`; do if [[ $LIST_OF_ASYNC_RECO_STEPS =~ (^| )${det}( |$) ]]; then has_detector ${det} && has_processing_step ${det}_RECO && add_comma_separated TRACK_SOURCES "$det" @@ -241,12 +244,6 @@ fi [[ ! -z $VERTEXING_SOURCES ]] && PVERTEX_CONFIG+=" --vertexing-sources $VERTEXING_SOURCES" [[ ! -z $VERTEX_TRACK_MATCHING_SOURCES ]] && PVERTEX_CONFIG+=" --vertex-track-matching-sources $VERTEX_TRACK_MATCHING_SOURCES" -if [[ -z ${SVERTEXING_SOURCES:-} ]]; then - SVERTEXING_SOURCES="$VERTEXING_SOURCES" -elif [[ "${SVERTEXING_SOURCES^^}" == "NONE" ]]; then - SVERTEXING_SOURCES= -fi - # this option requires well calibrated timing beween different detectors, at the moment suppress it #has_detector_reco FT0 && PVERTEX_CONFIG+=" --validate-with-ft0" From 868db817fee0ab4700b07a4c9229e1bcfc1c6b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Thu, 4 Dec 2025 23:27:57 +0100 Subject: [PATCH 167/362] Add pythia CLR-BLC Modes 0,2,3 (#2201) - Based on https://link.springer.com/article/10.1007/JHEP08(2015)003 --- .../ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini | 9 ++++ .../ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini | 9 ++++ .../ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini | 9 ++++ .../ini/tests/pythia8_pp_clr-blc0_13tev.C | 19 ++++++++ .../ini/tests/pythia8_pp_clr-blc2_13tev.C | 1 + .../ini/tests/pythia8_pp_clr-blc3_13tev.C | 1 + .../generator/pythia8_pp_clr-blc0_13tev.cfg | 44 ++++++++++++++++++ .../generator/pythia8_pp_clr-blc2_13tev.cfg | 45 +++++++++++++++++++ .../generator/pythia8_pp_clr-blc3_13tev.cfg | 45 +++++++++++++++++++ 9 files changed, 182 insertions(+) create mode 100644 MC/config/ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini create mode 100644 MC/config/ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini create mode 100644 MC/config/ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini create mode 100644 MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc0_13tev.C create mode 120000 MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc2_13tev.C create mode 120000 MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc3_13tev.C create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini b/MC/config/ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini new file mode 100644 index 000000000..a08d45738 --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini b/MC/config/ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini new file mode 100644 index 000000000..25474d61c --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini b/MC/config/ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini new file mode 100644 index 000000000..00ee82a3f --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc0_13tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc0_13tev.C new file mode 100644 index 000000000..d258500c3 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc0_13tev.C @@ -0,0 +1,19 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "read"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << std::endl; + return 1; + } + + TTree* tree = (TTree*)file.Get("o2sim"); + + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc2_13tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc2_13tev.C new file mode 120000 index 000000000..fbe2c4ed8 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc2_13tev.C @@ -0,0 +1 @@ +pythia8_pp_clr-blc0_13tev.C \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc3_13tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc3_13tev.C new file mode 120000 index 000000000..fbe2c4ed8 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc3_13tev.C @@ -0,0 +1 @@ +pythia8_pp_clr-blc0_13tev.C \ No newline at end of file diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg new file mode 100644 index 000000000..a5fc8e17f --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg @@ -0,0 +1,44 @@ +### ============================================ +### PYTHIA 8 — CLR-BLC Mode 0 configuration +### Based on table: Monash vs CLR-BLC (Mode 0) https://link.springer.com/article/10.1007/JHEP08(2015)003 in Appendix A +### ============================================ + +### Beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13000. +Beams:frameType = 1 + +### Decays (match ALICE) +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10.0 + +### Processes and base tune +SoftQCD:inelastic = on # all inelastic processes +Tune:pp = 14 # Monash 2013 as baseline + +### String fragmentation +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 # probQQtoQ → Q (Mode 0,2,3) +StringFlav:probStoUD = 0.20 # s/u,d suppression (Mode 0,2,3) + +# Diquark–diquark join probabilities (vector of 4 numbers) +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 # (Mode 0,2,3) +### Multi-parton interactions +MultiPartonInteractions:pT0Ref = 2.12 # Mode 0 pT0Ref + +### Beam remnants +BeamRemnants:remnantMode = 1 # required for CR mode 1 +BeamRemnants:saturation = 5 + +### Colour reconnection: CLR-BLC Mode 0 +ColourReconnection:mode = 1 # new CR scheme +ColourReconnection:allowDoubleJunRem = off # as in table +ColourReconnection:m0 = 2.9 # Mode 0 mass scale +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.43 # Mode 0 +ColourReconnection:timeDilationMode = 0 # Mode 0 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg new file mode 100644 index 000000000..405de08bb --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg @@ -0,0 +1,45 @@ +### ============================================ +### PYTHIA 8 — CLR-BLC Mode 2 configuration +### Based on table: Monash vs CLR-BLC (Mode 2) https://link.springer.com/article/10.1007/JHEP08(2015)003 in Appendix A +### ============================================ + +### Beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13000. +Beams:frameType = 1 + +### Decays (match ALICE) +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10.0 + +### Processes and base tune +SoftQCD:inelastic = on # all inelastic processes +Tune:pp = 14 # Monash 2013 as baseline + +### String fragmentation +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 # probQQtoQ → Q (Mode 0,2,3) +StringFlav:probStoUD = 0.20 # s/u,d suppression (Mode 0,2,3) + +# Diquark–diquark join probabilities (vector of 4 numbers) +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 # (Mode 0,2,3) +### Multi-parton interactions +MultiPartonInteractions:pT0Ref = 2.15 # Mode 2 pT0Ref + +### Beam remnants +BeamRemnants:remnantMode = 1 # required for CR mode 1 +BeamRemnants:saturation = 5 + +### Colour reconnection: CLR-BLC Mode 2 +ColourReconnection:mode = 1 # new CR scheme +ColourReconnection:allowDoubleJunRem = off # as in table +ColourReconnection:m0 = 0.3 # Mode 2 mass scale +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.2 # Mode 2 +ColourReconnection:timeDilationMode = 2 # Mode 2 +ColourReconnection:timeDilationPar = 0.18 # Mode 2 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg new file mode 100644 index 000000000..34c006469 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg @@ -0,0 +1,45 @@ +### ============================================ +### PYTHIA 8 — CLR-BLC Mode 3 configuration +### Based on table: Monash vs CLR-BLC (Mode 3) https://link.springer.com/article/10.1007/JHEP08(2015)003 in Appendix A +### ============================================ + +### Beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13000. +Beams:frameType = 1 + +### Decays (match ALICE) +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10.0 + +### Processes and base tune +SoftQCD:inelastic = on # all inelastic processes +Tune:pp = 14 # Monash 2013 as baseline + +### String fragmentation +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 # probQQtoQ → Q (Mode 0,2,3) +StringFlav:probStoUD = 0.20 # s/u,d suppression (Mode 0,2,3) + +# Diquark–diquark join probabilities (vector of 4 numbers) +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 # (Mode 0,2,3) +### Multi-parton interactions +MultiPartonInteractions:pT0Ref = 2.05 # Mode 3 pT0Ref + +### Beam remnants +BeamRemnants:remnantMode = 1 # required for CR mode 1 +BeamRemnants:saturation = 5 + +### Colour reconnection: CLR-BLC Mode 3 +ColourReconnection:mode = 1 # new CR scheme +ColourReconnection:allowDoubleJunRem = off # as in table +ColourReconnection:m0 = 0.3 # Mode 3 mass scale +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.15 # Mode 3 +ColourReconnection:timeDilationMode = 3 # Mode 3 +ColourReconnection:timeDilationPar = 0.073 # Mode 3 + +Random:setSeed = on From 7f7a3412876e5e17ee12b31c3b22d6ff4965d465 Mon Sep 17 00:00:00 2001 From: Francesca Ercolessi Date: Fri, 5 Dec 2025 12:53:12 +0100 Subject: [PATCH 168/362] Correct deuteron pdg code --- MC/config/common/external/generator/CoalescencePythia8.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MC/config/common/external/generator/CoalescencePythia8.h b/MC/config/common/external/generator/CoalescencePythia8.h index 7fbeac6db..b1f392ba4 100644 --- a/MC/config/common/external/generator/CoalescencePythia8.h +++ b/MC/config/common/external/generator/CoalescencePythia8.h @@ -32,7 +32,7 @@ enum NucleiBits { kHe4 = 4, }; -std::vector pdgList = {10010010, 1000010030, 1000020030, 1010010030, 1000020040}; +std::vector pdgList = {1000010020, 1000010030, 1000020030, 1010010030, 1000020040}; std::vector massList = {1.875612, 2.80892113298, 2.808391, 2.991134, 3.727379}; bool doCoal(Pythia8::Event& event, int charge, int pdgCode, float mass, bool trivialCoal, double coalescenceRadius, bool nuclFromDecay, int iD1, int iD2, int iD3 = -1, int iD4 = -1) @@ -179,4 +179,4 @@ bool CoalescencePythia8(Pythia8::Event& event, std::vector inputPd } } return coalHappened; -} \ No newline at end of file +} From 56699f6c0c493523f626b7db6e6ae139c3fdede8 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 5 Dec 2025 11:45:40 +0100 Subject: [PATCH 169/362] TPC digitizer should not use internal multi-threading We are already doing parallelism through multiple lanes. --- MC/bin/o2dpg_sim_workflow.py | 1 + 1 file changed, 1 insertion(+) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index db33b2f8e..7c3dc19e3 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1123,6 +1123,7 @@ def putConfigValues(listOfMainKeys=[], localCF = {}, globalTFConfig = True): + ' --onlyDet TPC --TPCuseCCDB --interactionRate ' + str(INTRATE) + ' --tpc-lanes ' + str(NWORKERS_TF) \ + ' --incontext ' + str(CONTEXTFILE) + ' --disable-write-ini --early-forward-policy always --forceSelectedDets ' \ + ' --tpc-distortion-type ' + str(tpcDistortionType) \ + + ' --n-threads-distortions 1 ' \ + putConfigValues(["TPCGasParam","TPCGEMParam","TPCEleParam","TPCITCorr","TPCDetParam"], localCF=tpcLocalCF) TPCDigitask['cmd'] += (' --tpc-chunked-writer','')[args.no_tpc_digitchunking] From c359dc30b6f8dce2c52afdddfae26497189c9dfa Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Sat, 6 Dec 2025 15:20:38 +0100 Subject: [PATCH 170/362] O2DPG MC: Support for missing MID Fixes https://its.cern.ch/jira/browse/O2-6530 --- MC/bin/o2dpg_sim_workflow.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 7c3dc19e3..fcef0b7ac 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1514,7 +1514,8 @@ def getDigiTaskName(det): MIDRECOtask['cmd'] += task_finalizer(['${O2_ROOT}/bin/o2-mid-reco-workflow', getDPL_global_options(), putConfigValues(),('',' --disable-mc')[args.no_mc_labels]]) - workflow['stages'].append(MIDRECOtask) + if isActive('MID'): + workflow['stages'].append(MIDRECOtask) #<--------- FDD reco workflow FDDRECOtask = createTask(name='fddreco_'+str(tf), needs=[getDigiTaskName("FDD")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') @@ -1602,15 +1603,19 @@ def getDigiTaskName(det): getDPL_global_options(ccdbbackend=False), putConfigValues(), ('',' --disable-mc')[args.no_mc_labels]]) - workflow['stages'].append(MCHMIDMATCHtask) + if isActive("MID") and isActive("MCH"): + workflow['stages'].append(MCHMIDMATCHtask) #<--------- MFT-MCH forward matching - MFTMCHMATCHtask = createTask(name='mftmchMatch_'+str(tf), needs=[MCHMIDMATCHtask['name'], MFTRECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') + forwardmatchneeds = [MCHRECOtask['name'], + MFTRECOtask['name'], + MCHMIDMATCHtask['name'] if isActive("MID") else None] + MFTMCHMATCHtask = createTask(name='mftmchMatch_'+str(tf), needs=forwardmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') MFTMCHMATCHtask['cmd'] = task_finalizer( ['${O2_ROOT}/bin/o2-globalfwd-matcher-workflow', putConfigValues(['ITSAlpideConfig', 'MFTAlpideConfig', - 'FwdMatching'],{"FwdMatching.useMIDMatch":"true"}), + 'FwdMatching'],{"FwdMatching.useMIDMatch": "true" if isActive("MID") else "false"}), ('',' --disable-mc')[args.no_mc_labels]]) if args.fwdmatching_assessment_full == True: From 35954dd516c10c204ceef6cb1fc7a451e4ad4a91 Mon Sep 17 00:00:00 2001 From: cpuggion84 <90757182+cpuggion84@users.noreply.github.com> Date: Sun, 16 Nov 2025 15:04:02 +0100 Subject: [PATCH 171/362] Update zdcPbPb.json Add paramiter CENTRAL_EVENT_CONFIG with values 2.5 and 1 This parameter is used to fill the histograms relating to the centroid conditioned by the cut on the zems. This configuration was already present in the zdc.json configuration file used for oxygen and neon. Now, it has also been added for PbPb. --- DATA/production/qc-async/zdcPbPb.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DATA/production/qc-async/zdcPbPb.json b/DATA/production/qc-async/zdcPbPb.json index 0b1f7d091..0407e0d90 100644 --- a/DATA/production/qc-async/zdcPbPb.json +++ b/DATA/production/qc-async/zdcPbPb.json @@ -57,7 +57,8 @@ "CENTR_ZNA": "200;-2;2;200;-2;2", "CENTR_ZNC": "200;-2;2;200;-2;2", "CENTR_ZPA": "2240;0;22.4", - "CENTR_ZPC": "2240;-22.4;0" + "CENTR_ZPC": "2240;-22.4;0", + "CENTRAL_EVENT_CONFIG": "2.5;1" } } } From 22da9869ada2bd81a226cc072515a0d3eb900007 Mon Sep 17 00:00:00 2001 From: Francesca Ercolessi Date: Mon, 8 Dec 2025 22:12:43 +0100 Subject: [PATCH 172/362] Add LF generator for MC with coalescence production for De Tr He3 (#2207) * add generators for nuclei MC with coalescence De Tr He3 * Add LF generator for MC with coalescence production for De Tr He3 * rm old cfg --- .../ini/GeneratorLF_Coalescence_pp536TeV.ini | 7 +++++ .../tests/GeneratorLF_Coalescence_pp536TeV.C | 28 +++++++++++++++++++ .../generator/pythia8_inel_pp536tev.cfg | 18 ++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Coalescence_pp536TeV.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Coalescence_pp536TeV.C create mode 100644 MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Coalescence_pp536TeV.ini b/MC/config/PWGLF/ini/GeneratorLF_Coalescence_pp536TeV.ini new file mode 100644 index 000000000..2e8f1e3c5 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Coalescence_pp536TeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C +funcName = generateCoalescence({1000010020, 1000010030, 1000020030}, 1, 0.239) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg + diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Coalescence_pp536TeV.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Coalescence_pp536TeV.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Coalescence_pp536TeV.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg new file mode 100644 index 000000000..6c22eb379 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg @@ -0,0 +1,18 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 5360. # GeV + +### processes +SoftQCD:inelastic = on # all inelastic processes + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 0.000000 +PhaseSpace:pTHatMax = -1.000000 + +Random:setSeed = on +Random:seed = 0 \ No newline at end of file From fd508bfaf44278b9544506df657f926b77d3a4c0 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Wed, 10 Dec 2025 09:04:17 +0100 Subject: [PATCH 173/362] Fix HF tests (#2208) * Fix HF tests * Fix another test file * Revert wrong change * Few more fixes * Even more fixes * Fix typo and slightly lower threshold --- ...rHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C | 4 +- ...neratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C | 70 ++++++++++++++++--- ..._ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C | 22 ++++-- ...and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C | 1 - ...F_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C | 66 +++++++++-------- ...ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C | 4 +- 6 files changed, 121 insertions(+), 46 deletions(-) diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C index 0177751d0..e46d1544d 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C @@ -68,7 +68,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -129,7 +129,7 @@ int External() { return 1; } - if (averagePt < 8.) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) + if (averagePt < 7.) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) std::cerr << "Average pT of charmed hadrons " << averagePt << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C index d29245b32..5735c969d 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C @@ -7,13 +7,65 @@ int External() { std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ - {421, {{-321, 211}, {-321, 111, 211}}}, // D0 - {431, {{211, 333}, {-313, 321}}}, // Ds+ - {4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+ - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+ - {4332, {{211, 3334}}} // Omegac+ + {411, { + {-321, 211, 211}, // K- π+ π+ (non-resonant) + {-321, 111, 211, 211}, // K- π+ π+ π0 (non-resonant) + {-313, 321}, // K*0(892) K+ + {-10311, 321}, // K*0(1430) K+ + {211, 333}, // φ π+ + {-321, 211, 321}, // K- K+ π+ (non-resonant) + {113, 211}, // ρ0 π+ + {211, 225}, // f2(1270) π+ + {-211, 211, 211} // π- π+ π+ (non-resonant) + }}, + {421, { + {-321, 211}, // K- π+ (non-resonant) + {-321, 111, 211}, // K- π+ π0 + {-321, 213}, // ρ+ K- + {-313, 111}, // antiK*0(892) π0 + {-323, 211}, // K*-(892) π+ + {-211, 211}, // π- π+ + {-211, 213}, // ρ+ π- + {-211, 111, 211}, // π- π+ π0 + {-321, 321} // K- K+ + }}, + {431, { + {211, 333}, // φ π+ + {-313, 321}, // antiK*(892) K+ + {213, 333}, // φ ρ + {113, 211}, // ρ π+ + {211, 225}, // f2(1270) π+ + {-211, 211, 211}, // π- π+ π+ (s-wave) + {211, 313}, // K*(892)0 π+ + {321, 10221}, // f0(1370) K+ + {113, 321}, // ρ0 K+ + {-211, 211, 321}, // π- K+ π+ (non-resonant) + {211, 221} // η π+ + }}, + {4122, { + {-321, 211, 2212}, // p K- π+ (non-resonant) + {-313, 2212}, // p K*0(892) + {-321, 2224}, // Δ++ K- + {211, 102134}, // Λ(1520) π+ + {-321, 111, 211, 2212}, // p K- π+ π0 + {-211, 211, 2212}, // p π- π+ + {333, 2212} // p φ + }}, + {4232, { + {-321, 211, 2212}, // Xic+ -> p, K-, pi+ + {-313, 2212}, // Xic+ -> p, Kbar^*(892)0 + {211, 211, 3312}, // Xic+ -> Xi-, pi+, pi+ + {333, 2212}, // Xic+ -> p, phi(1020)0 + {-211, 211, 3222}, // Xic+ -> Sigma+, pi-, pi+ + {211, 3324} // Xic+ -> Xi(1530)0, pi+ + }}, + {4132, { + {211, 3312}, // Xic0 -> Xi-, pi+ + }}, + {4332, { + {211, 3334}, // Omegac0 -> Omega-, pi+ + {211, 3312} // Omegac0 -> Xi-, pi+ + }} }; TFile file(path.c_str(), "READ"); @@ -66,7 +118,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -119,7 +171,7 @@ int External() { } float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + if (fracForcedDecays < 0.85) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C index 46befa6ad..e8a678315 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C @@ -5,11 +5,25 @@ int External() { int checkPdgQuarkTwo{5}; float ratioTrigger = 1./5; // one event triggered out of 5 - std::vector checkPdgHadron{4132, 4332, 4232}; + std::vector checkPdgHadron{4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {4132, {{211, 3312}}}, // Xic0 - {4332, {{211, 3334}, {211, 3312}}}, // Omegac0 - {4232, {{313, 2212}, {211, 321, 2212}, {211, 3324}, {211, 211, 3312}}} //Xic+ + {4232, { + {-321, 211, 2212}, // Xic+ -> p, K-, pi+ + {-313, 2212}, // Xic+ -> p, Kbar^*(892)0 + {211, 211, 3312}, // Xic+ -> Xi-, pi+, pi+ + {333, 2212}, // Xic+ -> p, phi(1020)0 + {-211, 211, 3222}, // Xic+ -> Sigma+, pi-, pi+ + {211, 3324}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {211, 3312}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {211, 3334}, // Omegac0 -> Omega-, pi+ + {211, 3312}, // Omegac0 -> Xi-, pi+ + }}, }; TFile file(path.c_str(), "READ"); diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C index 6f13ae05e..9e8456fad 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C @@ -57,7 +57,6 @@ int External() { {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ {2212, 333}, // Lambdac+ -> p, phi(1020)0 }}, - {4232, { {2212, -321, 211}, // Xic+ -> p, K-, pi+ {2212, -313}, // Xic+ -> p, Kbar^*(892)0 diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C index 688939eae..c7f5eaf16 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C @@ -5,57 +5,67 @@ int External() { int checkPdgQuarkTwo{5}; float ratioTrigger = 1./5; // one event triggered out of 5 - std::vector checkPdgHadron{411, 421, 431, 4122, 4232}; + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters {411, { {-321, 211, 211}, // K- π+ π+ (non-resonant) + {-321, 111, 211, 211}, // K- π+ π+ π0 (non-resonant) {-313, 321}, // K*0(892) K+ {-10311, 321}, // K*0(1430) K+ {211, 333}, // φ π+ - {-321, 321, 211}, // K- K+ π+ (non-resonant) + {-321, 211, 321}, // K- K+ π+ (non-resonant) {113, 211}, // ρ0 π+ - {225, 211}, // f2(1270) π+ - {-211, 211, 211} // π- π+ π+ (non-resonant) + {211, 225}, // f2(1270) π+ + {-211, 211, 211} // π- π+ π+ (non-resonant) }}, {421, { {-321, 211}, // K- π+ (non-resonant) {-321, 111, 211}, // K- π+ π0 - {213, -321}, // ρ+ K- + {-321, 213}, // ρ+ K- {-313, 111}, // antiK*0(892) π0 {-323, 211}, // K*-(892) π+ {-211, 211}, // π- π+ - {213, -211}, // ρ+ π- - {-211, 211, 111}, // π- π+ π0 - {-321, 321} // K- K+ + {-211, 213}, // ρ+ π- + {-211, 111, 211}, // π- π+ π0 + {-321, 321} // K- K+ }}, {431, { {211, 333}, // φ π+ {-313, 321}, // antiK*(892) K+ - {333, 213}, // φ ρ + {213, 333}, // φ ρ {113, 211}, // ρ π+ - {225, 211}, // f2(1270) π+ + {211, 225}, // f2(1270) π+ {-211, 211, 211}, // π- π+ π+ (s-wave) - {313, 211}, // K*(892)0 π+ - {10221, 321}, // f0(1370) K+ + {211, 313}, // K*(892)0 π+ + {321, 10221}, // f0(1370) K+ {113, 321}, // ρ0 K+ - {-211, 321, 211}, // π- K+ π+ (non-resonant) - {221, 211} // η π+ + {-211, 211, 321}, // π- K+ π+ (non-resonant) + {211, 221} // η π+ }}, {4122, { - {2212, -321, 211}, // p K- π+ (non-resonant) - {2212, -313}, // p K*0(892) - {2224, -321}, // Δ++ K- - {102134, 211}, // Λ(1520) K- - {2212, -321, 211, 111}, // p K- π+ π0 - {2212, -211, 211}, // p π- π+ - {2212, 333} // p φ - }}, - {4232, { - {-313, 2212}, // antiK*0(892) p - {2212, -321, 211}, // p K- π+ - {2212, 333}, // p φ - {3222, -211, 211} // Σ+ π- π+ + {-321, 211, 2212}, // p K- π+ (non-resonant) + {-313, 2212}, // p K*0(892) + {-321, 2224}, // Δ++ K- + {211, 102134}, // Λ(1520) π+ + {-321, 111, 211, 2212}, // p K- π+ π0 + {-211, 211, 2212}, // p π- π+ + {333, 2212} // p φ }}, + {4232, { + {-321, 211, 2212}, // Xic+ -> p, K-, pi+ + {-313, 2212}, // Xic+ -> p, Kbar^*(892)0 + {211, 211, 3312}, // Xic+ -> Xi-, pi+, pi+ + {333, 2212}, // Xic+ -> p, phi(1020)0 + {-211, 211, 3222}, // Xic+ -> Sigma+, pi-, pi+ + {211, 3324} // Xic+ -> Xi(1530)0, pi+ + }}, + {4132, { + {211, 3312}, // Xic0 -> Xi-, pi+ + }}, + {4332, { + {211, 3334}, // Omegac0 -> Omega-, pi+ + {211, 3312} // Omegac0 -> Xi-, pi+ + }} }; TFile file(path.c_str(), "READ"); @@ -108,7 +118,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C index a300882c0..460b121db 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C @@ -5,7 +5,7 @@ #include int External() { - std::string path{"/home/mattia/Documenti/cernbox/Documents/PostDoc/D2H/MC/corrBkgSigmaC/tf1/genevents_Kine.root"}; + std::string path{"o2sim_Kine.root"}; int checkPdgQuarkOne{4}; int checkPdgQuarkTwo{5}; @@ -177,7 +177,7 @@ int External() { } float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + if (fracForcedDecays < 0.5) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } From 55ce5b1a16b76aa7fc8bddb9fae602b28996d23a Mon Sep 17 00:00:00 2001 From: sawan <124118453+sawankumawat@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:49:37 +0530 Subject: [PATCH 174/362] MC production for glueball study (#2211) --- .../ini/GeneratorLF_Resonances_pp_exotic.ini | 2 +- .../PWGLF/pythia8/generator/gluelistgun.json | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 MC/config/PWGLF/pythia8/generator/gluelistgun.json diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini index 7ec78bb39..33ac0e832 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 4) # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/pythia8/generator/gluelistgun.json b/MC/config/PWGLF/pythia8/generator/gluelistgun.json new file mode 100644 index 000000000..c261c5608 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/gluelistgun.json @@ -0,0 +1,46 @@ +{ + "f_2(1270)": { + "pdg": 225, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, + "f_0(1710)": { + "pdg": 10331, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, + "f_2(1525)": { + "pdg": 335, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, + "a_2(1230)": { + "pdg": 115, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + } +} \ No newline at end of file From e5707720ea6c0ce85bc84c0c341830cbd65b2ddd Mon Sep 17 00:00:00 2001 From: Mattia Faggin Date: Wed, 10 Dec 2025 17:18:09 +0100 Subject: [PATCH 175/362] Fix test macro for Sc bkg, checking for D*+. (#2209) * Fix test macro for Sc bkg, checking for D*+. * Fix path. --------- Co-authored-by: mattia --- ...ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C index 460b121db..31aba24ad 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C @@ -15,12 +15,13 @@ int External() { std::array freqRepl = {0.5, 0.5}; std::map sumOrigReplacedParticles = {{413, 0}}; - std::array checkPdgHadron{14122, 4124}; + std::array checkPdgHadron{413, 14122, 4124}; std::map>> checkHadronDecays{ // sorted (!) pdg of daughters //{14122, {{4222, -211}, {4112, 211}, {4122, 211, -211}}}, // Lc(2595)+ //{4124, {{4222, -211}, {4112, 211}, {4122, 211, -211}}} // Lc(2625)+ {14122, {{-211, 4222}, {211, 4112}, {-211, 211, 4122}}}, // Lc(2595)+ - {4124, {{-211, 4222}, {211, 4112}, {-211, 211, 4122}}} // Lc(2625)+ + {4124, {{-211, 4222}, {211, 4112}, {-211, 211, 4122}}}, // Lc(2625)+ + {413, {{22, 411}, {111, 411}, {211, 421}}} // D*+ as in PYTHIA }; TFile file(path.c_str(), "READ"); @@ -64,7 +65,7 @@ int External() { auto absPdg = std::abs(pdg); if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) { // found signal nSignals++; // count signal PDG - std::cout << "==> signal " << absPdg << " found!" << std::endl; + std::cout << std::endl << "==> signal " << absPdg << " found!" << std::endl; if (subGeneratorId == checkPdgQuarkOne) { // replacement only for prompt ---> BUT ALSO NON-PROMPT D* SEEM TO BE REPLACED for (int iRepl{0}; iRepl<2; ++iRepl) { @@ -76,8 +77,9 @@ int External() { sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; } } - } else if (subGeneratorId == checkPdgQuarkTwo) { - std::cout << " NB: we have a " << absPdg << " also in event with quark " << checkPdgQuarkTwo << std::endl; + } + else if (subGeneratorId == checkPdgQuarkTwo && (absPdg == pdgReplParticles[0][1] || absPdg == pdgReplParticles[1][1])) { + std::cout << " NB: we have a " << absPdg << " also in event with quark " << checkPdgQuarkTwo << ", i.e in an event with c-cbar pair present, tagged with a b-bbar (e.g. double-parton scattering)" << std::endl; std::cout << " ### mother indices: "; int idFirstMother = track.getMotherTrackId(); int idSecondMother = track.getSecondMotherTrackId(); @@ -86,13 +88,29 @@ int External() { std::cout << i << " "; motherIds.push_back(i); } + std::cout << std::endl; + + /// To establish if the partonic event is switched on or not, check if the motherIds are all -1 for the current hadron + /// This is ok for Lc excited states deriving from the replacement of a prompt D*+ + /// Instead, Lc excited states coming from Lb decays (i.e. not coming from a D*+ replacement))have at least one mother that has idx !=-1 (*) bool partonicEventOn = false; - if(motherIds != std::vector{-1, -1}) { + bool motherIdsAllMinus1 = true; + for(int idx : motherIds) { + if(idx != -1) { + /// one mother id different from + motherIdsAllMinus1 = false; + break; + } + } + //if(motherIds != std::vector{-1, -1}) { + if(!motherIdsAllMinus1) { std::cout << "The " << absPdg << " particle has mothers. This should mean that it comes directly from parton hadronization, and that the partonic event was kept in the MC production " << std::endl; partonicEventOn = true; } + std::cout << " ### mother PDG codes: "; std::vector motherPdgCodes = {}; + bool updateCounters = true; if(partonicEventOn) { for(int i=idFirstMother; i<=idSecondMother; i++) { motherPdgCodes.push_back(tracks->at(i).GetPdgCode()); @@ -103,16 +121,21 @@ int External() { /// This means that the charm hadron comes from the c-quark hadronization, where the c/cbar quark /// comes from a c-cbar pair present in the current event, tagged with a b-bbar (e.g. double-parton scattering) if(std::find(motherPdgCodes.begin(), motherPdgCodes.end(), 4) == motherPdgCodes.end() && std::find(motherPdgCodes.begin(), motherPdgCodes.end(), -4) == motherPdgCodes.end()) { - /// if the partinc event is not really saved and we arrive here, it means that motherIds != {-1, -1} because - /// the hadron comes from the decay of a beauty hadron. This can happen if and only if this is not a replaced one (i.e. native from Lambdab0 decay) + /// if we arrive here, it means that the hadron comes from the decay of a beauty hadron. + /// This can happen if and only if this is not a replaced one (i.e. native from Lambdab0 decay) if (std::find(motherPdgCodes.begin(), motherPdgCodes.end(), 5122) == motherPdgCodes.end() && std::find(motherPdgCodes.begin(), motherPdgCodes.end(), -5122) == motherPdgCodes.end()) { std::cerr << "The particle " << absPdg << " does not originate neither from a c/c-bar quark (replaced) nor from a Lambda_b0 decay. There is something wrong, aborting..." << std::endl; return 1; } + /// since this is a native Lc excited state from Lb0 decay, we must not update the replacement counters + updateCounters = false; } } std::cout << std::endl; + /// update the counters only if the Lc excited state comes from a replaced prompt D*+, i.e. not from a Lb0 decay + if (!updateCounters) continue; + /// only if we arrive here it means that everything is ok, and we can safely update the counters for the final statistics for (int iRepl{0}; iRepl<2; ++iRepl) { if (absPdg == pdgReplParticles[iRepl][0]) { @@ -133,7 +156,7 @@ int External() { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); std::cout << " -- daughter " << j << ": " << pdgDau << std::endl; - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111) { // phi and pi0 are antiparticles of themselves pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -163,15 +186,15 @@ int External() { std::cout <<"# signal hadrons: " << nSignals << "\n"; std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; - if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.90 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.10) { // we put some tolerance since the number of generated events is small std::cerr << "Number of generated MB events different than expected\n"; return 1; } - if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.90 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.10) { std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; return 1; } - if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.90 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.10) { std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; return 1; } @@ -184,7 +207,7 @@ int External() { for (int iRepl{0}; iRepl<2; ++iRepl) { - std::cout << " --- pdgReplPartCounters[" << iRepl << "][1] = " << pdgReplPartCounters[iRepl][1] << ", freqRepl[" << iRepl <<"] = " << freqRepl[iRepl] << ", sumOrigReplacedParticles[pdgReplParticles[" << iRepl << "][0]] =" << sumOrigReplacedParticles[pdgReplParticles[iRepl][0]] << std::endl; + std::cout << " --- pdgReplPartCounters[" << iRepl << "][1] = " << pdgReplPartCounters[iRepl][1] << ", freqRepl[" << iRepl <<"] = " << freqRepl[iRepl] << ", sumOrigReplacedParticles[pdgReplParticles[" << iRepl << "][0]] = " << sumOrigReplacedParticles[pdgReplParticles[iRepl][0]] << std::endl; if (std::abs(pdgReplPartCounters[iRepl][1] - freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]) > 2 * std::sqrt(freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]])) { // 2 sigma compatibility float fracMeas = 0.; From 8b60d31da275846b9d017a3efa96e2f689687257 Mon Sep 17 00:00:00 2001 From: Mattia Faggin Date: Wed, 10 Dec 2025 17:18:45 +0100 Subject: [PATCH 176/362] Fix test macro for Ds-reso MC, checking also 425 pdg code. (#2210) * Fix test macro for Ds-reso MC, checking also 425 pdg code. * Fix array size. --------- Co-authored-by: mattia --- .../GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C index 008ef62f8..b33434bb0 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C @@ -9,7 +9,7 @@ int External() { std::array freqRepl = {0.1, 0.1, 0.1, 0.1, 0.5, 0.5}; std::map sumOrigReplacedParticles = {{10433, 0}, {435, 0}, {425, 0}}; - std::array checkPdgHadron{411, 421, 10433, 30433, 435, 437, 4325, 4326, 4315, 4316, 531}; + std::array checkPdgHadron{411, 421, 10433, 30433, 435, 437, 4325, 4326, 4315, 4316, 531, 425}; std::map>> checkHadronDecays{ // sorted pdg of daughters {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ {421, {{-321, 211}, {-321, 211, 111}}}, // D0 @@ -21,7 +21,8 @@ int External() { {4326, {{411, 3122}}}, // Xic(3080)+ {4315, {{421, 3122}}}, // Xic(3055)+ {4316, {{421, 3122}}}, // Xic(3080)+ - {531, {{-435, -11, 12}, {-10433, -11, 12}, {-435, -13, 14}, {-10433, -13, 14}, {-435, -15, 16}, {-10433, -15, 16}, {-435, 211}}}// Bs0 + {531, {{-435, -11, 12}, {-10433, -11, 12}, {-435, -13, 14}, {-10433, -13, 14}, {-435, -15, 16}, {-10433, -15, 16}, {-435, 211}}}, // Bs0 + {425, {{413, -211}, {423, 111}, {411, -211}, {421, 111}, {413, -211, 111}, {423, 211, -211}}} }; TFile file(path.c_str(), "READ"); @@ -81,7 +82,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111) { // phi and pi0 are antiparticles of themselves pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); From 2af1cc1c9e486515e752a4af7acdcae07e15d8de Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 11 Dec 2025 13:01:52 +0100 Subject: [PATCH 177/362] No B-scaling of ITS tracklets for PbPb+ optional TPCMEMORYSCALING --- DATA/production/configurations/asyncReco/setenv_extra.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index beeab8eee..f66cbe24b 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -394,6 +394,10 @@ elif [[ $ALIGNLEVEL == 1 ]]; then CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_proc.tpcUseOldCPUDecoding=1;GPU_proc.tpcApplyClusterFilterOnCPU=$ALIEN_JDL_TPCCLUSTERFILTER;" fi + if [[ -n "$ALIEN_JDL_TPCMEMORYSCALING" ]]; then + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_proc.memoryScalingFactor=$ALIEN_JDL_TPCMEMORYSCALING;" + fi + if [[ -n "$ALIEN_JDL_TPCCHICUTOPT" ]]; then # 0 or 1 to disable or enable (default) the chi2 cut both on one-side and smoothed Kalman chi2 CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.mergerInterpolateRejectAlsoOnCurrentPosition=$ALIEN_JDL_TPCCHICUTOPT;" fi @@ -544,7 +548,7 @@ export ITSEXTRAERR="ITSCATrackerParam.sysErrY2[0]=$ERRIB;ITSCATrackerParam.sysEr # ad-hoc options for ITS reco workflow EXTRA_ITSRECO_CONFIG= if [[ $BEAMTYPE == "PbPb" ]]; then - EXTRA_ITSRECO_CONFIG="ITSCATrackerParam.deltaRof=0;ITSVertexerParam.clusterContributorsCut=16;ITSVertexerParam.lowMultBeamDistCut=0;ITSCATrackerParam.nROFsPerIterations=12;ITSCATrackerParam.perPrimaryVertexProcessing=false;ITSCATrackerParam.fataliseUponFailure=false;ITSCATrackerParam.dropTFUponFailure=true" + EXTRA_ITSRECO_CONFIG="ITSCATrackerParam.deltaRof=0;ITSVertexerParam.clusterContributorsCut=16;ITSVertexerParam.lowMultBeamDistCut=0;ITSCATrackerParam.nROFsPerIterations=12;ITSCATrackerParam.perPrimaryVertexProcessing=false;ITSCATrackerParam.fataliseUponFailure=false;ITSCATrackerParam.dropTFUponFailure=true;ITSCATrackerParam.maxMemory=21474836480;" if [[ -z "$ALIEN_JDL_DISABLE_UPC" || $ALIEN_JDL_DISABLE_UPC != 1 ]]; then EXTRA_ITSRECO_CONFIG+=";ITSVertexerParam.nIterations=2;ITSCATrackerParam.doUPCIteration=true;" fi From a435c8400d6be1f55835f616a352ad6e678f02b9 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 12 Dec 2025 17:13:38 +0100 Subject: [PATCH 178/362] Use uniformly DOTPCRESIDUALEXTRACTION env.var --- MC/run/ANCHOR/anchorMC.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 9bc591704..732cc7505 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -378,7 +378,7 @@ else targetString="${targetString} 'tpctimes.*'" fi # -) TPC residual calibration - if [ "${ALIEN_JDL_DOTPCRESIDUALSEXTRACTION}" ]; then + if [ "${ALIEN_JDL_DOTPCRESIDUALEXTRACTION}" ]; then targetString="${targetString} 'tpcresidmerge.*'" fi # -) QC tasks From dd5dca1261d4fc20718b608ee1791c31fd1dadbf Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 27 Nov 2025 13:49:09 +0100 Subject: [PATCH 179/362] Scripts for MC-DATA embedding This commit provides: - anchorMC_DataEmbedding.sh performing an MC to producing an AO2D corresponding to a given DATA AOD as specified by ALIEN_JDL_MC_DATA_EMBEDDING_AO2D - A test showing how this is used - changes or additions to python scripts for the anchoring or extraction of collision structure from given AO2D --- MC/bin/o2dpg_sim_workflow_anchored.py | 32 +- MC/run/ANCHOR/anchorMC_DataEmbedding.sh | 466 ++++++++++++++++++++++ MC/run/ANCHOR/tests/data_embedding/run.sh | 30 ++ MC/utils/o2dpg_data_embedding_utils.py | 333 ++++++++++++++++ 4 files changed, 860 insertions(+), 1 deletion(-) create mode 100755 MC/run/ANCHOR/anchorMC_DataEmbedding.sh create mode 100755 MC/run/ANCHOR/tests/data_embedding/run.sh create mode 100644 MC/utils/o2dpg_data_embedding_utils.py diff --git a/MC/bin/o2dpg_sim_workflow_anchored.py b/MC/bin/o2dpg_sim_workflow_anchored.py index 9a7002bf2..31d8ffb1c 100755 --- a/MC/bin/o2dpg_sim_workflow_anchored.py +++ b/MC/bin/o2dpg_sim_workflow_anchored.py @@ -394,6 +394,29 @@ def determine_timestamp(sor, eor, splitinfo, cycle, ntf, HBF_per_timeframe = 256 assert (timestamp_of_production <= eor) return int(timestamp_of_production), production_offset +def determine_timestamp_from_timeframeID(sor, eor, timeframeID, HBF_per_timeframe = 256): + """ + Determines the timestamp based on the given timeframeID within a run + Args: + sor: int + start-of-run in milliseconds since epoch + eor: int + end-of-run in milliseconds since epoch + timeframeID: int + timeframe id + HBF_per_timeframe: int + number of orbits per timeframe + Returns: + int: timestamp in milliseconds + """ + # length of this run in micro seconds, since we use the orbit duration in micro seconds + + timestamp_of_production = sor + timeframeID * HBF_per_timeframe * LHCOrbitMUS / 1000 + # this is a closure test. If we had perfect floating point precision everywhere, it wouldn't fail. + # But since we don't have that and there are some int casts as well, better check again. + assert (timestamp_of_production >= sor) + assert (timestamp_of_production <= eor) + return int(timestamp_of_production) def exclude_timestamp(ts, orbit, run, filename, global_run_params): """ @@ -481,6 +504,7 @@ def main(): parser.add_argument("--invert-irframe-selection", action='store_true', help="Inverts the logic of --run-time-span-file") parser.add_argument("--orbitsPerTF", type=str, help="Force a certain orbits-per-timeframe number; Automatically taken from CCDB if not given.", default="") parser.add_argument('--publish-mcprodinfo', action='store_true', default=False, help="Publish MCProdInfo metadata to CCDB") + parser.add_argument('--timeframeID', type=int, help="If given, anchor to this specific timeframe id within a run. Takes precendence over determination based on (split-id, prod-split, cycle)", default=-1) parser.add_argument('forward', nargs=argparse.REMAINDER) # forward args passed to actual workflow creation args = parser.parse_args() print (args) @@ -553,7 +577,13 @@ def main(): GLOparams["OrbitsPerTF"] = determined_orbits # determine timestamp, and production offset for the final MC job to run - timestamp, prod_offset = determine_timestamp(run_start, run_end, [args.split_id - 1, args.prod_split], args.cycle, args.tf, GLOparams["OrbitsPerTF"]) + timestamp = 0 + prod_offset = 0 + if args.timeframeID != -1: + timestamp = determine_timestamp_from_timeframeID(run_start, run_end, args.timeframeID, GLOparams["OrbitsPerTF"]) + prod_offset = args.timeframeID + else: + timestamp, prod_offset = determine_timestamp(run_start, run_end, [args.split_id - 1, args.prod_split], args.cycle, args.tf, GLOparams["OrbitsPerTF"]) # determine orbit corresponding to timestamp (mainly used in exclude_timestamp function) orbit = GLOparams["FirstOrbit"] + int((timestamp - GLOparams["SOR"]) / ( LHCOrbitMUS / 1000)) diff --git a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh new file mode 100755 index 000000000..74aecfd7b --- /dev/null +++ b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh @@ -0,0 +1,466 @@ +#!/bin/bash + +# add distortion maps +# https://alice.its.cern.ch/jira/browse/O2-3346?focusedCommentId=300982&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-300982 +# +# export O2DPG_ENABLE_TPC_DISTORTIONS=ON +# SCFile=$PWD/distortions_5kG_lowIR.root # file needs to be downloaded +# export O2DPG_TPC_DIGIT_EXTRA=" --distortionType 2 --readSpaceCharge ${SCFile} " + +# +# procedure setting up and executing an anchored MC +# + +######################## +# helper functionality # +######################## + +echo_info() +{ + echo "INFO [anchorMC]: ${*}" +} + +echo_error() +{ + echo "ERROR [anchorMC]: ${*}" +} + +print_help() +{ + echo "Usage: ./anchorMC.sh" + echo + echo "This needs O2 and O2DPG loaded from alienv." + echo + echo "Make sure the following env variables are set:" + echo "ALIEN_JDL_LPMANCHORPASSNAME or ANCHORPASSNAME," + echo "ALIEN_JDL_MCANCHOR or MCANCHOR," + echo "ALIEN_JDL_LPMPASSNAME or PASSNAME," + echo "ALIEN_JDL_LPMRUNNUMBER or RUNNUMBER," + echo "ALIEN_JDL_LPMPRODUCTIONTYPE or PRODUCTIONTYPE," + echo "ALIEN_JDL_LPMINTERACTIONTYPE or INTERACTIONTYPE," + echo "ALIEN_JDL_LPMPRODUCTIONTAG or PRODUCTIONTAG," + echo "ALIEN_JDL_LPMANCHORRUN or ANCHORRUN," + echo "ALIEN_JDL_LPMANCHORPRODUCTION or ANCHORPRODUCTION," + echo "ALIEN_JDL_LPMANCHORYEAR or ANCHORYEAR," + echo + echo "as well as:" + echo "NTIMEFRAMES," + echo "SPLITID," + echo "PRODSPLIT." + echo + echo "Optional are:" + echo "ALIEN_JDL_CPULIMIT or CPULIMIT, set the CPU limit of the workflow runner, default: 8," + echo "NWORKERS, set the number of workers during detector transport, default: 8," + echo "ALIEN_JDL_SIMENGINE or SIMENGINE, choose the transport engine, default: TGeant4," + echo "ALIEN_JDL_WORKFLOWDETECTORS, set detectors to be taken into account, default: not-used (take the ones from async-reco)" + echo "ALIEN_JDL_ANCHOR_SIM_OPTIONS, additional options that are passed to the workflow creation, default: -gen pythia8," + echo "ALIEN_JDL_ADDTIMESERIESINMC, run TPC time series. Default: 1, switch off by setting to 0," + echo "ALIEN_JDL_MC_ORBITS_PER_TF=N, enforce some orbits per timeframe, instead of determining from CCDB" + echo "ALIEN_JDL_RUN_TIME_SPAN_FILE=FILE, use a run-time-span file to exclude bad data-taking periods" + echo "ALIEN_JDL_INVERT_IRFRAME_SELECTION, invertes the choice of ALIEN_JDL_RUN_TIME_SPAN_FILE" + echo "ALIEN_JDL_CCDB_CONDITION_NOT_AFTER, sets the condition_not_after timestamp for CCDB queries" + echo "DISABLE_QC, set this to disable QC, e.g. to 1" + echo "CYCLE, to set a cycle number different than 0" + echo "NSIGEVENTS, to enforce a specific upper limit of events in a timeframe (not counting orbit-early) events" +} + +# Prevent the script from being soured to omit unexpected surprises when exit is used +SCRIPT_NAME="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" +if [ "${SCRIPT_NAME}" != "$(basename ${BASH_SOURCE[0]})" ] ; then + echo_error "This script cannot not be sourced" >&2 + return 1 +fi + +while [ "$1" != "" ] ; do + case $1 in + --help|-h ) shift + print_help + exit 0 + ;; + * ) echo "Unknown argument ${1}" + exit 1 + ;; + esac +done + +# 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 + +# check if jq is there +which jq >/dev/null 2>&1 +[ "${?}" != "0" ] && { echo_error "jq is not found. Install or load via alienv." ; exit 1 ; } + +alien-token-info >/dev/null 2>&1 +[ "${?}" != "0" ] && { echo_error "No GRID token found, required to run." ; exit 1 ; } + +################################################################# +# Set all required variables to identify an anchored production # +################################################################# + +# Allow for both "ALIEN_JDL_LPM" as well as "KEY" + +# the only four where there is a real default for +export ALIEN_JDL_CPULIMIT=${ALIEN_JDL_CPULIMIT:-${CPULIMIT:-8}} +export ALIEN_JDL_SIMENGINE=${ALIEN_JDL_SIMENGINE:-${SIMENGINE:-TGeant4}} +# can be passed to contain additional options that will be passed to o2dpg_sim_workflow_anchored.py and eventually to o2dpg_sim_workflow.py +export ALIEN_JDL_ANCHOR_SIM_OPTIONS=${ALIEN_JDL_ANCHOR_SIM_OPTIONS:--gen pythia8} +# all others MUST be set by the user/on the outside +export ALIEN_JDL_LPMANCHORPASSNAME=${ALIEN_JDL_LPMANCHORPASSNAME:-${ANCHORPASSNAME}} +# LPMPASSNAME is used in O2 and O2DPG scripts, however on the other hand, ALIEN_JDL_LPMANCHORPASSNAME is the one that is set in JDL templates; so use ALIEN_JDL_LPMANCHORPASSNAME and set ALIEN_JDL_LPMPASSNAME +export ALIEN_JDL_LPMPASSNAME=${ALIEN_JDL_LPMANCHORPASSNAME} +export ALIEN_JDL_LPMRUNNUMBER=${ALIEN_JDL_LPMRUNNUMBER:-${RUNNUMBER}} +export ALIEN_JDL_LPMPRODUCTIONTYPE=${ALIEN_JDL_LPMPRODUCTIONTYPE:-${PRODUCTIONTYPE}} +export ALIEN_JDL_LPMINTERACTIONTYPE=${ALIEN_JDL_LPMINTERACTIONTYPE:-${INTERACTIONTYPE}} +export ALIEN_JDL_LPMPRODUCTIONTAG=${ALIEN_JDL_LPMPRODUCTIONTAG:-${PRODUCTIONTAG}} +export ALIEN_JDL_LPMANCHORRUN=${ALIEN_JDL_LPMANCHORRUN:-${ANCHORRUN}} +export ALIEN_JDL_LPMANCHORPRODUCTION=${ALIEN_JDL_LPMANCHORPRODUCTION:-${ANCHORPRODUCTION}} +export ALIEN_JDL_LPMANCHORYEAR=${ALIEN_JDL_LPMANCHORYEAR:-${ANCHORYEAR}} +# decide whether to run TPC time series; on by default, switched off by setting to 0 +export ALIEN_JDL_ADDTIMESERIESINMC=${ALIEN_JDL_ADDTIMESERIESINMC:-1} + +# check for presence of essential variables that need to be set +[ -z "${ALIEN_JDL_LPMANCHORPASSNAME}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORPASSNAME or ANCHORPASSNAME" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMRUNNUMBER}" ] && { echo_error "Set ALIEN_JDL_LPMRUNNUMBER or RUNNUMBER" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMPRODUCTIONTYPE}" ] && { echo_error "Set ALIEN_JDL_LPMPRODUCTIONTYPE or PRODUCTIONTYPE" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMINTERACTIONTYPE}" ] && { echo_error "Set ALIEN_JDL_LPMINTERACTIONTYPE or INTERACTIONTYPE" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMPRODUCTIONTAG}" ] && { echo_error "Set ALIEN_JDL_LPMPRODUCTIONTAG or PRODUCTIONTAG" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMANCHORRUN}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORRUN or ANCHORRUN" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMANCHORPRODUCTION}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORPRODUCTION or ANCHORPRODUCTION" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMANCHORYEAR}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORYEAR or ANCHORYEAR" ; exit 1 ; } + +[ -z "${NTIMEFRAMES}" ] && { echo_error "Set NTIMEFRAMES" ; exit 1 ; } +[ -z "${SPLITID}" ] && { echo_error "Set SPLITID" ; exit 1 ; } +[ -z "${PRODSPLIT}" ] && { echo_error "Set PRODSPLIT" ; exit 1 ; } + + +# cache the production tag, will be set to a special anchor tag; reset later in fact +ALIEN_JDL_LPMPRODUCTIONTAG_KEEP=$ALIEN_JDL_LPMPRODUCTIONTAG +echo_info "Substituting ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG with ALIEN_JDL_LPMANCHORPRODUCTION=$ALIEN_JDL_LPMANCHORPRODUCTION for simulating reco pass..." +ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMANCHORPRODUCTION + +if [[ $ALIEN_JDL_ANCHOR_SIM_OPTIONS == *"--tpc-distortion-type 2"* ]]; then + export O2DPG_ENABLE_TPC_DISTORTIONS=ON + # set the SCALING SOURCE to CTP for MC unless explicitely given from outside + export ALIEN_JDL_TPCSCALINGSOURCE=${ALIEN_JDL_TPCSCALINGSOURCE:-"CTP"} +fi + + +# The number of signal events can be given, but should be useful only in +# certain expert modes. In the default case, the final event number is determined by the timeframe length. +if [ -z "${NSIGEVENTS}" ]; then + NSIGEVENTS=10000 # this is just some big number; In the simulation the event number is the minimum of this number and what fits into a single timeframe + # based on the interaction rate. The number is a reasonable upper limit related to ~5696 collisions that fit into 32 LHC orbits at 2MHz interaction rate. +fi + +if [ -z "${CYCLE}" ]; then + echo_info "No CYCLE number given ... defaulting to 0" + CYCLE=0 +fi + +# this generates an exact reproducer script for this job +# that can be used locally for debugging etc. +if [[ -n "${ALIEN_PROC_ID}" && -n "${JALIEN_WSPORT}" ]]; then + ${O2DPG_ROOT}/GRID/utils/getReproducerScript.sh ${ALIEN_PROC_ID} +fi + +# also for this keep a real default +NWORKERS=${NWORKERS:-8} +# set a default seed if not given +SEED=${ALIEN_PROC_ID:-${SEED:-1}} + +ONCVMFS=0 + +if [ "${ALIEN_JDL_O2DPG_OVERWRITE}" ]; then + echo "Setting O2DPG_ROOT to overwritten path ${ALIEN_JDL_O2DPG_OVERWRITE}" + export O2DPG_ROOT=${ALIEN_JDL_O2DPG_OVERWRITE} +fi + +export > env_base.env + +if ! declare -F module > /dev/null; then + module() { + eval "$(/usr/bin/modulecmd bash "$@")"; + } + export -f module +fi + +[[ "${BASEDIR}" == /cvmfs/* ]] && ONCVMFS=1 +if [ ! "${MODULEPATH}" ]; then + export MODULEPATH=${BASEDIR}/../Modules/modulefiles + if [ "${ONCVMFS}" == "1" ]; then + PLATFORM=$(echo "${BASEDIR}" | sed -E 's|.*/([^/]+)/Packages|\1|') + export MODULEPATH=${MODULEPATH}:${BASEDIR}/../../etc/toolchain/modulefiles/${PLATFORM} + fi + echo "Determined Modulepath to be ${MODULEPATH}" +fi + +#<----- START OF part that should run under a clean alternative software environment if this was given ------ +if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + if [ "${LOADEDMODULES}" ]; then + printenv > env_before_stashing.printenv + echo "Stashing initial modules" + module save initial_modules.list # we stash the current modules environment + module list --no-pager + module purge --no-pager + printenv > env_after_stashing.printenv + echo "Modules after purge" + module list --no-pager + fi + echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" + /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env + source async_environment.env + export > env_async.env +fi + +# default async_pass.sh script +DPGRECO=$O2DPG_ROOT/DATA/production/configurations/asyncReco/async_pass.sh +# default destenv_extra.sh script +DPGSETENV=$O2DPG_ROOT/DATA/production/configurations/asyncReco/setenv_extra.sh + +# a specific async_pass.sh script is in the current directory, assume that one should be used +if [[ -f async_pass.sh ]]; then + # the default is executable, however, this may not be, so make it so + chmod +x async_pass.sh + DPGRECO=./async_pass.sh +else + cp -v $DPGRECO . +fi + +# if there is no setenv_extra.sh in this directory (so no special version is "shipped" with this rpodcution), copy the default one +if [[ ! -f setenv_extra.sh ]] ; then + cp ${DPGSETENV} . + echo_info "Use default setenv_extra.sh from ${DPGSETENV}." +else + echo_info "setenv_extra.sh was found in the current working directory, use it." +fi + +chmod u+x setenv_extra.sh + +echo_info "Setting up DPGRECO to ${DPGRECO}" + +# take out line running the workflow (if we don't have data input) +[ ${CTF_TEST_FILE} ] || sed -i '/WORKFLOWMODE=run/d' async_pass.sh + +# create workflow ---> creates the file that can be parsed +export IGNORE_EXISTING_SHMFILES=1 +touch list.list + +# run the async_pass.sh and store output to log file for later inspection and extraction of information +./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log +RECO_RC=$? + +echo_info "async_pass.sh finished with ${RECO_RC}" + +if [[ "${RECO_RC}" != "0" ]] ; then + exit ${RECO_RC} +fi + +# check that workflowconfig.log was created correctly +if [[ ! -f workflowconfig.log ]]; then + echo "Workflowconfig.log file not found" + exit 1 +fi + +export ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG_KEEP +echo_info "Setting back ALIEN_JDL_LPMPRODUCTIONTAG to $ALIEN_JDL_LPMPRODUCTIONTAG" + +# get rid of the temporary software environment +if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + module purge --no-pager + # restore the initial software environment + echo "Restoring initial environment" + module --no-pager restore initial_modules.list + module saverm initial_modules.list + + # Restore overwritten O2DPG variables set by modules but changed by user + # (in particular custom O2DPG_ROOT and O2DPG_MC_CONFIG_ROOT) + printenv > env_after_restore.printenv + comm -12 <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ + <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort) | + while read -r var; do + b=$(grep "^$var=" env_before_stashing.printenv | cut -d= -f2-) + a=$(grep "^$var=" env_after_restore.printenv | cut -d= -f2-) + [[ "$b" != "$a" ]] && export "$var=$b" && echo "Reapplied: $var to ${b}" + done +fi +#<----- END OF part that should run under a clean alternative software environment if this was given ------ + +# now create the local MC config file --> config-json.json +# we create the new config output with blacklist functionality +ASYNC_CONFIG_BLACKLIST=${ASYNC_CONFIG_BLACKLIST:-${O2DPG_ROOT}/MC/run/ANCHOR/anchor-dpl-options-blacklist.json} +${O2DPG_ROOT}/MC/bin/o2dpg_dpl_config_tools.py workflowconfig.log ${ASYNC_CONFIG_BLACKLIST} config-json.json +ASYNC_WF_RC=${?} + +# check if config reasonably created +if [[ "${ASYNC_WF_RC}" != "0" || `grep "ConfigParams" config-json.json 2> /dev/null | wc -l` == "0" ]]; then + echo_error "Problem in anchor config creation. Exiting." + exit 1 +fi + +# -- CREATE THE MC JOB DESCRIPTION ANCHORED TO RUN -- + +MODULES="--skipModules ZDC" + +# publish MCPRODINFO for first few jobs of a production +# if external script exported PUBLISH_MCPRODINFO, it will be published anyways +if [ -z "$PUBLISH_MCPRODINFO" ] && [ "$SPLITID" -lt 20 ]; then + PUBLISH_MCPRODINFO_OPTION="--publish-mcprodinfo" + echo "Will publish MCProdInfo" +else + echo "Will not publish MCProdInfo" +fi +PUBLISH_MCPRODINFO_OPTION="" + +# let's take the input data AO2D from a JDL variable +AOD_DATA_FILE=${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D} +if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + NTIMEFRAMES=1 + NWORKERS=1 # these embedding jobs process only light pp type signals ... the parallelism will come via parallel workflows +fi + +# call the python script to extract all collision contexts +python3 ${O2DPG_ROOT}/MC/utils/o2dpg_data_embedding_utils.py --aod-file ${AOD_DATA_FILE} --run-number ${ALIEN_JDL_LPMRUNNUMBER} --limit ${DATA_EMBEDDING_LIMIT:-8} + +parallel_job_count=0 +failed_count=0 +for external_context in collission_context_*.root; do + echo "Embedding into ${external_context}" + # extract timeframe from name + anchoring_tf="${external_context#collission_context_}" # remove prefix 'collision_context_' + anchoring_tf="${anchoring_tf%.root}" # remove suffix '.root' + echo "Treating timeframe ${anchoring_tf}" + + # we do it in a separate workspace + workspace="TF_${anchoring_tf}" + mkdir "${workspace}"; cd "${workspace}" + # fetch the apass reco anchoring config + cp ../*.json . + + # we need to adjust the SEED for each job + JOBSEED=$SEED + [ "$JOBSEED" != "-1" ] && let JOBSEED=JOBSEED+anchoring_tf + echo "TF ${anchoring_tf} got seed ${JOBSEED}" + + # these arguments will be digested by o2dpg_sim_workflow_anchored.py + anchoringArgs="--split-id ${SPLITID} --prod-split ${PRODSPLIT} --cycle ${CYCLE}" + if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + anchoringArgs="--timeframeID ${anchoring_tf}" + fi + baseargs="-tf ${NTIMEFRAMES} ${anchoringArgs} --run-number ${ALIEN_JDL_LPMRUNNUMBER} \ + ${ALIEN_JDL_RUN_TIME_SPAN_FILE:+--run-time-span-file ${ALIEN_JDL_RUN_TIME_SPAN_FILE} ${ALIEN_JDL_INVERT_IRFRAME_SELECTION:+--invert-irframe-selection}} \ + ${ALIEN_JDL_MC_ORBITS_PER_TF:+--orbitsPerTF ${ALIEN_JDL_MC_ORBITS_PER_TF}} ${PUBLISH_MCPRODINFO_OPTION}" + + # these arguments will be passed as well but only eventually be digested by o2dpg_sim_workflow.py which is called from o2dpg_sim_workflow_anchored.py + remainingargs="-seed ${JOBSEED} -ns ${NSIGEVENTS} --include-local-qc --pregenCollContext" + remainingargs="${remainingargs} -e ${ALIEN_JDL_SIMENGINE} -j ${NWORKERS}" + remainingargs="${remainingargs} -productionTag ${ALIEN_JDL_LPMPRODUCTIONTAG:-alibi_anchorTest_tmp}" + # prepend(!) ALIEN_JDL_ANCHOR_SIM_OPTIONS + # since the last passed argument wins, e.g. -productionTag cannot be overwritten by the user + remainingargs="${ALIEN_JDL_ANCHOR_SIM_OPTIONS} ${remainingargs} --anchor-config config-json.json" + # apply software tagging choice + # remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}}" + ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE=${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE:-RECO} + remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${PWD}/env_async.env@${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE}}" + # potentially add CCDB timemachine timestamp + remainingargs="${remainingargs} ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}}" + # add external collision context injection + if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + remainingargs="${remainingargs} --data-anchoring ${PWD}/../${external_context}" + fi + + echo_info "baseargs passed to o2dpg_sim_workflow_anchored.py: ${baseargs}" + echo_info "remainingargs forwarded to o2dpg_sim_workflow.py: ${remainingargs}" + + anchoringLogFile=timestampsampling_${ALIEN_JDL_LPMRUNNUMBER}.log + # query CCDB has changed, w/o "_" + ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow_anchored.py ${baseargs} -- ${remainingargs} &> ${anchoringLogFile} + WF_RC="${?}" + if [ "${WF_RC}" != "0" ] ; then + echo_error "Problem during anchor timestamp sampling and workflow creation. Exiting." + exit ${WF_RC} + fi + + TIMESTAMP=`grep "Determined timestamp to be" ${anchoringLogFile} | awk '//{print $6}'` + echo_info "TIMESTAMP IS ${TIMESTAMP}" + + if [ "${ONLY_WORKFLOW_CREATION}" ]; then + continue # or exit + fi + + # check if this job is exluded because it falls inside a bad data-taking period + ISEXCLUDED=$(grep "TIMESTAMP IS EXCLUDED IN RUN" ${anchoringLogFile}) + if [ "${ISEXCLUDED}" ]; then + # we can quit here; there is nothing to do + # (apart from maybe creating a fake empty AO2D.root file or the like) + echo "Timestamp is excluded from run. Nothing to do here" + continue # or exit 0 + fi + + # -- RUN THE MC WORKLOAD TO PRODUCE TARGETS -- + + export FAIRMQ_IPC_PREFIX=./ + echo_info "Ready to start main workflow" + + # Let us construct the workflow targets + targetString="" + if [ "${ALIEN_JDL_O2DPGWORKFLOWTARGET}" ]; then + # The user gave ${ALIEN_JDL_O2DPGWORKFLOWTARGET}. This is an expert mode not used in production. + # In this case, we will build just that. No QC, no TPC timeseries, ... + targetString=${ALIEN_JDL_O2DPGWORKFLOWTARGET} + else + targetString="'aodmerge.*'" + # Now add more targets depending on options + # -) The TPC timeseries targets + if [[ "${ALIEN_JDL_ADDTIMESERIESINMC}" == "1" ]]; then + targetString="${targetString} 'tpctimes.*'" + fi + # -) TPC residual calibration + if [ "${ALIEN_JDL_DOTPCRESIDUALSEXTRACTION}" ]; then + targetString="${targetString} 'tpcresidmerge.*'" + fi + # -) QC tasks + if [[ -z "${DISABLE_QC}" && "${remainingargs}" == *"--include-local-qc"* ]]; then + targetString="${targetString} '^.*QC.*'" # QC tasks should have QC in the name + fi + fi + echo_info "Workflow will run with target specification ${targetString}" + + ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt ${targetString} -j 1 \ + --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} --dynamic-resources \ + ${ALIEN_O2DPG_FILEGRAPH:+--remove-files-early ${ALIEN_O2DPG_FILEGRAPH}} \ + ${ALIEN_O2DPG_ADDITIONAL_WORKFLOW_RUNNER_ARGS} &> pipeline_log & + + ((parallel_job_count++)) + # If limit reached, wait for one job to finish + if ((parallel_job_count >= 8)); then + if ! wait -n; then + ((failed_count++)) + fi + ((parallel_job_count--)) + fi + + cd .. +done # done outer loop +while ((parallel_job_count > 0)); do + if ! wait -n; then + ((failed_count++)) + fi + ((parallel_job_count--)) +done + +if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + # produce the final merged AO2D + find ./ -maxdepth 2 -mindepth 2 -name "AO2D.root" > aod_inputs.txt + o2-aod-merger --input aod_inputs.txt --output AO2D.root +fi + +# +# full logs tar-ed for output, regardless the error code or validation - to catch also QC logs... +# +if [[ -n "$ALIEN_PROC_ID" ]]; then + find ./ \( -name "*.log*" -o -name "*mergerlog*" -o -name "*serverlog*" -o -name "*workerlog*" -o -name "pythia8.cfg" -o -name "reproducer*.sh" \) | tar -czvf debug_log_archive.tgz -T - + if [[ "$ALIEN_JDL_CREATE_TAR_IN_MC" == "1" ]]; then + find ./ \( -name "*.log*" -o -name "*mergerlog*" -o -name "*serverlog*" -o -name "*workerlog*" -o -name "*.root" \) | tar -czvf debug_full_archive.tgz -T - + fi +fi diff --git a/MC/run/ANCHOR/tests/data_embedding/run.sh b/MC/run/ANCHOR/tests/data_embedding/run.sh new file mode 100755 index 000000000..f11cf822e --- /dev/null +++ b/MC/run/ANCHOR/tests/data_embedding/run.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Simple test for Data anchoring +# + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=544742 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC24a2 +export ALIEN_JDL_LPMANCHORRUN=544742 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC23f +export ALIEN_JDL_LPMANCHORYEAR=2023 + +# need to give a data AOD +export ALIEN_JDL_MC_DATA_EMBEDDING_AO2D="alien:///alice/data/2023/LHC23zzm/544742/apass5/0000/o2_ctf_run00544742_orbit0137377824_tf0002239365_epn262/002/AO2D.root" + +export NTIMEFRAMES=1 +export NWORKERS=1 +export SPLITID=1 +export PRODSPLIT=1 +export ALIEN_JDL_O2DPGWORKFLOWTARGET=aod + +# setup of the signal generator +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen pythia8pp" + +export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC_DataEmbedding.sh diff --git a/MC/utils/o2dpg_data_embedding_utils.py b/MC/utils/o2dpg_data_embedding_utils.py new file mode 100644 index 000000000..dad1769a9 --- /dev/null +++ b/MC/utils/o2dpg_data_embedding_utils.py @@ -0,0 +1,333 @@ +# Set of python modules/util functions for the MC-to-DATA embedding +# Mostly concerning extraction of MC collision context from existing data AO2D.root + +import ROOT +import uproot +import pandas as pd +import re +from ROOT import o2 # for CCDB +import argparse +import sys + +class lhc_constants: + LHCMaxBunches = 3564 # max N bunches + LHCRFFreq = 400.789e6 # LHC RF frequency in Hz + LHCBunchSpacingNS = 10 * 1.e9 / LHCRFFreq # bunch spacing in ns (10 RFbuckets) + LHCOrbitNS = LHCMaxBunches * LHCBunchSpacingNS # orbit duration in ns + LHCRevFreq = 1.e9 / LHCOrbitNS # revolution frequency + LHCBunchSpacingMUS = LHCBunchSpacingNS * 1e-3 # bunch spacing in \mus (10 RFbuckets) + LHCOrbitMUS = LHCOrbitNS * 1e-3 + +def thin_AO2D_file(input_file): + """ + A function to thin an existing AO2D file by just keeping a single DF_ folder + """ + + # Open the input ROOT file + infile = ROOT.TFile.Open(input_file, "READ") + + # Find the first TDirectory starting with "DF_" + df_dir = None + dir_name = "" + for key in infile.GetListOfKeys(): + name = key.GetName() + if name.startswith("DF_"): + # Access the TDirectory + df_dir = infile.Get(name) + dir_name = name + break + + if not df_dir: + raise RuntimeError("No TDirectory starting with 'DF_' found.") + + # Open the output file (create if not exist) + output_file = "AO2D_reduced_" + str(dir_name) + ".root" + outfile = ROOT.TFile.Open(output_file, "RECREATE") + + # Create the same directory structure in the output file + df_dir_copy = outfile.mkdir(dir_name) + + # Move to the newly created directory + df_dir_copy.cd() + + # Loop over the keys (trees) inside the "DF_" directory and copy them + for key in df_dir.GetListOfKeys(): + obj = df_dir.Get(key.GetName()) + if isinstance(obj, ROOT.TTree): # Check if it's a TTree + # Clone the tree and write it to the corresponding directory in the output file + obj.CloneTree(-1).Write(key.GetName(), ROOT.TObject.kOverwrite) # Copy the tree + + # Now handle the metaData;1 key (TMap) in the top-level directory + meta_data = infile.Get("metaData") + if meta_data: + if isinstance(meta_data, ROOT.TMap): + copied_meta_data = meta_data.Clone() + outfile.cd() # Make sure we're at the top-level in the output file + outfile.WriteObject(meta_data, "metaData") + + # Iterate over the map + iter = meta_data.MakeIterator() + entry = iter.Next() + while entry: + key = entry + value = meta_data.GetValue(key) + + # Convert TObjString to Python string + key_str = key.GetName() + value_str = value.GetName() if value else "None" + print(f"{key_str}: {value_str}") + entry = iter.Next() + + # Close the files + outfile.Close() + infile.Close() + + print(f"Copied all trees from TDirectory '{dir_name}' to '{output_file}'.") + + +def retrieve_Aggregated_RunInfos(run_number): + """ + Retrieves the aggregated runinfo object ... augmented with the number of timeframes + """ + runInfo = o2.parameters.AggregatedRunInfo.buildAggregatedRunInfo(o2.ccdb.BasicCCDBManager.instance(), run_number) + detList = o2.detectors.DetID.getNames(runInfo.grpECS.getDetsReadOut()) + assert (run_number == runInfo.runNumber) + assert (run_number == runInfo.grpECS.getRun()) + + run_info = {"SOR" : runInfo.sor, + "EOR" : runInfo.eor, + "FirstOrbit" : runInfo.orbitSOR, + "LastOrbit" : runInfo.orbitEOR, + "OrbitReset" : runInfo.orbitReset, + "OrbitsPerTF" : int(runInfo.orbitsPerTF), + "detList" : detList} + + # update num of timeframes + # figure out how many timeframes fit into this run range + # take the number of orbits per timeframe and multiply by orbit duration to calculate how many timeframes fit into this run + time_length_inmus = 1000 * (run_info["EOR"] - run_info["SOR"]) + ntimeframes = time_length_inmus / (run_info["OrbitsPerTF"] * lhc_constants.LHCOrbitMUS) + run_info["ntimeframes"] = ntimeframes + + return run_info + + +def get_bc_with_timestamps(bc_data, run_info): + """ + bc_data is a pandas df containing the AO2D basic bunch crossing data. + Returns the bc table with additional information on timeframeID etc. + """ + + # add a new column to the bc table dynamically + # this is the time in mu s + bc_data["timestamp"] = run_info["OrbitReset"] + (bc_data["fGlobalBC"] * lhc_constants.LHCBunchSpacingMUS).astype("int64") + bc_data["timeframeID"] = ((bc_data["fGlobalBC"] - (run_info["FirstOrbit"] * lhc_constants.LHCMaxBunches)) / (lhc_constants.LHCMaxBunches * run_info["OrbitsPerTF"])).astype("int64") + bc_data["orbit"] = (bc_data["fGlobalBC"] // lhc_constants.LHCMaxBunches).astype("int64") + bc_data["bc_within_orbit"] = (bc_data["fGlobalBC"] % lhc_constants.LHCMaxBunches).astype("int64") + return bc_data + + +def get_timeframe_structure(filepath, run_info, max_folders=1, include_dataframe = False, folder_filter=None): + """ + run_info: The aggregated run_info object for this run + """ + def find_tree_key(keys, pattern): + for key in keys: + key_clean = key + if re.search(pattern, key_clean, re.IGNORECASE): + return key_clean + return None + + file = uproot.open(filepath) + raw_keys = file.keys() + + folders = { k.split("/")[0] : 1 for k in raw_keys if "O2bc_001" in k } + folders = [ k for k in folders.keys() ] + folders = folders[:max_folders] + + print ("have ", len(raw_keys), f" in file {filepath}") + + merged = {} # data containers per file + for folder in folders: + if folder_filter != None and folder != folder_filter: + continue + #print (f"Looking into {folder}") + + # Find correct table names using regex + bc_key = find_tree_key(raw_keys, f"^{folder}/O2bc_001") + bc_data = file[bc_key].arrays(library="pd") + + # collision data + coll_key = find_tree_key(raw_keys, f"^{folder}/O2coll.*_001") + coll_data = file[coll_key].arrays(library="pd") + + # extend the data + bc_data = get_bc_with_timestamps(bc_data, run_info) + + # do the splice with collision data + bc_data_coll = bc_data.iloc[coll_data["fIndexBCs"]].reset_index(drop=True) + # this is the combined table containing collision data associated to bc and time information + combined = pd.concat([bc_data_coll, coll_data], axis = 1) + + # do the actual timeframe structure calculation; we only take collisions with a trigger decision attached + triggered = combined[combined["fTriggerMask"] != 0] + timeframe_structure = triggered.groupby('timeframeID').apply( + lambda g: list(zip(g['fGlobalBC'], g['fPosX'], g['fPosY'], g['fPosZ'], g['orbit'], g['bc_within_orbit'], g['fCollisionTime'])) + ).reset_index(name='position_vectors') + + folderkey = folder + '@' + filepath + merged[folderkey] = timeframe_structure # data per folder + if include_dataframe: + merged["data"] = combined + + # annotate which timeframes are available here and from which file + return merged + + +def fetch_bccoll_to_localFile(alien_file, local_filename): + """ + A function to remotely talk to a ROOT file ... and fetching only + BC and collision tables for minimal network transfer. Creates a ROOT file locally + of name local_filename. + + Returns True if success, otherwise False + """ + + # make sure we have a TGrid connection + # Connect to AliEn grid + if not ROOT.gGrid: + ROOT.TGrid.Connect("alien://") + + if not ROOT.gGrid: + print (f"Not TGrid object found ... aborting") + return False + + # Open the remote file via AliEn + infile = ROOT.TFile.Open(alien_file, "READ") + if not infile or infile.IsZombie(): + raise RuntimeError(f"Failed to open {alien_file}") + return False + + # Output local file + outfile = ROOT.TFile.Open(local_filename, "RECREATE") + + # List of trees to copy + trees_to_copy = ["O2bc_001", "O2collision_001"] + + # Loop over top-level keys to find DF_ folders + for key in infile.GetListOfKeys(): + obj = key.ReadObj() + if obj.InheritsFrom("TDirectory") and key.GetName().startswith("DF_"): + df_name = key.GetName() + df_dir = infile.Get(df_name) + + # Create corresponding folder in output file + out_df_dir = outfile.mkdir(df_name) + out_df_dir.cd() + + # Copy only specified trees if they exist + for tree_name in trees_to_copy: + if df_dir.GetListOfKeys().FindObject(tree_name): + tree = df_dir.Get(tree_name) + cloned_tree = tree.CloneTree(-1) # copy all entries + cloned_tree.Write(tree_name) + + outfile.cd() # go back to top-level for next DF_ + + # Close files + outfile.Close() + infile.Close() + return True + + +def convert_to_digicontext(aod_timeframe=None, timeframeID=-1): + """ + converts AOD collision information from AO2D to collision context + which can be used for MC + """ + # we create the digitization context object + digicontext=o2.steer.DigitizationContext() + + # we can fill this container + parts = digicontext.getEventParts() + # we can fill this container + records = digicontext.getEventRecords() + # copy over information + maxParts = 1 + + entry = 0 + vertices = ROOT.std.vector("o2::math_utils::Point3D")() + vertices.resize(len(aod_timeframe)) + + colindex = 0 + for colindex, col in enumerate(aod_timeframe): + # we make an event interaction record + pvector = ROOT.std.vector("o2::steer::EventPart")() + pvector.push_back(o2.steer.EventPart(0, colindex)) + parts.push_back(pvector) + + orbit = col[4] + bc_within_orbit = col[5] + interaction_rec = o2.InteractionRecord(bc_within_orbit, orbit) + col_time_relative_to_bc = col[6] # in NS + time_interaction_rec = o2.InteractionTimeRecord(interaction_rec, col_time_relative_to_bc) + records.push_back(time_interaction_rec) + vertices[colindex].SetX(col[1]) + vertices[colindex].SetY(col[2]) + vertices[colindex].SetZ(col[3]) + + digicontext.setInteractionVertices(vertices) + digicontext.setNCollisions(vertices.size()) + digicontext.setMaxNumberParts(maxParts) + + # set the bunch filling ---> NEED to fetch it from CCDB + # digicontext.setBunchFilling(bunchFillings[0]); + + prefixes = ROOT.std.vector("std::string")(); + prefixes.push_back("sgn") + + digicontext.setSimPrefixes(prefixes); + digicontext.printCollisionSummary(); + digicontext.saveToFile(f"collission_context_{timeframeID}.root") + + +def process_data_AO2D(file_name, run_number, upper_limit = -1): + """ + Creates all the collision contexts + """ + timeframe_data = [] + + local_filename = "local.root" + fetch_bccoll_to_localFile(file_name, local_filename) + + # fetch run_info object + run_info = retrieve_Aggregated_RunInfos(run_number) + merged = get_timeframe_structure(local_filename, run_info, max_folders=1000) + print ("Got " + str(len(merged)) + " datasets") + timeframe_data.append(merged) + + counter = 0 + for d in timeframe_data: + for key in d: + result = d[key] + for index, row in result.iterrows(): + if upper_limit >= 0 and counter >= upper_limit: + break + tf = row['timeframeID'] + cols = row['position_vectors'] + convert_to_digicontext(cols, tf) + counter = counter + 1 + + +def main(): + parser = argparse.ArgumentParser(description='Extracts collision contexts from reconstructed AO2D') + + parser.add_argument("--run-number", type=int, help="Run number to anchor to", required=True) + parser.add_argument("--aod-file", type=str, help="Data AO2D file (can be on AliEn)", required=True) + parser.add_argument("--limit", type=int, default=-1, help="Upper limit of timeframes to be extracted") + args = parser.parse_args() + + process_data_AO2D(args.aod_file, args.run_number, args.limit) + +if __name__ == "__main__": + sys.exit(main()) From c81c6484c7a2e85e533e56c93750e6af1e07cf1b Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 12 Dec 2025 18:01:40 +0100 Subject: [PATCH 180/362] scripts to delete CCDB objects from the test instance --- UTILS/delete_CCDBObject.sh | 9 +++++++++ UTILS/delete_CCDBPath_recursively.sh | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100755 UTILS/delete_CCDBObject.sh create mode 100755 UTILS/delete_CCDBPath_recursively.sh diff --git a/UTILS/delete_CCDBObject.sh b/UTILS/delete_CCDBObject.sh new file mode 100755 index 000000000..91ec03f48 --- /dev/null +++ b/UTILS/delete_CCDBObject.sh @@ -0,0 +1,9 @@ +OBJECT=${1} +# object is of the form PATH/VALIDITY/ID +# Users/s/swenzel/MCProdInfo/LHC24d1c_minus50/529663/55ceab78-485e-11f0-8e6c-c0a80209250c + +curl -X DELETE --cert /tmp/tokencert_$(id -u).pem \ + --key /tmp/tokenkey_$(id -u).pem \ + -v -k \ + "http://ccdb-test.cern.ch:8080/${OBJECT}" + diff --git a/UTILS/delete_CCDBPath_recursively.sh b/UTILS/delete_CCDBPath_recursively.sh new file mode 100755 index 000000000..c17add57a --- /dev/null +++ b/UTILS/delete_CCDBPath_recursively.sh @@ -0,0 +1,17 @@ +# Step 1 we browse the complete MCProd (or whatever) subfolder + +P=$1 + +BROWSE_RESULT=$(curl --cert /tmp/tokencert_$(id -u).pem \ + --key /tmp/tokenkey_$(id -u).pem \ + -v -k \ + "http://ccdb-test.cern.ch:8080/browse/${P}/*" | awk -F': ' ' +/^ID:/ {id=$2} +/^Path:/ {path=$2} +/^Validity:/ {split($2, a, " -"); validity=a[1]; print path "/" validity "/" id} +') + +for path in ${BROWSE_RESULT}; do + echo "Will,Would delete ${path}" + ./delete_CCDBObject.sh ${path} +done From 4c4bdca570b3fe7c6290fbdab44fc3997468dad8 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 12 Dec 2025 18:06:28 +0100 Subject: [PATCH 181/362] Script to extract/upload BcTVX from EvtSelQA --- MC/prodinfo/bctvx_evselqa_harvester.py | 312 +++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100755 MC/prodinfo/bctvx_evselqa_harvester.py diff --git a/MC/prodinfo/bctvx_evselqa_harvester.py b/MC/prodinfo/bctvx_evselqa_harvester.py new file mode 100755 index 000000000..387abd293 --- /dev/null +++ b/MC/prodinfo/bctvx_evselqa_harvester.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python3 +""" +PyROOT pipeline to: + - parse file paths like ./LHC25as/cpass0/568664/AnalysisResults.root + - choose highest-priority pass per run + - extract histogram event-selection-qa-task/hBcTVX + - hash histogram to prevent duplicates + - write upload ROOT file + - upload using o2-ccdb-upload (or optionally call o2::CcdbApi from C++) + + +Usage: + python3 upload_pipeline.py --file-list files.txt + OR + python3 upload_pipeline.py ./LHC25as/*/*/*/AnalysisResults.root +""" + +import os +import sys +import json +import argparse +import hashlib +import tempfile +import subprocess +from collections import defaultdict + +# PyROOT import +import ROOT +from ROOT import o2 # for O2 access + +# -------- user config ---------- +# priority: earlier in list -> higher priority +PASS_PRIORITY = ["apass6", "apass5", "apass4", "apass3", "apass2", "apass1", "cpass0"] + +# path inside AnalysisResults.root to histogram +HIST_PATH = "event-selection-qa-task/hBcTVX" + +# Local JSON file storing processed histogram hashes to avoid duplicates +PROCESSED_HASH_DB = "processed_hashes.json" + +def getRunInformation(runnumber): + runInfo = o2.parameters.AggregatedRunInfo.buildAggregatedRunInfo(o2.ccdb.BasicCCDBManager.instance(), runnumber) + return {"SOR" : runInfo.sor, + "EOR" : runInfo.eor} + + +def make_ccdb_upload_command(localfile, passname, runnumber, sor, eor, key="ccdb_object"): + l = [ + "o2-ccdb-upload", + "--host", "http://ccdb-test.cern.ch:8080", # <-- adapt to your CCDB server + "--path", "GLO/CALIB/EVSELQA/HBCTVX", # will be filled per-run + "--file", f"{localfile}", # will be replaced with filename + "-k", f"{key}", + "-m", f"run_number={runnumber};pass={passname}", # no extra quotes here (only needed on shell) + "--starttimestamp", f"{sor}", + "--endtimestamp", f"{eor}", + ] + return l # " ".join(l) + +# ------------------------------- +def load_processed_db(path): + if os.path.exists(path): + with open(path, "r") as f: + return json.load(f) + else: + return {"hashes": []} + + +def save_processed_db(path, db): + with open(path, "w") as f: + json.dump(db, f, indent=2) + + +def parse_path_meta(filepath): + """ + Find a pattern *////AnalysisResults.root anywhere in the path. + Returns {period, pass, run}. + + Example accepted paths: + ./LHC25as/cpass0/568664/AnalysisResults.root + /tmp/foo/2023/LHC23zzh/cpass0/544095/AnalysisResults.root + """ + p = os.path.normpath(filepath) + parts = p.split(os.sep) + + # Find the index of AnalysisResults.root + try: + idx = parts.index("AnalysisResults.root") + except ValueError: + # maybe something like analysisresults.root? Lowercase? + # Try case-insensitive fallback + idx = None + for i, comp in enumerate(parts): + if comp.lower() == "analysisresults.root": + idx = i + break + if idx is None: + raise ValueError(f"File does not contain AnalysisResults.root: {filepath}") + + # Need at least 3 dirs before it: period, pass, run + if idx < 3: + raise ValueError(f"Cannot extract period/pass/run from short path: {filepath}") + + run = parts[idx-1] + passname = parts[idx-2] + period = parts[idx-3] + + # Optional sanity checks + if not run.isdigit(): + raise ValueError(f"Run number is not numeric: '{run}' in path {filepath}") + + return {"period": period, "pass": passname, "run": run} + + +def pass_priority_rank(pass_name): + try: + return PASS_PRIORITY.index(pass_name) + except ValueError: + # unknown pass name -> low priority (append at end) + return len(PASS_PRIORITY) + + +def pick_best_pass_file(files_for_run): + """ + files_for_run: list of dicts with keys {pass, path, period} + returns the dict for the chosen file (highest priority) + """ + # sort by priority (lower index -> higher preference) + files_sorted = sorted(files_for_run, key=lambda x: pass_priority_rank(x["pass"])) + return files_sorted[0] if files_sorted else None + + +def histogram_hash(hist): + """ + Deterministic hash of a TH1* content: + - axis nbins, xmin, xmax + - bin contents + bin errors + Returns hex sha256 string. + """ + h = hist + nbins = h.GetNbinsX() + xmin = h.GetXaxis().GetXmin() + xmax = h.GetXaxis().GetXmax() + # collect values + m = hashlib.sha256() + m.update(f"{nbins}|{xmin}|{xmax}|{h.GetName()}|{h.GetTitle()}".encode("utf-8")) + for b in range(0, nbins + 2): # include under/overflow + c = float(h.GetBinContent(b)) + e = float(h.GetBinError(b)) + m.update(f"{b}:{c:.17g}:{e:.17g};".encode("utf-8")) + return m.hexdigest() + + +def extract_histogram_from_file(root_path, hist_path): + """ + Returns a clone of the TH1 found at hist_path or raises on error. + """ + f = ROOT.TFile.Open(root_path, "READ") + if not f or f.IsZombie(): + raise IOError(f"Cannot open file {root_path}") + obj = f.Get(hist_path) + if not obj: + f.Close() + raise KeyError(f"Histogram {hist_path} not found in {root_path}") + if not isinstance(obj, ROOT.TH1): + f.Close() + raise TypeError(f"Object at {hist_path} is not a TH1 (found {type(obj)}) in {root_path}") + # clone to decouple from file and then close file + clone = obj.Clone(obj.GetName()) + clone.SetDirectory(0) + f.Close() + return clone + + +def write_upload_root(hist, meta, outpath): + """ + Writes histogram and metadata (as a TObjString) into a new ROOT file for uploading. + meta: dict of metadata (period, pass, run, runinfo, hash) + """ + f = ROOT.TFile(outpath, "RECREATE") + f.cd() + # set name to include run for clarity + hist_copy = hist.Clone(hist.GetName()) + hist_copy.SetDirectory(f) + hist_copy.Write() + # write metadata as JSON inside TObjString + json_meta = json.dumps(meta) + sobj = ROOT.TObjString(json_meta) + sobj.Write("metadata") + f.Close() + + +def upload_ccdb_via_cli(upload_file, ccdb_path, passname, runnumber, sor, eor): + """ + Call o2-ccdb-upload CLI with CCDB_UPLOAD_CMD template. + Adjust template above for your environment if needed. + """ + cmd = make_ccdb_upload_command(upload_file, passname, runnumber, sor, eor, key="hBcTVX") + print("Running upload command:", " ".join(cmd)) + res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + if res.returncode != 0: + # raise RuntimeError(f"o2-ccdb-upload failed: {res.returncode}\nstdout:{res.stdout}\nstderr:{res.stderr}") + print (f"o2-ccdb-upload failed: {res.returncode}\nstdout:{res.stdout}\nstderr:{res.stderr}") + return False + + print (f"o2-ccdb-upload succeeded: {res.returncode}\nstdout:{res.stdout}\nstderr:{res.stderr}") + return True + + +def main(argv): + parser = argparse.ArgumentParser(description="Extract histogram from AnalysisResults.root and upload to CCDB") + parser.add_argument("--file-list", help="Text file with one file path per line (or '-')", default=None) + parser.add_argument("paths", nargs="*", help="globs or paths to AnalysisResults.root files") + parser.add_argument("--skip-upload", action="store_true", help="Only create upload ROOT files, do not call o2-ccdb-upload") + parser.add_argument("--out-dir", default="ccdb_uploads", help="Where to put temporary upload ROOT files") + parser.add_argument("--processed-db", default=PROCESSED_HASH_DB, help="JSON file to keep processed-hashes") + parser.add_argument("--ccdb-base-path", default="/calibration/hBcTVX", help="Base path inside CCDB where to upload") + args = parser.parse_args(argv) + + # collect files + file_paths = [] + if args.file_list: + if args.file_list == "-": + lines = sys.stdin.read().splitlines() + else: + with open(args.file_list, "r") as f: + lines = [ln.strip() for ln in f if ln.strip()] + file_paths.extend(lines) + if args.paths: + # expand globs + import glob + for p in args.paths: + file_paths.extend(sorted(glob.glob(p))) + if not file_paths: + print("No files provided. Exiting.") + return 1 + + # build per-run grouping + runs = defaultdict(list) + for p in file_paths: + try: + meta = parse_path_meta(p) + except Exception as e: + print(f"Skipping {p}: cannot parse path: {e}") + continue + runs[meta["run"]].append({"path": p, "pass": meta["pass"], "period": meta["period"]}) + + # load processed DB + db = load_processed_db(args.processed_db) + processed_hashes = set(db.get("hashes", [])) + + os.makedirs(args.out_dir, exist_ok=True) + + for run, filelist in runs.items(): + selected = pick_best_pass_file(filelist) + if not selected: + print(f"No candidate for run {run}, skipping.") + continue + path = selected["path"] + period = selected["period"] + pass_name = selected["pass"] + print(f"Selected for run {run}: {path} (period={period}, pass={pass_name})") + + try: + hist = extract_histogram_from_file(path, HIST_PATH) + except Exception as e: + print(f"Failed to extract histogram from {path}: {e}") + continue + + # compute hash + hsh = histogram_hash(hist) + if hsh in processed_hashes: + print(f"Histogram hash {hsh} for run {run} already processed -> skipping upload.") + continue + + # get run information + runinfo = getRunInformation(int(run)) + + # prepare metadata + meta = { + "period": period, + "pass": pass_name, + "run": run, + "runinfo": runinfo, + "hist_name": hist.GetName(), + "hist_title": hist.GetTitle(), + "hash": hsh + } + + # write temporary upload file + out_fname = os.path.join(args.out_dir, f"upload_{period}_{pass_name}_{run}.root") + write_upload_root(hist, meta, out_fname) + print(f"Wrote upload file: {out_fname}") + + # perform upload + if not args.skip_upload: + # build ccdb path (customize to your conventions) + ccdb_path = os.path.join(args.ccdb_base_path, period, pass_name, run) + upload_ccdb_via_cli(out_fname, ccdb_path, pass_name, run, runinfo["SOR"], runinfo["EOR"]) + + # mark as processed (only after successful upload or skip-upload) + processed_hashes.add(hsh) + db["hashes"] = list(processed_hashes) + save_processed_db(args.processed_db, db) + print(f"Marked hash {hsh} as processed.") + + print("Done.") + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) From 8ca8e84357dde982394261aa90ceac88f9688db4 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 12 Dec 2025 18:02:30 +0100 Subject: [PATCH 182/362] Make precollcontext task outside-configurable streamline with other tasks in terms of configurability. Allows to customize the task via --overwrite-config custom.json mechanism. Can be used to ask for non-uniform mu(bc) distribution which is not yet default. --- MC/bin/o2dpg_sim_workflow.py | 38 +++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index fcef0b7ac..b6686e425 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -630,20 +630,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): if doembedding: interactionspecification = 'bkg,' + str(INTRATE) + ',' + str(NTIMEFRAMES*args.ns) + ':' + str(args.nb) + ' ' + signalprefix + ',' + args.embeddPattern -PreCollContextTask['cmd']='${O2_ROOT}/bin/o2-steer-colcontexttool -i ' + interactionspecification \ - + ' --show-context ' \ - + ' --timeframeID ' + str(int(args.production_offset)*NTIMEFRAMES) \ - + ' --orbitsPerTF ' + str(orbitsPerTF) \ - + ' --orbits ' + str(NTIMEFRAMES * (orbitsPerTF)) \ - + ' --seed ' + str(RNDSEED) \ - + ' --noEmptyTF --first-orbit ' + str(args.first_orbit) \ - + ' --extract-per-timeframe tf:sgn' \ - + ' --with-vertices ' + vtxmode_precoll \ - + ' --maxCollsPerTF ' + str(args.ns) \ - + ' --orbitsEarly ' + str(args.orbits_early) \ - + ('',f" --import-external {args.data_anchoring}")[len(args.data_anchoring) > 0] - -PreCollContextTask['cmd'] += ' --bcPatternFile ccdb' # <--- the object should have been set in (local) CCDB +qedspec="" if includeQED: if PDGA==2212 or PDGB==2212: # QED is not enabled for pp and pA collisions @@ -652,9 +639,28 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): else: qedrate = INTRATE * QEDXSecExpected[COLTYPE] / XSecSys[COLTYPE] # hadronic interaction rate * cross_section_ratio qedspec = 'qed' + ',' + str(qedrate) + ',10000000:' + str(NEventsQED) - PreCollContextTask['cmd'] += ' --QEDinteraction ' + qedspec -workflow['stages'].append(PreCollContextTask) +PreCollContextTask['cmd'] = task_finalizer([ + '${O2_ROOT}/bin/o2-steer-colcontexttool', + f'-i {interactionspecification}', + '--show-context', + f'--timeframeID {int(args.production_offset)*NTIMEFRAMES}', + f'--orbitsPerTF {orbitsPerTF}', + f'--orbits {NTIMEFRAMES * (orbitsPerTF)}', + f'--seed {RNDSEED}', + '--noEmptyTF', + f'--first-orbit {args.first_orbit}', + '--extract-per-timeframe tf:sgn', + f'--with-vertices {vtxmode_precoll}', + f'--maxCollsPerTF {args.ns}', + f'--orbitsEarly {args.orbits_early}', + f'--timestamp {args.timestamp}', + f'--import-external {args.data_anchoring}' if len(args.data_anchoring) > 0 else None, + '--bcPatternFile ccdb', + f'--QEDinteraction {qedspec}' if includeQED else None + ], configname = 'precollcontext') +workflow['stages'].append(PreCollContextTask) +#TODO: in future add standard ' --nontrivial-mu-distribution ccdb://http://ccdb-test.cern.ch:8080/GLO/CALIB/EVSELQA/HBCTVX' if doembedding: if not usebkgcache: From b925a3372c85e48829e15ec74c837f414d0b5936 Mon Sep 17 00:00:00 2001 From: Jseo <47848181+JinjooSeo@users.noreply.github.com> Date: Tue, 16 Dec 2025 09:33:40 +0100 Subject: [PATCH 183/362] Fix mother index and decay chain issue (#2197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix moder index and decay chain issue≈ --- .../generator_pythia8_HadronTriggered_PbPb.C | 84 +++++++++++++------ 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C index 2e6fe4a12..3c3034f80 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C @@ -26,7 +26,7 @@ public: mInverseTriggerRatio = inputTriggerRatio; // define minimum bias event generator auto seed = (gRandom->TRandom::GetSeed() % 900000000); - TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_PbPb_5TeV.cfg"); + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg"); pythiaMBgen.readFile(pathconfigMB.Data()); pythiaMBgen.readString("Random:setSeed on"); pythiaMBgen.readString("Random:seed " + std::to_string(seed)); @@ -79,7 +79,7 @@ protected: for (int pdg : mHadronsPDGs) { // check that at least one of the pdg code is found in the event if (event[ida].id() == pdg) { if ((event[ida].y() > mRapidityMin) && (event[ida].y() < mRapidityMax)) { - cout << "============= Found jpsi y,pt " << event[ida].y() << ", " << event[ida].pT() << endl; + //cout << "============= Found jpsi y,pt " << event[ida].y() << ", " << event[ida].pT() << endl; out.push_back(ida); } } @@ -90,12 +90,22 @@ protected: return out; } + bool keepAncestor(int idabs){ + // charmonium + int mid2 = (idabs / 10) % 100; // 443,100443,20443,445... + if (mid2 == 44) return true; + + // open charm/beauty hadron (D, B, charmed/bottom baryon...) + int flav = (idabs / 100) % 10; + if (flav == 4 || flav == 5) return true; + + return false; +} + void collectAncestors(const Pythia8::Event& event, int idx, std::vector& decayChains, std::vector& visited) { if (idx < 0 || idx >= event.size()) return; - if (!visited[idx]) { - visited[idx] = 1; - decayChains.push_back(idx); - } + if (visited[idx]) return; + visited[idx] = 1; const int idabs = std::abs(event[idx].id()); if (idabs == 4 || idabs == 5 || idabs == 21) return; @@ -108,6 +118,8 @@ void collectAncestors(const Pythia8::Event& event, int idx, std::vector& de if (m == idx) continue; collectAncestors(event, m, decayChains, visited); } + + if (keepAncestor(idabs)) decayChains.push_back(idx); } void collectDaughters(const Pythia8::Event& event, int idx, std::vector& decayChains, std::vector& visited) { @@ -123,6 +135,7 @@ void collectDaughters(const Pythia8::Event& event, int idx, std::vector& de int daughter2 = event[idx].daughter2(); if (daughter1 < 0) return; if (daughter2 < daughter1) daughter2 = daughter1; + for (int d = daughter1; d <= daughter2; ++d) { if (d == idx) continue; collectDaughters(event, d, decayChains, visited); @@ -131,19 +144,28 @@ void collectDaughters(const Pythia8::Event& event, int idx, std::vector& de TParticle makeTParticleTemp(const Pythia8::Event& event, int idx) { const auto& q = event[idx]; - int status = q.status(); - if (status < 0) { - return TParticle(0, 0, -1, -1, -1, -1, - 0.,0.,0.,0., 0.,0.,0.,0.); - } - + int status = q.daughter1() < 0? 1 : 2; + int m1 = q.mother1(); int m2 = q.mother2(); int d1 = q.daughter1(); int d2 = q.daughter2(); - return TParticle(q.id(), status, m1, m2, d1, d2, + TParticle tparticle(q.id(), status, m1, m2, d1, d2, q.px(), q.py(), q.pz(), q.e(), q.xProd(), q.yProd(), q.zProd(), q.tProd()); + + if (tparticle.GetStatusCode() == 1) { + tparticle.SetStatusCode( + o2::mcgenstatus::MCGenStatusEncoding(1, 91).fullEncoding); + tparticle.SetBit(ParticleStatus::kToBeDone, true); + } else { + tparticle.SetStatusCode( + o2::mcgenstatus::MCGenStatusEncoding(2, -91).fullEncoding); + tparticle.SetBit(ParticleStatus::kToBeDone, false); + } + + return tparticle; + } Bool_t importParticles() override @@ -169,7 +191,9 @@ Bool_t importParticles() override std::vector decayChains; std::vector visited(mPythia.event.size(), 0); - decayChains.reserve(256); + decayChains.reserve(mPythia.event.size()); + + //int originalSize = mParticles.size(); // find all ancestors of the charmonia for (size_t ic = 0; ic < charmonia.size(); ++ic) { @@ -187,15 +211,14 @@ Bool_t importParticles() override mParticles.reserve(mParticles.size() + (int)decayChains.size()); for (int i = 0; i < (int)decayChains.size(); ++i) { - const int srcIdx = decayChains[i]; - if (srcIdx < 0 || srcIdx >= mPythia.event.size()) continue; + const int srcIdx = decayChains[i]; + if (srcIdx < 0 || srcIdx >= mPythia.event.size()) continue; - TParticle part = makeTParticleTemp(mPythia.event, srcIdx); - if(part.GetPdgCode() == 0) continue; + TParticle part = makeTParticleTemp(mPythia.event, srcIdx); - int newIdx = (int)mParticles.size(); - mParticles.push_back(part); - idxMap[srcIdx] = newIdx; + int newIdx = (int)mParticles.size(); + mParticles.push_back(part); + idxMap[srcIdx] = newIdx; } for (int iLoc = 0; iLoc < (int) decayChains.size(); ++iLoc) { @@ -218,11 +241,20 @@ Bool_t importParticles() override particle.SetFirstDaughter(daughter1); particle.SetLastDaughter(daughter2); } - LOG(info) << "-----------------------------------------------"; - LOG(info) << "============ After event " << isig << " (size " << decayChains.size() << ")"; - LOG(info) << "Full stack (size " << mParticles.size() << "):"; - LOG(info) << "-----------------------------------------------"; - // printParticleVector(mParticles); + //LOG(info) << "-----------------------------------------------"; + //LOG(info) << "============ After event " << isig << " (size " << decayChains.size() << ")"; + //LOG(info) << "Full stack (size " << mParticles.size() << "):"; + //LOG(info) << "New particles from signal event " << isig; + //for (int id = originalSize; id < (int)mParticles.size(); ++id) { + // const auto& p = mParticles[id]; + // LOG(info) << " id = " << id + // << ", pdg = " << p.GetPdgCode() + // << " --> firstMother=" << p.GetFirstMother() + // << ", lastMother=" << p.GetSecondMother() + // << ", firstDaughter=" << p.GetFirstDaughter() + // << ", lastDaughter=" << p.GetLastDaughter(); + //} + //LOG(info) << "-----------------------------------------------"; } if (mVerbose) mOutputEvent.list(); From f0f1a9b570f7bbe39491d47fca8d7ceb05a27962 Mon Sep 17 00:00:00 2001 From: sawan <124118453+sawankumawat@users.noreply.github.com> Date: Wed, 17 Dec 2025 11:25:55 +0530 Subject: [PATCH 184/362] Added ini file for all exotic resonances for general MC production (#2218) * Added ini file for all exotic resonances general MC production * Added DPG test script for corresponding ini file and corrected the a2(1320) particle --------- Co-authored-by: Sawan Sawan --- .../GeneratorLF_Resonances_pp_exoticAll.ini | 10 ++ .../tests/GeneratorLF_Resonances_pp_exotic.C | 8 +- .../GeneratorLF_Resonances_pp_exoticAll.C | 167 ++++++++++++++++++ .../generator/resonancelistgun_exotic.json | 2 +- 4 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini new file mode 100644 index 000000000..7ec78bb39 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4) + +# [GeneratorPythia8] # if triggered then this will be used as the background event +# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C index 61d739eab..6fe8638d7 100644 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C @@ -7,13 +7,15 @@ int External() int numberOfEventsProcessedWithoutInjection{0}; std::vector injectedPDGs = { 9010221, // f_0(980) + 225, // f_2(1270) + 115, // a_2(1320) 10221, // f_0(1370) 9030221, // f_0(1500) + 335, // f_2(1525) 10331, // f_0(1710) 20223, // f_1(1285) 20333, // f_1(1420) 335, // f_2(1525) - 115, // a_2(1230) 10323, // K1(1270)+ -10323, // K1(1270)-bar 123314, // Xi(1820)- @@ -23,13 +25,15 @@ int External() }; std::vector> decayDaughters = { {211, -211}, // f_0(980) + {310, 310}, // f_2(1270) + {310, 310}, // a_2(1320) {310, 310}, // f_0(1370) {310, 310}, // f_0(1500) + {310, 310}, // f_2(1525) {310, 310}, // f_0(1710) {310, -321, 211}, // f_1(1285) {310, -321, 211}, // f_1(1420) {310, 310}, // f_2(1525) - {310, 310}, // a_2(1230) {321, 211}, // K1(1270)+ {-321, -211}, // K1(1270)-bar {2212, 211}, // Delta(1232)+ diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll.C new file mode 100644 index 000000000..6fe8638d7 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll.C @@ -0,0 +1,167 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 9010221, // f_0(980) + 225, // f_2(1270) + 115, // a_2(1320) + 10221, // f_0(1370) + 9030221, // f_0(1500) + 335, // f_2(1525) + 10331, // f_0(1710) + 20223, // f_1(1285) + 20333, // f_1(1420) + 335, // f_2(1525) + 10323, // K1(1270)+ + -10323, // K1(1270)-bar + 123314, // Xi(1820)- + -123314, // Xi(1820)+ + 123324, // Xi(1820)0 + -123324 // Xi(1820)0bar + }; + std::vector> decayDaughters = { + {211, -211}, // f_0(980) + {310, 310}, // f_2(1270) + {310, 310}, // a_2(1320) + {310, 310}, // f_0(1370) + {310, 310}, // f_0(1500) + {310, 310}, // f_2(1525) + {310, 310}, // f_0(1710) + {310, -321, 211}, // f_1(1285) + {310, -321, 211}, // f_1(1420) + {310, 310}, // f_2(1525) + {321, 211}, // K1(1270)+ + {-321, -211}, // K1(1270)-bar + {2212, 211}, // Delta(1232)+ + {3122, -311}, // Xi(1820)- + {3122, 311}, // Xi(1820)+ + {3122, 310}, // Xi(1820)0 + {-3122, 310} // Xi(1820)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json index 870beacdf..2727376ca 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json @@ -87,7 +87,7 @@ "rapidityMax": 1.2, "genDecayed": true }, - "a_2(1230)": { + "a_2(1320)": { "pdg": 115, "n": 1, "ptMin": 0.0, From 35d151b2a32f6d70ed3954a3fc73be2b438b4a43 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 16 Dec 2025 10:38:10 +0100 Subject: [PATCH 185/362] Allow to run central barrel only Makes it possible to run with central-barrel only, minimal detector lists such as export ALIEN_JDL_WORKFLOWDETECTORS=ITS,TPC,CTP export ALIEN_JDL_WORKFLOWDETECTORS=ITS,TPC,TOF,CTP export ALIEN_JDL_WORKFLOWDETECTORS=ITS,TPC,TOF,TRD,CTP --- MC/bin/o2dpg_qc_finalization_workflow.py | 28 ++++++----- MC/bin/o2dpg_sim_workflow.py | 61 +++++++++++++----------- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/MC/bin/o2dpg_qc_finalization_workflow.py b/MC/bin/o2dpg_qc_finalization_workflow.py index 45d4ffd77..815425968 100755 --- a/MC/bin/o2dpg_qc_finalization_workflow.py +++ b/MC/bin/o2dpg_qc_finalization_workflow.py @@ -85,15 +85,16 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif ## The list of remote-batch workflows (reading the merged QC tasks results, applying Checks, uploading them to QCDB) MFTDigitsQCneeds = [] - for flp in range(5): - MFTDigitsQCneeds.extend(['mftDigitsQC'+str(flp)+'_local'+str(tf) for tf in range(1, ntimeframes + 1)]) - add_QC_finalization('mftDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-0.json', MFTDigitsQCneeds) - add_QC_finalization('mftClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-clusters.json') - add_QC_finalization('mftTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks.json') - add_QC_finalization('mftMCTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks-mc.json') - add_QC_finalization('emcRecoQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') - add_QC_finalization('emcBCQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') - #add_QC_finalization('tpcTrackingQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-tracking-direct.json') + if isActive('MFT'): + for flp in range(5): + MFTDigitsQCneeds.extend(['mftDigitsQC'+str(flp)+'_local'+str(tf) for tf in range(1, ntimeframes + 1)]) + add_QC_finalization('mftDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-0.json', MFTDigitsQCneeds) + add_QC_finalization('mftClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-clusters.json') + add_QC_finalization('mftTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks.json') + add_QC_finalization('mftMCTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks-mc.json') + if isActive('EMC'): + add_QC_finalization('emcRecoQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') + add_QC_finalization('emcBCQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') add_QC_finalization('tpcStandardQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-standard-direct.json') if isActive('TRD'): add_QC_finalization('trdDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') @@ -127,8 +128,10 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif else: add_QC_finalization('tofPIDQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/pidtofNoTRD.json') add_QC_finalization('RecPointsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/ft0-reconstruction-config.json') - add_QC_finalization('FV0DigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fv0-digits.json') - add_QC_finalization('FDDRecPointsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fdd-recpoints.json') + if isActive('FV0'): + add_QC_finalization('FV0DigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fv0-digits.json') + if isActive('FDD'): + add_QC_finalization('FDDRecPointsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fdd-recpoints.json') if isActive('CPV'): add_QC_finalization('CPVDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-digits-task.json') add_QC_finalization('CPVClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-clusters-task.json') @@ -136,7 +139,8 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif add_QC_finalization('PHSCellsClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/phs-cells-clusters-task.json') # The list of QC Post-processing workflows - add_QC_postprocessing('tofTrendingHits', 'json://${O2DPG_ROOT}/MC/config/QC/json/tof-trending-hits.json', [QC_finalize_name('tofDigitsQC')], runSpecific=False, prodSpecific=True) + if isActive('TOF'): + add_QC_postprocessing('tofTrendingHits', 'json://${O2DPG_ROOT}/MC/config/QC/json/tof-trending-hits.json', [QC_finalize_name('tofDigitsQC')], runSpecific=False, prodSpecific=True) return stages diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index b6686e425..6a0bac050 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1382,13 +1382,13 @@ def getDigiTaskName(det): workflow['stages'].append(FT0RECOtask) #<--------- ITS-TPC track matching task - ITSTPCMATCHtask=createTask(name='itstpcMatch_'+str(tf), needs=[TPCRECOtask['name'], ITSRECOtask['name'], FT0RECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='8000', relative_cpu=3/8) + ITSTPCMATCHtask=createTask(name='itstpcMatch_'+str(tf), needs=[TPCRECOtask['name'], ITSRECOtask['name'], FT0RECOtask['name'] if isActive("FT0") else None], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='8000', relative_cpu=3/8) ITSTPCMATCHtask["cmd"] = task_finalizer([ '${O2_ROOT}/bin/o2-tpcits-match-workflow', getDPL_global_options(bigshm=True), ' --tpc-track-reader tpctracks.root', '--tpc-native-cluster-reader \"--infile tpc-native-clusters.root\"', - '--use-ft0', + '--use-ft0' if isActive("FT0") else None, putConfigValues(['MFTClustererParam', 'ITSCATrackerParam', 'tpcitsMatch', @@ -1468,7 +1468,7 @@ def getDigiTaskName(det): 'trackTuneParams'], tpcLocalCFreco), ' --track-sources ' + toftracksrcdefault, (' --combine-devices','')[args.no_combine_dpl_devices], - tofusefit, + tofusefit if isActive("FT0") else None, tpc_corr_scaling_options, tpc_corr_options_mc ] @@ -1493,7 +1493,8 @@ def getDigiTaskName(det): 'MFTClustererParam']), ('','--disable-mc')[args.no_mc_labels], ('','--run-assessment')[args.mft_assessment_full]]) - workflow['stages'].append(MFTRECOtask) + if isActive("MFT"): + workflow['stages'].append(MFTRECOtask) # MCH reco: needing access to kinematics ... so some extra logic needed here mchreconeeds = [getDigiTaskName("MCH")] @@ -1614,7 +1615,7 @@ def getDigiTaskName(det): #<--------- MFT-MCH forward matching forwardmatchneeds = [MCHRECOtask['name'], - MFTRECOtask['name'], + MFTRECOtask['name'] if isActive("MFT") else None, MCHMIDMATCHtask['name'] if isActive("MID") else None] MFTMCHMATCHtask = createTask(name='mftmchMatch_'+str(tf), needs=forwardmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') MFTMCHMATCHtask['cmd'] = task_finalizer( @@ -1877,21 +1878,22 @@ def remove_json_prefix(path): ### MFT # to be enabled once MFT Digits should run 5 times with different configurations - for flp in range(5): - addQCPerTF(taskName='mftDigitsQC' + str(flp), - needs=[getDigiTaskName("MFT")], - readerCommand='o2-qc-mft-digits-root-file-reader --mft-digit-infile=mftdigits.root', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-' + str(flp) + '.json', - objectsFile='mftDigitsQC.root') - addQCPerTF(taskName='mftClustersQC', + if isActive("MFT"): + for flp in range(5): + addQCPerTF(taskName='mftDigitsQC' + str(flp), + needs=[getDigiTaskName("MFT")], + readerCommand='o2-qc-mft-digits-root-file-reader --mft-digit-infile=mftdigits.root', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-' + str(flp) + '.json', + objectsFile='mftDigitsQC.root') + addQCPerTF(taskName='mftClustersQC', needs=[MFTRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types none --cluster-types MFT', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-clusters.json') - addQCPerTF(taskName='mftTracksQC', + addQCPerTF(taskName='mftTracksQC', needs=[MFTRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types MFT --cluster-types MFT', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks.json') - addQCPerTF(taskName='mftMCTracksQC', + addQCPerTF(taskName='mftMCTracksQC', needs=[MFTRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types MFT --cluster-types MFT', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks-mc.json') @@ -1962,22 +1964,25 @@ def remove_json_prefix(path): readerCommand='o2-emcal-cell-reader-workflow --infile emccells.root | o2-ctp-digit-reader --inputfile ctpdigits.root --disable-mc', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/emc-bc-task.json') ### FT0 - addQCPerTF(taskName='RecPointsQC', - needs=[FT0RECOtask['name']], - readerCommand='o2-ft0-recpoints-reader-workflow --infile o2reco_ft0.root', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/ft0-reconstruction-config.json') + if isActive("FT0"): + addQCPerTF(taskName='RecPointsQC', + needs=[FT0RECOtask['name']], + readerCommand='o2-ft0-recpoints-reader-workflow --infile o2reco_ft0.root', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/ft0-reconstruction-config.json') ### FV0 - addQCPerTF(taskName='FV0DigitsQC', - needs=[getDigiTaskName("FV0")], - readerCommand='o2-fv0-digit-reader-workflow --fv0-digit-infile fv0digits.root', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/fv0-digits.json') + if isActive("FV0"): + addQCPerTF(taskName='FV0DigitsQC', + needs=[getDigiTaskName("FV0")], + readerCommand='o2-fv0-digit-reader-workflow --fv0-digit-infile fv0digits.root', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/fv0-digits.json') ### FDD - addQCPerTF(taskName='FDDRecPointsQC', - needs=[FDDRECOtask['name']], - readerCommand='o2-fdd-recpoints-reader-workflow --fdd-recpoints-infile o2reco_fdd.root', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/fdd-recpoints.json') + if isActive("FDD"): + addQCPerTF(taskName='FDDRecPointsQC', + needs=[FDDRECOtask['name']], + readerCommand='o2-fdd-recpoints-reader-workflow --fdd-recpoints-infile o2reco_fdd.root', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/fdd-recpoints.json') ### GLO + RECO addQCPerTF(taskName='vertexQC', @@ -2079,7 +2084,9 @@ def remove_json_prefix(path): tpctsneeds = [ TPCRECOtask['name'], ITSTPCMATCHtask['name'], TOFTPCMATCHERtask['name'], - PVFINDERtask['name'] + FT0RECOtask['name'], + PVFINDERtask['name'], + TRDTRACKINGtask2['name'] ] TPCTStask = createTask(name='tpctimeseries_'+str(tf), needs=tpctsneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='2000', cpu='1') TPCTStask['cmd'] = 'o2-global-track-cluster-reader --disable-mc --cluster-types "FT0,TOF,TPC" --track-types "ITS,TPC,ITS-TPC,ITS-TPC-TOF,ITS-TPC-TRD-TOF"' From 0acdaf14adf9f4ee755eccc16af7f356d4c11fe1 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 18 Dec 2025 17:07:11 +0100 Subject: [PATCH 186/362] Treat "all" in detector list cleaning --- MC/bin/o2dpg_sim_workflow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 6a0bac050..412f7c8f5 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -295,6 +295,8 @@ def load_external_config(configfile): # function to finalize detector source lists based on activeDetectors # detector source lists are comma separated lists of DET1, DET2, DET1-DET2, ... def cleanDetectorInputList(inputlist): + if inputlist == "all": + return inputlist sources_list = inputlist.split(",") # Filter the sources filtered_sources = [ From 31cbf2f39828c55abbdd59e954c0385846054e65 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Wed, 17 Dec 2025 18:11:59 +0100 Subject: [PATCH 187/362] Add DPL-eventgen testing --- MC/config/common/ini/GeneratorPerformanceFix.ini | 2 +- test/run_generator_tests.sh | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/MC/config/common/ini/GeneratorPerformanceFix.ini b/MC/config/common/ini/GeneratorPerformanceFix.ini index b92b2300c..7c0ce5f0d 100644 --- a/MC/config/common/ini/GeneratorPerformanceFix.ini +++ b/MC/config/common/ini/GeneratorPerformanceFix.ini @@ -1,4 +1,4 @@ -# Test performance generator for multidimensional studies using fix number of signal particles per event +# Test performance generator for multidimensional studies using fixed number of signal particles per event # Parameters are in order: fraction of signal particles, fixed number of signal particles per event, tag to select the generator type # Setting fraction = -1 enables the fixed number of signal particles per event (nsig). # An hybrid configuration JSON file is provided in ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/perfConf.json to run the generator diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index 6c5f3b8b8..a5d732291 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -113,6 +113,7 @@ exec_test() local generator_lower=$(echo "${generator}" | tr '[:upper:]' '[:lower:]') # TODO Potentially, one could run an external generator that derives from GeneratorPythia8 and so could probably use configuration for TriggerPythia8 local trigger=${3:+-t ${generator_lower}} + local trigger_dpl=${3:+--trigger ${generator_lower}} local RET=0 # this is how our test script is expected to be called local test_script=$(get_test_script_path_for_ini ${ini_path}) @@ -122,7 +123,15 @@ exec_test() echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_KINE} echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_GENERIC_KINE} echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_SIM} + echo "### Testing DPL-eventgen ###" >> ${LOG_FILE_SIM} + # run the event generation using the dpl-eventgen executable. + # This is a basic running test, however it's important because the system running on Hyperloop + # is largely used for MCGEN productions and is currently tested only locally + o2-sim-dpl-eventgen --generator ${generator_lower} ${trigger_dpl} --nEvents ${nev} --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" -b >> ${LOG_FILE_SIM} 2>&1 + RET=${?} + [[ "${RET}" != "0" ]] && { remove_artifacts ; return ${RET} ; } # run the simulation, fail if not successful + echo "### Testing base o2-sim executable ###" >> ${LOG_FILE_SIM} o2-sim -g ${generator_lower} ${trigger} --noGeant -n ${nev} -j 4 --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" >> ${LOG_FILE_SIM} 2>&1 RET=${?} [[ "${RET}" != "0" ]] && { remove_artifacts ; return ${RET} ; } From d48f01f52e44a0d77c69f32ce85c9f1b7e098c83 Mon Sep 17 00:00:00 2001 From: Florian Jonas Date: Wed, 17 Dec 2025 11:35:14 +0100 Subject: [PATCH 188/362] [PWGHF] add configuration for D2H ccbar and bbbar gap2 for pO collisions --- ...torHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini | 8 + ...ratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C | 189 +++++++++++ ...hia8_charmhadronic_with_decays_SCCR_pO.cfg | 300 ++++++++++++++++++ 3 files changed, 497 insertions(+) create mode 100755 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini new file mode 100755 index 000000000..701dfc74e --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini @@ -0,0 +1,8 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(2, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C new file mode 100644 index 000000000..5cc0e18e6 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C @@ -0,0 +1,189 @@ +int External(std::string path = "o2sim_Kine.root") { + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./2; // one event triggered out of 2 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = float(nSignalGoodDecay) / nSignals; + if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg new file mode 100644 index 000000000..e59c79da7 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg @@ -0,0 +1,300 @@ +# Pythia8 configuration file for charm hadronic production in pO collisions at 9.62 TeV + +### beams +Beams:frameType 2 # back-to-back beams of different energies and particles +Beams:idA 2212 # proton +Beams:idB 1000080160 # Oxygen +Beams:eA 6800. # Energy of proton beam in GeV moving in the +z direction +Beams:eB 3400. # Energy in GeV per Oxygen nucleon (6.8 Z TeV) moving in the -z direction + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen 0 +HeavyIon:SigFitDefPar 2.15,18.42,0.33 + +Random:setSeed on + +### switching on spatially constrained QCD colour reconnection (SC-CR) mode +ColourReconnection:mode = 1 +ColourReconnection:timeDilationMode = 0 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 1.05 +ColourReconnection:allowJunctions = on +ColourReconnection:lambdaForm = 1 +ColourReconnection:mPseudo = 1.05 +ColourReconnection:junctionCorrection = 1.37 +ColourReconnection:dipoleMaxDist = 0.5 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.4 +StringFlav:probQQ1toQQ0join = 0.5,0.7,0.9,1.0 +MultiPartonInteractions:pT0Ref = 2.37 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation = 5 +BeamRemnants:beamJunction = on +ColourReconnection:heavyLambdaForm = 1 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +# HF decays +### BR are set to yield 50% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (50%) +421:oneChannel = 1 0.50000 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (12.50%) +421:addChannel = 1 0.00625 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.08750 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.01250 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.01875 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (12.50%) +421:addChannel = 1 0.12500 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (12.50%) +421:addChannel = 1 0.08750 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.03750 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (12.50%) +421:addChannel = 1 0.12500 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (50%) +411:oneChannel = 1 0.40189 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +411:addChannel = 1 0.05356 0 -10311 211 ### D+ -> antiK*0(1430) π+ 1.25% +411:addChannel = 1 0.04455 0 -313 211 ### D+ -> K*0(892) pi+ 1.04% +### D+ -> K- π+ π+ π0 (small, 3%) +411:addChannel = 1 0.03000 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (36.00%, set 25% for D+ -> φ π+, 11% for the rest) +411:addChannel = 1 0.25000 0 333 211 ### D+ -> φ π+ 2.69e-3 !needed for signal +411:addChannel = 1 0.03929 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.02865 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.04206 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (11.00%) +411:addChannel = 1 0.02911 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.01618 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.06471 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (50%) +431:oneChannel = 1 0.50000 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.15000 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 2%) +431:addChannel = 1 0.02000 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (11.00%) +431:addChannel = 1 0.00220 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.00220 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.10560 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (11.00%) +431:addChannel = 1 0.03080 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.02200 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.03960 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.01760 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (11.00%) +431:addChannel = 1 0.11000 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 + +### add OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 +### rho0 -> π+ π- +113:onMode = off +113:onIfAll = 211 211 +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +3122:onMode = off +3122:onIfAll = 2212 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 + +# switch off all decay channels +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4232:onMode = off +4132:onMode = off +443:onMode = off +4332:onMode = off + +# Allow the decay of HF +### D0 -> K π +421:onIfMatch = 321 211 +### D0 -> K π π0 +421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 + +### D+/- -> K π π +411:onIfMatch = 321 211 211 +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* π +411:onIfMatch = 313 211 +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 211 +### D+/- -> antiK* K +411:onIfMatch = 10311 321 +### D+/- -> φ π +411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 + +### Ds -> φ π +431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 + +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 \ No newline at end of file From d25f9339e98e70cef5d35706ee527861db4b709a Mon Sep 17 00:00:00 2001 From: Florian Jonas Date: Wed, 17 Dec 2025 11:55:21 +0100 Subject: [PATCH 189/362] reduce number of events for tests --- .../PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini index 701dfc74e..80e2bc876 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 12 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(2, -1.5, 1.5) From 627024708948c81bd0bf3a52536bab9c13779dd9 Mon Sep 17 00:00:00 2001 From: Ravindra Singh <56298081+singhra1994@users.noreply.github.com> Date: Fri, 19 Dec 2025 10:00:45 +0100 Subject: [PATCH 190/362] [PWGHG] Adjusted centrality range in HF config file to keep dummy values (#2220) * PWGHF: Adjust centrality range in hfEvSel settings to include dummy values * Update centrality range in analysis JSON config to keep dummy values --- .../json/dpl/o2-analysis-hf-candidate-creator-2prong.json | 6 +++--- .../json/dpl/o2-analysis-hf-track-index-skim-creator.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json index b49600077..16db4aa70 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json @@ -14,8 +14,8 @@ "ccdbPathGrp": "GLO\/GRP\/GRP", "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", "hfEvSel": { - "centralityMin": "0", - "centralityMax": "100", + "centralityMin": "-10", + "centralityMax": "110", "useSel8Trigger": "true", "triggerClass": "-1", "useTvxTrigger": "false", @@ -93,4 +93,4 @@ "processMcCentFT0C": "false", "processMcCentFT0M": "false" } -} \ No newline at end of file +} diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json index 9bfa2f5d9..3d941b71e 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json @@ -3,8 +3,8 @@ "fillHistograms": "true", "triggerClassName": "", "hfEvSel": { - "centralityMin": "0", - "centralityMax": "100", + "centralityMin": "-10", + "centralityMax": "110", "useSel8Trigger": "true", "triggerClass": "-1", "useTvxTrigger": "false", @@ -892,4 +892,4 @@ "processNoCascades": "true", "processCascades": "false" } -} \ No newline at end of file +} From 2e31d1b293ec8a7fdf2eb43e3cda201b6939c60a Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 19 Dec 2025 15:05:57 +0100 Subject: [PATCH 191/362] add 2tag-test case (recently failing) --- MC/run/ANCHOR/tests/test_anchor_cases.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/MC/run/ANCHOR/tests/test_anchor_cases.csv b/MC/run/ANCHOR/tests/test_anchor_cases.csv index 490b7bba5..d6bd9a6f3 100644 --- a/MC/run/ANCHOR/tests/test_anchor_cases.csv +++ b/MC/run/ANCHOR/tests/test_anchor_cases.csv @@ -8,6 +8,7 @@ # O2PDPSuite::async-async-2022-pp-apass7-v1,apass7, | 526641 # 2023 O2sim::v20250806-1,O2PDPSuite::async-async-2023-PbPb-apass5-v5-slc9-alidist-async-2023-PbPb-apass5-v5-1,apass5,Pb-Pb,544091,PbPb,LHC23zzh,2023,-gen pythia8 +O2sim::v20250806-1,O2PDPSuite::async-async-20240229.pp.2b-slc9-alidist-O2PDPSuite-daily-20231208-0100-async1-1,apass4,p-p,535085,pp,LHC23f,2023,-gen pythia8 # 2024 O2sim::v20250806-1,O2PDPSuite::async-async-2024-pp-apass1-v7-slc9-alidist-async-2024-pp-apass1-v7-1,apass1,p-p,553185,pp,LHC24al,2024,-gen pythia8 O2sim::v20250806-1,O2PDPSuite::async-async-2024-ppRef-apass1-v1-slc9-alidist-async-2024-ppRef-apass1-v1-1,apass1,p-p,559348,pp,LHC24ap,2024,-gen pythia8 From 28f0599860c395e6f3692ceae09212d52a66726d Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Wed, 17 Dec 2025 20:36:20 +0100 Subject: [PATCH 192/362] Fix Pythia8 CI testing The Pythia8() function exists already in the Pythia namespace loaded with ROOT, so when executing the macro a function redefinition error was thrown. By replacing the name to pythia8() the problem is solved. --- MC/config/ALICE3/ini/tests/pythia8_ArAr.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_KrKr.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_OO.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_PbPb.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_XeXe.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C | 2 +- MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C | 2 +- MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C | 8 ++++---- test/README.md | 2 +- test/run_generator_tests.sh | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/MC/config/ALICE3/ini/tests/pythia8_ArAr.C b/MC/config/ALICE3/ini/tests/pythia8_ArAr.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_ArAr.C +++ b/MC/config/ALICE3/ini/tests/pythia8_ArAr.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_KrKr.C b/MC/config/ALICE3/ini/tests/pythia8_KrKr.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_KrKr.C +++ b/MC/config/ALICE3/ini/tests/pythia8_KrKr.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_OO.C b/MC/config/ALICE3/ini/tests/pythia8_OO.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_OO.C +++ b/MC/config/ALICE3/ini/tests/pythia8_OO.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_PbPb.C b/MC/config/ALICE3/ini/tests/pythia8_PbPb.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_PbPb.C +++ b/MC/config/ALICE3/ini/tests/pythia8_PbPb.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C b/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_XeXe.C b/MC/config/ALICE3/ini/tests/pythia8_XeXe.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_XeXe.C +++ b/MC/config/ALICE3/ini/tests/pythia8_XeXe.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp.C b/MC/config/ALICE3/ini/tests/pythia8_pp.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C index 9250232c0..ac9df9f68 100644 --- a/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C +++ b/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C @@ -50,7 +50,7 @@ int External() { return 0; } -//int Pythia8() -//{ -// return External(); -//} +int pythia8() +{ + return External(); +} diff --git a/test/README.md b/test/README.md index 3c2a90d47..6745eae5b 100644 --- a/test/README.md +++ b/test/README.md @@ -26,7 +26,7 @@ Whenever an `ini` file is detedcted to be tested, a test macro is required to be ``` Note, that `run_tests.sh` will automatically detect all generators used in an `ini`. For at least one generator defined in the `ini` file there must be a test. Each test is defined as a function in the `.C` macro. Assuming you want to test `External` and `Pythia8` generator, the macro should look like ```cpp -int Pythia8() +int pythia8() { // do your test return ret; diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index a5d732291..04443c528 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -21,7 +21,7 @@ export ROOT_INCLUDE_PATH LD_LIBRARY_PATH # Entrypoint for O2DPG related tests # ###################################### -CHECK_GENERATORS="Pythia8 External" +CHECK_GENERATORS="pythia8 External" # The test parent dir to be cretaed in current directory TEST_PARENT_DIR="o2dpg_tests/generators" From 7161e7ec294250f405a292c1189b470781a7118e Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Tue, 23 Dec 2025 19:50:10 +0100 Subject: [PATCH 193/362] Reduce number of events for tests (#2216) --- MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini | 1 + MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini | 1 + MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini | 2 +- .../ini/GeneratorHFTrigger_LambdaBToNuclei.ini | 2 +- .../PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini | 2 +- .../PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini | 2 +- .../PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini | 2 +- MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini | 2 +- MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini | 2 +- MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini | 1 + .../GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini | 2 +- .../ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini | 2 +- .../ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini | 2 +- .../GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini | 2 +- ...atorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini | 2 +- MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini | 1 + ...ratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini | 1 + .../ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini | 1 + ...GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini | 1 + ...eratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini | 1 + ...GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini | 1 + .../ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini | 1 + .../GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini | 1 + ...neratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini | 1 + .../ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini | 1 + .../GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini | 1 + ...atorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini | 1 + .../GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini | 1 + ..._D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini | 1 + ...bar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini | 1 + ...neratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini | 1 + ...HF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini | 1 + ...torHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini | 1 + ...D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini | 2 +- ...atorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini | 1 + .../ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini | 1 + ...neratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini | 1 + MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini | 1 + .../GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini | 1 + .../GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini | 1 + ...eneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini | 1 + .../GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini | 1 + ...eratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini | 1 + .../GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini | 1 + .../GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini | 1 + ...eneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini | 1 + .../GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini | 1 + ...eratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini | 1 + .../GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini | 1 + .../PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C | 2 +- .../PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C | 2 +- ...neratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C | 2 +- ...eratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C | 4 ++-- ...ratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C | 2 +- MC/config/PWGHF/ini/trigger_hf.ini | 13 ------------- 55 files changed, 55 insertions(+), 32 deletions(-) delete mode 100644 MC/config/PWGHF/ini/trigger_hf.ini diff --git a/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini b/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini index df4ef98a1..1401a63ec 100644 --- a/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini +++ b/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_box.C funcName=generatePythia8Box(4332, 3) diff --git a/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini b/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini index 06695380b..a781b81be 100644 --- a/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini +++ b/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_box.C funcName=generatePythia8Box(4332, 3) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini index 108242b2a..9c30cbdcb 100755 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(3, -5, 5) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToNuclei.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToNuclei.ini index 5960295a7..5ef69c415 100644 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToNuclei.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToNuclei.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C funcName=generateHFHadToNuclei(3, {5122}, {1000020030, 1000010030}, true, 0.5) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini index bbe44e4f2..80c27b5ba 100644 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(5,-1.5,1.5,-1.5,1.5,{4332}) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini index 5cce50121..5beb85b15 100644 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(5,-1.5,1.5,-1.5,1.5,{4132}) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini index 650649e46..98035dc7a 100644 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapHF(5,-1.5,1.5,-1.5,1.5,{4,5}, {4132, 4332}) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini index fffbad370..c79c39e3c 100755 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(3, -5, 5) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini index 3becd0dfb..4dc2594a0 100755 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(3, -5, 5) diff --git a/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini b/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini index 517923892..4a234ed08 100644 --- a/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini +++ b/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_box.C funcName=generatePythia8Box(4132, 3) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini index de43066b4..52ddaf828 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(5, -1.5, 1.5) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini index 304d17a20..25d30964c 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(5, -1.5, 1.5) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini index 1a8eeb8b5..fc956774f 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini @@ -1,4 +1,4 @@ -#NEV_TEST> 10 +#NEV_TEST> 5 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini index 091f15e22..508b76dec 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini @@ -1,4 +1,4 @@ -#NEV_TEST> 10 +#NEV_TEST> 5 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini index 6fd35e411..5a9b792e5 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -1,4 +1,4 @@ -#NEV_TEST> 10 +#NEV_TEST> 5 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini index 5e463ae0e..4b65f23e8 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini index 4f67c5b2e..ed7202eb2 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini index 5a7e99b3c..03b15ce2c 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini index 143f9589f..57715e41c 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini index dc2cb28a0..2273c8205 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini index 080a6c2b0..1c74bb53d 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 16 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini index 60a6ff4c5..f7fefbb20 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 24 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini index aab7d4b5f..8b0d2fb2f 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 12 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini index 0abfe5c4f..bfa5df7b9 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 12 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini index de97f7740..429f59170 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini index 84138c596..713b79c1c 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini index 493a53901..93c74daa2 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini index f6ba8d251..2f4a41721 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini index 8f5bfbca4..20fd5ab60 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini index 9c6f81e7d..569fee4c5 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini index 5869198dc..ad1aa5422 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini index bae677ab5..4d2e31712 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini index a88c48b63..840f0d14b 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini index e219b44b5..8dd04bc87 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini @@ -1,4 +1,4 @@ - +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini index 1d0d23364..a25d587cc 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini index c2731d152..47b370b8c 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 32 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini index d4d5ca1c3..97795a224 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 16 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini index cfcfb073e..8c598e7e1 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini index 9f7191c80..564cb14f7 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini index e945e5789..73dd727e7 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 24 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini index 8a0b4ffd3..582ed736b 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini index ad1d271eb..8db0ed60b 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini index 1c5368bf2..972c075b2 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini index e96f24a0c..923394b48 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini index f3ae527b9..bc2c06c55 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 24 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini index 8540f0838..149728000 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini index 7ca5f7c86..6c3904834 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini index 149812d38..970a08807 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini index c694e078f..43e1b79fa 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C index ac58836b2..234b51bbe 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C @@ -83,7 +83,7 @@ int External() } float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) // we put some tolerance (e.g. due to oscillations which might change the final state) + if (fracForcedDecays < 0.85) // we put some tolerance (e.g. due to oscillations which might change the final state) { std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C index 0dda90492..7fb3eacb6 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C @@ -103,7 +103,7 @@ int External() } float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + if (fracForcedDecays < 0.7) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C index e46d1544d..11cb92fc3 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C @@ -129,7 +129,7 @@ int External() { return 1; } - if (averagePt < 7.) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) + if (averagePt < 6.5) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) std::cerr << "Average pT of charmed hadrons " << averagePt << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C index b33434bb0..f70d958d5 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C @@ -12,7 +12,7 @@ int External() { std::array checkPdgHadron{411, 421, 10433, 30433, 435, 437, 4325, 4326, 4315, 4316, 531, 425}; std::map>> checkHadronDecays{ // sorted pdg of daughters {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ - {421, {{-321, 211}, {-321, 211, 111}}}, // D0 + {421, {{-321, 211}, {-321, 111, 211}}}, // D0 {435, {{311, 413}, {311, 411}}}, // Ds2*(2573) {10433, {{311, 413}}}, // Ds1(2536) {30433, {{311, 413}}}, // Ds1*(2700) @@ -22,7 +22,7 @@ int External() { {4315, {{421, 3122}}}, // Xic(3055)+ {4316, {{421, 3122}}}, // Xic(3080)+ {531, {{-435, -11, 12}, {-10433, -11, 12}, {-435, -13, 14}, {-10433, -13, 14}, {-435, -15, 16}, {-10433, -15, 16}, {-435, 211}}}, // Bs0 - {425, {{413, -211}, {423, 111}, {411, -211}, {421, 111}, {413, -211, 111}, {423, 211, -211}}} + {425, {{-211, 413}, {111, 423}, {-211, 411}, {111, 421}, {-211, 111, 413}, {-211, 211, 423}}} }; TFile file(path.c_str(), "READ"); diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C index c7f5eaf16..eeb37acfc 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C @@ -171,7 +171,7 @@ int External() { } float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + if (fracForcedDecays < 0.8) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/trigger_hf.ini b/MC/config/PWGHF/ini/trigger_hf.ini deleted file mode 100644 index 0558581fe..000000000 --- a/MC/config/PWGHF/ini/trigger_hf.ini +++ /dev/null @@ -1,13 +0,0 @@ -[GeneratorPythia8] -config=pythia8.cfg - -[TriggerExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/trigger/trigger_ccbar.C -funcName=trigger_ccbar(-1.5,1.5) - -[DecayerPythia8] -config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/decayer/force_hadronic_D.cfg -config[2] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/decayer/force_hadronic_D_use4bodies.cfg - -#/alice/O2DPG/MC/config/PWGHF/external/trigger From 9c5a142cdb475af361311bb5219c566ab2759e4a Mon Sep 17 00:00:00 2001 From: Arvind Khuntia Date: Tue, 23 Dec 2025 12:55:41 +0100 Subject: [PATCH 194/362] Add deuteron injected ini files for OO --- .../PWGLF/ini/GeneratorLFDeuteronOOGap.ini | 6 +++ .../ini/tests/GeneratorLFDeuteronOOGap.C | 53 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLFDeuteronOOGap.C diff --git a/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini b/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini new file mode 100644 index 000000000..850b3e26a --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C +funcName=generateLongLivedGapTriggered(1000010020, 1, 4, 0.4, 8.0) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFDeuteronOOGap.C b/MC/config/PWGLF/ini/tests/GeneratorLFDeuteronOOGap.C new file mode 100644 index 000000000..6d270f811 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFDeuteronOOGap.C @@ -0,0 +1,53 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector possiblePDGs = {1000010020, -1000010020}; + + int nPossiblePDGs = possiblePDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector injectedPDGs; + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(possiblePDGs.begin(), possiblePDGs.end(), pdg); + if (it != possiblePDGs.end() && track.isPrimary()) // found + { + injectedPDGs.push_back(pdg); + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + if(injectedPDGs.empty()){ + std::cerr << "No injected particles\n"; + return 1; // At least one of the injected particles should be generated + } + for (int i = 0; i < nPossiblePDGs; i++) + { + std::cout << "# Injected nuclei \n"; + std::cout << possiblePDGs[i] << ": " << std::count(injectedPDGs.begin(), injectedPDGs.end(), possiblePDGs[i]) << "\n"; + } + return 0; +} From d71859aa417b597e8c410bff6a9ae5430cb25f8d Mon Sep 17 00:00:00 2001 From: arvindkhuntia <31609955+arvindkhuntia@users.noreply.github.com> Date: Tue, 23 Dec 2025 17:03:46 +0100 Subject: [PATCH 195/362] Update GeneratorLFDeuteronOOGap.ini --- MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini b/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini index 850b3e26a..5fd1a11dc 100644 --- a/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini +++ b/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C -funcName=generateLongLivedGapTriggered(1000010020, 1, 4, 0.4, 8.0) +funcName=generateLongLivedGapTriggered({1000010020}, 1, 4, 0.4, 8.0) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg \ No newline at end of file +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg From 3bef31fe6bbf41294d2f65cf51e98d68c218b18f Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 19 Dec 2025 15:49:24 +0100 Subject: [PATCH 196/362] Implemented ITS ramp-up shift in start-of-run --- MC/bin/o2dpg_sim_workflow_anchored.py | 29 ++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow_anchored.py b/MC/bin/o2dpg_sim_workflow_anchored.py index 31d8ffb1c..14ce8d146 100755 --- a/MC/bin/o2dpg_sim_workflow_anchored.py +++ b/MC/bin/o2dpg_sim_workflow_anchored.py @@ -266,6 +266,21 @@ def retrieve_CTPScalers(ccdbreader, run_number, timestamp=None): return ctpscaler return None +def retrieve_ITS_RampDuration(ccdbreader, timestamp): + """ + Retrieves the ITS ramp-up duration for a given timestamp and + returns it in milliseconds. + ITS does not deliver digits during a certain ramp-up period so + the start of run is adjusted accordingly using this value. + """ + _, ramp_duration = ccdbreader.fetch("ITS/Calib/RampDuration", "vector", timestamp=timestamp) + if ramp_duration and len(ramp_duration) > 0: + # The vector contains the duration in seconds, convert to milliseconds + duration_ms = int(ramp_duration[0] * 1000) + return duration_ms + print("WARNING: ITS ramp duration vector is empty, using 0") + return 0 + def retrieve_MinBias_CTPScaler_Rate(ctpscaler, finaltime, trig_eff_arg, NBunches, ColSystem, eCM): """ retrieves the CTP scalers object for a given timestamp @@ -520,7 +535,11 @@ def main(): run_start = GLOparams["SOR"] run_end = GLOparams["EOR"] - mid_run_timestamp = (run_start + run_end) // 2 + # Adjust start of run using ITS ramp-up period + ITS_rampup = retrieve_ITS_RampDuration(ccdbreader, run_start) + print(f"ITS ramp-up time: {ITS_rampup} ms") + effective_run_start = run_start + ITS_rampup + mid_run_timestamp = (effective_run_start + run_end) // 2 # -------- # fetch other important global properties needed further below @@ -580,16 +599,16 @@ def main(): timestamp = 0 prod_offset = 0 if args.timeframeID != -1: - timestamp = determine_timestamp_from_timeframeID(run_start, run_end, args.timeframeID, GLOparams["OrbitsPerTF"]) + timestamp = determine_timestamp_from_timeframeID(effective_run_start, run_end, args.timeframeID, GLOparams["OrbitsPerTF"]) prod_offset = args.timeframeID else: - timestamp, prod_offset = determine_timestamp(run_start, run_end, [args.split_id - 1, args.prod_split], args.cycle, args.tf, GLOparams["OrbitsPerTF"]) + timestamp, prod_offset = determine_timestamp(effective_run_start, run_end, [args.split_id - 1, args.prod_split], args.cycle, args.tf, GLOparams["OrbitsPerTF"]) # determine orbit corresponding to timestamp (mainly used in exclude_timestamp function) orbit = GLOparams["FirstOrbit"] + int((timestamp - GLOparams["SOR"]) / ( LHCOrbitMUS / 1000)) # this is anchored to - print ("Determined start-of-run to be: ", run_start) + print ("Determined start-of-run to be: ", effective_run_start) print ("Determined end-of-run to be: ", run_end) print ("Determined timestamp to be : ", timestamp) print ("Determined offset to be : ", prod_offset) @@ -630,7 +649,7 @@ def main(): # However, the last passed argument wins, so they would be overwritten. If this should not happen, the option # needs to be handled as further below: energyarg = (" -eCM " + str(eCM)) if A1 == A2 else (" -eA " + str(eA) + " -eB " + str(eB)) - forwardargs += " -tf " + str(args.tf) + " --sor " + str(run_start) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " --run-anchored --first-orbit " \ + forwardargs += " -tf " + str(args.tf) + " --sor " + str(effective_run_start) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " --run-anchored --first-orbit " \ + str(GLOparams["FirstOrbit"]) + " --orbitsPerTF " + str(GLOparams["OrbitsPerTF"]) + " -col " + str(ColSystem) + str(energyarg) # the following options can be overwritten/influence from the outside if not '--readoutDets' in forwardargs: From 6d85da1988a55aa9e06967d5cb51a3bd8211199f Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Mon, 5 Jan 2026 10:41:55 +0100 Subject: [PATCH 197/362] Disable TPC timeseries when required detectors are missing Fixes https://its.cern.ch/jira/browse/O2-6586 --- MC/bin/o2dpg_sim_workflow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 412f7c8f5..aea495b48 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -2095,7 +2095,9 @@ def remove_json_prefix(path): TPCTStask['cmd'] += ' --primary-vertices ' TPCTStask['cmd'] += ' | o2-tpc-time-series-workflow --enable-unbinned-root-output --sample-unbinned-tsallis --sampling-factor 0.01 ' TPCTStask['cmd'] += putConfigValues() + ' ' + getDPL_global_options(bigshm=True) - workflow['stages'].append(TPCTStask) + if isActive('TOF') and isActive('TPC') and isActive('FT0'): + # could be relaxed or changed once the timerseries worklow is more reactive to input cluster- and track-types + workflow['stages'].append(TPCTStask) # cleanup # -------- From cca6b975fe46029e05c96826d2caa596c53a2968 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 15 Jan 2026 22:36:12 +0100 Subject: [PATCH 198/362] Add SITEARCHS for generic sites with AMD or NVIDIA GPUs and 8 cores --- .../configurations/asyncReco/async_pass.sh | 8 ++++++-- DATA/production/workflow-multiplicities.sh | 13 ++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index d2665a647..5e2729223 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -417,7 +417,7 @@ if [[ $ASYNC_PASS_NO_OPTIMIZED_DEFAULTS != 1 ]]; then if [[ $ALIEN_JDL_USEGPUS == 1 ]] ; then echo "Enabling GPUS" if [[ -z $ALIEN_JDL_SITEARCH ]]; then echo "ERROR: Must set ALIEN_JDL_SITEARCH to define GPU architecture!"; exit 1; fi - if [[ $ALIEN_JDL_SITEARCH == "NERSC" ]]; then # Disable mlock / ulimit / gpu memory registration - has performance impact, but doesn't work at NERSC for now + if [[ $ALIEN_JDL_SITEARCH == "NERSC" || $ALIEN_JDL_SITEARCH == "GENERIC_NVIDIA" || $ALIEN_JDL_SITEARCH == "GENERIC_AMD" ]]; then # Disable mlock / ulimit / gpu memory registration - has performance impact, but doesn't work at NERSC for now export SETENV_NO_ULIMIT=1 export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_proc.noGPUMemoryRegistration=1;" fi @@ -428,7 +428,11 @@ if [[ $ASYNC_PASS_NO_OPTIMIZED_DEFAULTS != 1 ]]; then elif [[ $ALIEN_JDL_SITEARCH == "EPN_MI50" ]]; then ALIEN_JDL_SITEARCH_TMP=EPN fi - if [[ "ALIEN_JDL_USEFULLNUMADOMAIN" == 0 ]]; then + if [[ $ALIEN_JDL_SITEARCH == "GENERIC_NVIDIA" ]]; then + export OPTIMIZED_PARALLEL_ASYNC=8cpu_NVIDIA + elif [[ $ALIEN_JDL_SITEARCH == "GENERIC_AMD" ]]; then + export OPTIMIZED_PARALLEL_ASYNC=8cpu_AMD + elif [[ "ALIEN_JDL_USEFULLNUMADOMAIN" == 0 ]]; then if [[ $keep -eq 0 ]]; then if [[ $ALIEN_JDL_UNOPTIMIZEDGPUSETTINGS != 1 ]]; then export OPTIMIZED_PARALLEL_ASYNC=pp_1gpu_${ALIEN_JDL_SITEARCH_TMP} # (16 cores, 1 gpu per job, pp) diff --git a/DATA/production/workflow-multiplicities.sh b/DATA/production/workflow-multiplicities.sh index 66879db68..cc6a2abcc 100644 --- a/DATA/production/workflow-multiplicities.sh +++ b/DATA/production/workflow-multiplicities.sh @@ -53,9 +53,20 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then [[ ! -z ${TIMEFRAME_RATE_LIMIT:-} ]] && unset TIMEFRAME_RATE_LIMIT [[ ! -z ${SHMSIZE:-} ]] && unset SHMSIZE fi - if [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu" ]]; then + if [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu" || $OPTIMIZED_PARALLEL_ASYNC == "8cpu_NVIDIA" || $OPTIMIZED_PARALLEL_ASYNC == "8cpu_AMD" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=3 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=16000000000 + if [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu_NVIDIA" ]]; then + NGPUS=1 + GPUTYPE=CUDA + GPUMEMSIZE=$((25 << 30)) + N_TPCTRK=$NGPUS + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu_AMD" ]]; then + NGPUS=1 + GPUTYPE=HIP + GPUMEMSIZE=$((25 << 30)) + N_TPCTRK=$NGPUS + fi NGPURECOTHREADS=5 if [[ $BEAMTYPE == "pp" ]]; then if (( $(echo "$RUN_IR > 800000" | bc -l) )); then From d1db8ef8edb2acd0968f87bffd065bb7a1a8e17e Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 16 Jan 2026 13:28:09 +0100 Subject: [PATCH 199/362] Included Hybrid generators testing + example (#2223) --- MC/config/common/ini/GeneratorPerformance.ini | 4 ++ .../common/ini/tests/GeneratorPerformance.C | 55 +++++++++++++++++++ test/README.md | 8 ++- test/run_generator_tests.sh | 2 +- 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 MC/config/common/ini/GeneratorPerformance.ini create mode 100644 MC/config/common/ini/tests/GeneratorPerformance.C diff --git a/MC/config/common/ini/GeneratorPerformance.ini b/MC/config/common/ini/GeneratorPerformance.ini new file mode 100644 index 000000000..c4a4efb03 --- /dev/null +++ b/MC/config/common/ini/GeneratorPerformance.ini @@ -0,0 +1,4 @@ +# Performance generator test using hybrid configuration with Pythia8 +# underlying event generator +[GeneratorHybrid] +configFile = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/perfConf.json diff --git a/MC/config/common/ini/tests/GeneratorPerformance.C b/MC/config/common/ini/tests/GeneratorPerformance.C new file mode 100644 index 000000000..c34ca7c5d --- /dev/null +++ b/MC/config/common/ini/tests/GeneratorPerformance.C @@ -0,0 +1,55 @@ +int Hybrid() +{ + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree 'o2sim' in file " << path << "\n"; + return 1; + } + // Get the MCTrack branch + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + // Check if processes with ID 42 are available + const int processID = 42; // Performance test particle custom process ID + int nEvents = tree->GetEntries(); + short int count_perf = 0; + bool flag = false; + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int nTracks = tracks->size(); + count_perf = 0; + for (auto &track : *tracks) + { + const auto &process = track.getProcess(); + if (process == processID) + { + flag = true; + // No need to continue checking other tracks in the event + break; + } + } + if (flag == true) + { + count_perf++; + flag = false; + } + } + if (count_perf == 0) + { + std::cerr << "No performance test particles found in the events\n"; + return 1; + } else if (count_perf > nEvents) { + std::cerr << "More performance test flagged events than generated events\n"; + return 1; + } + file.Close(); + return 0; +} \ No newline at end of file diff --git a/test/README.md b/test/README.md index 6745eae5b..7109e4e70 100644 --- a/test/README.md +++ b/test/README.md @@ -24,7 +24,7 @@ Whenever an `ini` file is detedcted to be tested, a test macro is required to be ```bash .C ``` -Note, that `run_tests.sh` will automatically detect all generators used in an `ini`. For at least one generator defined in the `ini` file there must be a test. Each test is defined as a function in the `.C` macro. Assuming you want to test `External` and `Pythia8` generator, the macro should look like +Note, that `run_tests.sh` will automatically detect all generators used in an `ini`. For at least one generator defined in the `ini` file there must be a test. Each test is defined as a function in the `.C` macro. Assuming you want to test `External`, `Pythia8` and `Hybrid` generators, the macro should look like ```cpp int pythia8() { @@ -37,6 +37,12 @@ int External() // do your test return ret; } + +int Hybrid() +{ + // do your test + return ret; +} ``` The return type must be an integer, `0` in case of success and `!=0` in case of failure. diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index 04443c528..579d0a696 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -21,7 +21,7 @@ export ROOT_INCLUDE_PATH LD_LIBRARY_PATH # Entrypoint for O2DPG related tests # ###################################### -CHECK_GENERATORS="pythia8 External" +CHECK_GENERATORS="pythia8 External Hybrid" # The test parent dir to be cretaed in current directory TEST_PARENT_DIR="o2dpg_tests/generators" From b664d2db335f6e908f28d94206227e8922f0f393 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Fri, 16 Jan 2026 21:56:25 +0900 Subject: [PATCH 200/362] Update to use the gap triggered production as default (#2233) * update to use the gap trigger * prevent none-input test --- .../PWGLF/ini/GeneratorLF_Resonances_PbPb.ini | 2 +- .../GeneratorLF_Resonances_PbPb_exotic.ini | 2 +- .../PWGLF/ini/GeneratorLF_Resonances_pp.ini | 2 +- .../ini/GeneratorLF_Resonances_pp1360.ini | 2 +- .../ini/GeneratorLF_Resonances_pp900.ini | 2 +- .../ini/GeneratorLF_Resonances_pp_exotic.ini | 2 +- .../GeneratorLF_Resonances_pp_exoticAll.ini | 2 +- .../pythia8/generator_pythia8_LF_rapidity.C | 339 +++++++++++------- 8 files changed, 218 insertions(+), 135 deletions(-) diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini index 529787320..4586b3bb3 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json", true, 4, true, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg") # [GeneratorPythia8] # config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini index fb7869c66..f5456c207 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4, true, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg") # [GeneratorPythia8] # config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini index 4ba2a3fd9..345433715 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini index 4ba2a3fd9..345433715 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini index a890a5531..86503c6ab 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg") # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini index 33ac0e832..f83430519 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini index 7ec78bb39..b02959589 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") # [GeneratorPythia8] # if triggered then this will be used as the background event # config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C index 12191584a..26c088b0e 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C @@ -3,17 +3,17 @@ /// \author Bong-Hwi Lim bong-hwi.lim@cern.ch /// \author Based on generator_pythia8_LF.C by Nicolò Jacazio /// \since 2025/08/18 -/// \brief Implementation of a gun generator for multiple particles using rapidity instead of eta, built on generator_pythia8_longlived.C -/// Needs PDG, Number of injected, minimum and maximum pT, minimum and maximum rapidity. These can be provided in three ways, bundeling variables, particles or from input file +/// \brief Implementation of a gun generator for multiple particles using rapidity or pseudorapidity (default) instead of eta, built on generator_pythia8_longlived.C +/// Needs PDG, Number of injected, minimum and maximum pT, minimum and maximum y/eta. These can be provided in three ways, bundeling variables, particles or from input file /// usage: /// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity({1000010020, 1000010030}, {10, 10}, {0.5, 0.5}, {10, 10}, {-1.0, -1.0}, {1.0, 1.0})'` -/// Here PDG, Number injected, pT limits, rapidity limits are separated and matched by index +/// Here PDG, Number injected, pT limits, y/eta limits are separated and matched by index /// or: /// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity({{1000010020, 10, 0.5, 10, -1.0, 1.0}, {1000010030, 10, 0.5, 10, -1.0, 1.0}})'` -/// Here PDG, Number injected, pT limits, rapidity limits are divided per particle +/// Here PDG, Number injected, pT limits, y/eta limits are divided per particle /// or: /// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun")'` -/// Here PDG, Number injected, pT limits, rapidity limits are provided via an intermediate configuration file +/// Here PDG, Number injected, pT limits, y/eta limits are provided via an intermediate configuration file /// #if !defined(__CLING__) || defined(__ROOTCLING__) @@ -58,41 +58,26 @@ using namespace Pythia8; using namespace o2::mcgenstatus; -// // Helper function to get mass from PDG code (copied from generator_pythia8_longlived.C to avoid include issues) -// namespace { -// double getMassFromPDG(int input_pdg) -// { -// double mass = 0; -// if (TDatabasePDG::Instance()) -// { -// TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg); -// if (particle) { -// mass = particle->Mass(); -// } else { -// LOG(warning) << "Unknown particle requested with PDG " << input_pdg << ", mass set to 0"; -// } -// } -// return mass; -// } -// } - class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 { public: /// Parametric constructor - GeneratorPythia8LFRapidity(bool injOnePerEvent /*= true*/, - int gapBetweenInjection /*= 0*/, - bool useTrigger /*= false*/, - std::string pythiaCfgMb /*= "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_minbias.cfg"*/, - std::string pythiaCfgSignal /*= "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_signal.cfg"*/) : GeneratorPythia8{}, - mOneInjectionPerEvent{injOnePerEvent}, - mGapBetweenInjection{gapBetweenInjection}, - mUseTriggering{useTrigger} + GeneratorPythia8LFRapidity(bool injOnePerEvent = true, + int gapBetweenInjection = 0, + bool useTrigger = false, + bool useRapidity = false, + std::string pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_minbias.cfg", + std::string pythiaCfgSignal = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_signal.cfg") : GeneratorPythia8{}, + mOneInjectionPerEvent{injOnePerEvent}, + mGapBetweenInjection{gapBetweenInjection}, + mUseTriggering{useTrigger}, + mUseRapidity{useRapidity} { LOG(info) << "GeneratorPythia8LFRapidity constructor"; LOG(info) << "++ mOneInjectionPerEvent: " << mOneInjectionPerEvent; LOG(info) << "++ mGapBetweenInjection: " << mGapBetweenInjection; LOG(info) << "++ mUseTriggering: " << mUseTriggering; + LOG(info) << "++ mUseRapidity: " << mUseRapidity; LOG(info) << "++ pythiaCfgMb: " << pythiaCfgMb; LOG(info) << "++ pythiaCfgSignal: " << pythiaCfgSignal; gRandom->SetSeed(0); @@ -119,20 +104,43 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 pythiaObjectMinimumBias.readString("Random:setSeed = on"); pythiaObjectMinimumBias.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); - if (!pythiaObjectMinimumBias.init()) { - LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; - } + // FIX: Init signal pythia object if (!pythiaObjectSignal.readFile(pythiaCfgSignal)) { LOG(fatal) << "Could not pythiaObjectSignal.readFile(\"" << pythiaCfgSignal << "\")"; } pythiaObjectSignal.readString("Random:setSeed = on"); pythiaObjectSignal.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + + if (!pythiaObjectMinimumBias.init()) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; + } if (!pythiaObjectSignal.init()) { LOG(fatal) << "Could not pythiaObjectSignal.init() from " << pythiaCfgSignal; } } else { // Using simple injection with internal decay (if needed). Fetching the parameters from the configuration file of the PythiaDecayer + + if (pythiaCfgMb == "") { // If no configuration file is provided, use the one from the Pythia8Param + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Instance LFRapidity \'Pythia8\' generator with following parameters for MB event"; + LOG(info) << param; + pythiaCfgMb = param.config; + } + // FIX: Fallback if still empty to default minbias + if (pythiaCfgMb == "") { + pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_minbias.cfg"; + } + pythiaCfgMb = gSystem->ExpandPathName(pythiaCfgMb.c_str()); + if (!pythiaObjectMinimumBias.readFile(pythiaCfgMb)) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.readFile(\"" << pythiaCfgMb << "\")"; + } + pythiaObjectMinimumBias.readString("Random:setSeed = on"); + pythiaObjectMinimumBias.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + if (!pythiaObjectMinimumBias.init()) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; + } + /** switch off process level **/ - mPythia.readString("ProcessLevel:all off"); + mPythiaGun.readString("ProcessLevel:all off"); /** config **/ auto& paramGen = o2::eventgen::GeneratorPythia8Param::Instance(); @@ -149,7 +157,7 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } std::string config = gSystem->ExpandPathName(param.config[i].c_str()); LOG(info) << "GeneratorPythia8LFRapidity Reading configuration from file: " << config; - if (!mPythia.readFile(config, true)) { + if (!mPythiaGun.readFile(config, true)) { LOG(fatal) << "Failed to init \'DecayerPythia8\': problems with configuration file " << config; return; @@ -158,13 +166,13 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 /** show changed particle data **/ if (param.showChanged) { - mPythia.readString(std::string("Init:showChangedParticleData on")); + mPythiaGun.readString(std::string("Init:showChangedParticleData on")); } else { - mPythia.readString(std::string("Init:showChangedParticleData off")); + mPythiaGun.readString(std::string("Init:showChangedParticleData off")); } /** initialise **/ - if (!mPythia.init()) { + if (!mPythiaGun.init()) { LOG(fatal) << "Failed to init \'DecayerPythia8\': init returned with error"; return; } @@ -180,19 +188,37 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 //__________________________________________________________________ Bool_t generateEvent() override { - if (!mUseTriggering) { // If the triggering is used we handle the the gap when generating the signal + if (!mUseTriggering) { // Injected mode: Embedding into MB + // 1. Generate Background (MB) + // LOG(info) << "Generating background event " << mEventCounter; + bool lGenerationOK = false; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; // Copy MB event to main event + + // 2. Determine if we inject specific particles (Gap logic) + bool doInjection = true; if (mGapBetweenInjection > 0) { if (mGapBetweenInjection == 1 && mEventCounter % 2 == 0) { - LOG(info) << "Skipping event " << mEventCounter; - return true; + doInjection = false; } else if (mEventCounter % mGapBetweenInjection != 0) { - LOG(info) << "Skipping event " << mEventCounter; - return true; + doInjection = false; } } + + if (!doInjection) { + LOG(info) << "Skipping injection for event " << mEventCounter; + return true; + } + } + + LOG(info) << "generateEvent (Injection) " << mEventCounter; + + // For Triggered mode, we start clean. For Injected mode, we have MB in mPythia.event + if (mUseTriggering) { + mPythia.event.reset(); } - LOG(info) << "generateEvent " << mEventCounter; - mPythia.event.reset(); mConfigToUse = mOneInjectionPerEvent ? static_cast(gRandom->Uniform(0.f, getNGuns())) : -1; LOG(info) << "Using configuration " << mConfigToUse << " out of " << getNGuns() << ", of which " << mGunConfigs.size() << " are transport decayed and " << mGunConfigsGenDecayed.size() << " are generator decayed"; @@ -206,7 +232,7 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } LOG(info) << "Using config container "; cfg.print(); - if (mUseTriggering) { // Do the triggering + if (mUseTriggering) { // Do the triggering bool doSignal{mEventCounter % (mGapBetweenInjection + 1) == 0}; // Do signal or gap if (doSignal) { @@ -218,13 +244,13 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 if (!pythiaObjectSignal.next()) { continue; } - // Check if triggered condition satisfied - using rapidity instead of eta - for (Long_t j = 0; j < pythiaObjectSignal.event.size(); j++) { + // Check if triggered condition satisfied + for (int j = 0; j < pythiaObjectSignal.event.size(); j++) { const int& pypid = pythiaObjectSignal.event[j].id(); - const float& pyrapidity = pythiaObjectSignal.event[j].y(); // Using rapidity (y) instead of eta + const float& pyeta = mUseRapidity ? pythiaObjectSignal.event[j].y() : pythiaObjectSignal.event[j].eta(); const float& pypt = pythiaObjectSignal.event[j].pT(); - if (pypid == cfg.mPdg && cfg.mRapidityMin < pyrapidity && pyrapidity < cfg.mRapidityMax && pypt > cfg.mPtMin && pypt < cfg.mPtMax) { - LOG(info) << "Found particle " << j << " " << pypid << " with rapidity " << pyrapidity << " and pT " << pypt << " in event " << mEventCounter << " after " << nTries << " tries"; + if (pypid == cfg.mPdg && cfg.mMin < pyeta && pyeta < cfg.mMax && pypt > cfg.mPtMin && pypt < cfg.mPtMax) { + LOG(info) << "Found particle " << j << " " << pypid << " with " << (mUseRapidity ? "rapidity" : "eta") << " " << pyeta << " and pT " << pypt << " in event " << mEventCounter << " after " << nTries << " tries"; satisfiesTrigger = true; break; } @@ -243,17 +269,31 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } continue; } - // Do the injection - using rapidity instead of eta + + // Do the injection + // Use mPythiaGun for separate generation and decay + mPythiaGun.event.reset(); for (int i{0}; i < cfg.mNInject; ++i) { const double pt = gRandom->Uniform(cfg.mPtMin, cfg.mPtMax); - const double rapidity = gRandom->Uniform(cfg.mRapidityMin, cfg.mRapidityMax); + const double eta = gRandom->Uniform(cfg.mMin, cfg.mMax); const double phi = gRandom->Uniform(0, TMath::TwoPi()); const double px{pt * std::cos(phi)}; const double py{pt * std::sin(phi)}; - // Convert rapidity to pz using the relation: pz = pt * sinh(rapidity) - const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); - const double pz{mT * std::sinh(rapidity)}; - const double et{mT * std::cosh(rapidity)}; // Energy E = mT * cosh(y) + + double pz = 0; + double et = 0; + + if (mUseRapidity) { + // Rapidty Case + const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); + pz = mT * std::sinh(eta); + et = mT * std::cosh(eta); + } else { + // Eta Case + pz = pt * std::sinh(eta); + const double p = pt * std::cosh(eta); + et = std::sqrt(p * p + cfg.mMass * cfg.mMass); + } Particle particle; particle.id(cfg.mPdg); @@ -266,22 +306,50 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 particle.xProd(0.f); particle.yProd(0.f); particle.zProd(0.f); - mPythia.particleData.mayDecay(cfg.mPdg, true); // force decay - mPythia.event.append(particle); + mPythiaGun.particleData.mayDecay(cfg.mPdg, true); // force decay + mPythiaGun.event.append(particle); } - injectedForThisEvent = true; - } - if (injectedForThisEvent) { - LOG(info) << "Calling next!"; - mPythia.moreDecays(); - mPythia.next(); - if (mPythia.event.size() <= 2) { - LOG(fatal) << "Event size is " << mPythia.event.size() << ", this is not good! Check that the decay actually happened or consider not using the generator decayed particles!"; - } else { - LOG(info) << "Event size is " << mPythia.event.size() << " particles"; + // Decay the gun particles + mPythiaGun.moreDecays(); + mPythiaGun.next(); + + // Merge mPythiaGun event into mPythia.event (MB) + int offset = mPythia.event.size(); + LOG(info) << "Merging " << mPythiaGun.event.size() - 1 << " injected particles into MB event of size " << offset; + + for (int i = 1; i < mPythiaGun.event.size(); ++i) { // Skip system particle 0 + Particle& p = mPythiaGun.event[i]; + // Adjust history indices + int mother1 = p.mother1(); + int mother2 = p.mother2(); + int daughter1 = p.daughter1(); + int daughter2 = p.daughter2(); + + if (mother1 > 0) + mother1 += offset - 1; + if (mother2 > 0) + mother2 += offset - 1; + if (daughter1 > 0) + daughter1 += offset - 1; + if (daughter2 > 0) + daughter2 += offset - 1; + + p.mothers(mother1, mother2); + p.daughters(daughter1, daughter2); + + mPythia.event.append(p); } + + injectedForThisEvent = true; } + // For purely trivial injection (no generator decay needed in loop or just transport decay), we still might have injection flag + // But above loop covers generator decayed. + // What if we only have Transport Decay particles? (mGunConfigs) + // We treat them in importParticles usually. + // But if we are in embedding mode, we just need to ensure the MB event is there. + // The mGunConfigs are handled in importParticles. + if (mVerbose) { LOG(info) << "Eventlisting"; mPythia.event.list(1); @@ -312,17 +380,26 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 if (mConfigToUse >= 0 && (nConfig - 1) != mConfigToUse) { continue; } - LOGF(info, "Injecting %i particles with PDG %i, pT in [%f, %f], rapidity in [%f, %f]", cfg.mNInject, cfg.mPdg, cfg.mPtMin, cfg.mPtMax, cfg.mRapidityMin, cfg.mRapidityMax); + LOGF(info, "Injecting %i particles with PDG %i, pT in [%f, %f], %s in [%f, %f]", cfg.mNInject, cfg.mPdg, cfg.mPtMin, cfg.mPtMax, (mUseRapidity ? "rapidity" : "eta"), cfg.mMin, cfg.mMax); for (int i{0}; i < cfg.mNInject; ++i) { const double pt = gRandom->Uniform(cfg.mPtMin, cfg.mPtMax); - const double rapidity = gRandom->Uniform(cfg.mRapidityMin, cfg.mRapidityMax); + const double eta = gRandom->Uniform(cfg.mMin, cfg.mMax); const double phi = gRandom->Uniform(0, TMath::TwoPi()); const double px{pt * std::cos(phi)}; const double py{pt * std::sin(phi)}; - const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); - const double pz{mT * std::sinh(rapidity)}; - const double et{mT * std::cosh(rapidity)}; + double pz = 0; + double et = 0; + + if (mUseRapidity) { + const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); + pz = mT * std::sinh(eta); + et = mT * std::cosh(eta); + } else { + pz = pt * std::sinh(eta); + const double p = pt * std::cosh(eta); + et = std::sqrt(p * p + cfg.mMass * cfg.mMass); + } // TParticle::TParticle(Int_t pdg, // Int_t status, @@ -347,7 +424,7 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 LOG(info) << "Printing particles that are appended"; int n = 0; for (const auto& p : mParticles) { - LOG(info) << "Particle " << n++ << " is a " << p.GetPdgCode() << " with status " << p.GetStatusCode() << " and px = " << p.Px() << " py = " << p.Py() << " pz = " << p.Pz(); + LOG(info) << "Particle " << n++ << " is a " << p.GetPdgCode() << " with status " << p.GetStatusCode() << " and px = " << p.Py() << " py = " << p.Py() << " pz = " << p.Pz(); } } return true; @@ -356,20 +433,20 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 struct ConfigContainer { ConfigContainer(int input_pdg = 0, int n = 1, float ptMin = 1, float ptMax = 10, - float rapidityMin = -1, float rapidityMax = 1) : mPdg{input_pdg}, - mNInject{n}, - mPtMin{ptMin}, - mPtMax{ptMax}, - mRapidityMin{rapidityMin}, - mRapidityMax{rapidityMax} + float min = -1, float max = 1) : mPdg{input_pdg}, + mNInject{n}, + mPtMin{ptMin}, + mPtMax{ptMax}, + mMin{min}, + mMax{max} { // mMass = getMassFromPDG(mPdg); mMass = GeneratorPythia8LongLivedGun::getMass(mPdg); if (mMass <= 0) { LOG(fatal) << "Could not find mass for mPdg " << mPdg; } - LOGF(info, "ConfigContainer: mPdg = %i, mNInject = %i, mPtMin = %f, mPtMax = %f, mRapidityMin = %f, mRapidityMax = %f, mMass = %f", - mPdg, mNInject, mPtMin, mPtMax, mRapidityMin, mRapidityMax, mMass); + LOGF(info, "ConfigContainer: mPdg = %i, mNInject = %i, mPtMin = %f, mPtMax = %f, mMin = %f, mMax = %f, mMass = %f", + mPdg, mNInject, mPtMin, mPtMax, mMin, mMax, mMass); }; ConfigContainer(TObjArray* arr) : ConfigContainer(atoi(arr->At(0)->GetName()), @@ -399,20 +476,20 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } }; ConfigContainer(TString line) : ConfigContainer(line.Tokenize(" ")){}; - ConfigContainer(const nlohmann::json& jsonParams) : ConfigContainer(jsonParams["pdg"], + ConfigContainer(const nlohmann::json& jsonParams, bool useRapidity = false) : ConfigContainer(jsonParams["pdg"], jsonParams["n"], jsonParams["ptMin"], jsonParams["ptMax"], - jsonParams["rapidityMin"], - jsonParams["rapidityMax"]){}; + (useRapidity && jsonParams.contains("rapidityMin")) ? jsonParams["rapidityMin"] : (jsonParams.contains("min") ? jsonParams["min"] : jsonParams["etaMin"]), + (useRapidity && jsonParams.contains("rapidityMax")) ? jsonParams["rapidityMax"] : (jsonParams.contains("max") ? jsonParams["max"] : jsonParams["etaMax"])){}; // Data Members const int mPdg = 0; const int mNInject = 1; const float mPtMin = 1; const float mPtMax = 10; - const float mRapidityMin = -1.f; - const float mRapidityMax = 1.f; + const float mMin = -1.f; + const float mMax = 1.f; double mMass = 0.f; void print() const @@ -421,36 +498,36 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 LOGF(info, "int mNInject = %i", mNInject); LOGF(info, "float mPtMin = %f", mPtMin); LOGF(info, "float mPtMax = %f", mPtMax); - LOGF(info, "float mRapidityMin = %f", mRapidityMin); - LOGF(info, "float mRapidityMax = %f", mRapidityMax); + LOGF(info, "float mMin = %f", mMin); + LOGF(info, "float mMax = %f", mMax); LOGF(info, "double mMass = %f", mMass); } }; //__________________________________________________________________ - ConfigContainer addGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float rapidityMin = 1, float rapidityMax = 10) + ConfigContainer addGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float min = 1, float max = 10) { if (mUseTriggering) { // If in trigger mode, every particle needs to be generated from pythia - return addGunGenDecayed(input_pdg, nInject, ptMin, ptMax, rapidityMin, rapidityMax); + return addGunGenDecayed(input_pdg, nInject, ptMin, ptMax, min, max); } - ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, rapidityMin, rapidityMax}; + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, min, max}; mGunConfigs.push_back(cfg); return cfg; } //__________________________________________________________________ - ConfigContainer addGun(ConfigContainer cfg) { return addGun(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mRapidityMin, cfg.mRapidityMax); } + ConfigContainer addGun(ConfigContainer cfg) { return addGun(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mMin, cfg.mMax); } //__________________________________________________________________ - ConfigContainer addGunGenDecayed(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float rapidityMin = 1, float rapidityMax = 10) + ConfigContainer addGunGenDecayed(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float min = 1, float max = 10) { - ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, rapidityMin, rapidityMax}; + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, min, max}; mGunConfigsGenDecayed.push_back(cfg); return cfg; } //__________________________________________________________________ - ConfigContainer addGunGenDecayed(ConfigContainer cfg) { return addGunGenDecayed(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mRapidityMin, cfg.mRapidityMax); } + ConfigContainer addGunGenDecayed(ConfigContainer cfg) { return addGunGenDecayed(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mMin, cfg.mMax); } //__________________________________________________________________ long int getNGuns() const { return mGunConfigs.size() + mGunConfigsGenDecayed.size(); } @@ -480,6 +557,7 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 const bool mOneInjectionPerEvent = true; // if true, only one injection per event is performed, i.e. if multiple PDG (including antiparticles) are requested to be injected only one will be done per event const bool mUseTriggering = false; // if true, use triggering instead of injection const int mGapBetweenInjection = 0; // Gap between two signal events. 0 means injection at every event + const bool mUseRapidity = false; // if true, use rapidity instead of eta // Running variables int mConfigToUse = -1; // Index of the configuration to use @@ -488,22 +566,23 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 std::vector mGunConfigs; // List of gun configurations to use std::vector mGunConfigsGenDecayed; // List of gun configurations to use that will be decayed by the generator - Pythia8::Pythia pythiaObjectSignal; // Signal collision generator - Pythia8::Pythia pythiaObjectMinimumBias; // Minimum bias collision generator + Pythia8::Pythia pythiaObjectSignal; // Signal collision generator + Pythia8::Pythia pythiaObjectMinimumBias; // Minimum bias collision generator + Pythia8::Pythia mPythiaGun; // Gun generator with decay support }; ///___________________________________________________________ /// Create generator via arrays of entries. By default injecting in every event and all particles -FairGenerator* generateLFRapidity(std::vector PDGs, std::vector nInject, std::vector ptMin, std::vector ptMax, std::vector rapidityMin, std::vector rapidityMax) +FairGenerator* generateLFRapidity(std::vector PDGs, std::vector nInject, std::vector ptMin, std::vector ptMax, std::vector min, std::vector max, bool useRapidity = false) { - const std::vector entries = {PDGs.size(), nInject.size(), ptMin.size(), ptMax.size(), rapidityMin.size(), rapidityMax.size()}; + const std::vector entries = {PDGs.size(), nInject.size(), ptMin.size(), ptMax.size(), min.size(), max.size()}; if (!std::equal(entries.begin() + 1, entries.end(), entries.begin())) { LOGF(fatal, "Not equal number of entries, check configuration"); return nullptr; } - GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(false, 0, false, "", ""); + GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(false, 0, false, useRapidity, "", ""); for (unsigned long i = 0; i < entries[0]; i++) { - multiGun->addGun(PDGs[i], nInject[i], ptMin[i], ptMax[i], rapidityMin[i], rapidityMax[i]); + multiGun->addGun(PDGs[i], nInject[i], ptMin[i], ptMax[i], min[i], max[i]); } return multiGun; } @@ -511,14 +590,15 @@ FairGenerator* generateLFRapidity(std::vector PDGs, std::vector nInjec ///___________________________________________________________ /// Create generator via an array of configurations FairGenerator* generateLFRapidity(std::vector cfg, - std::vector cfgGenDecayed, - bool injectOnePDGPerEvent = true, - int gapBetweenInjection = 0, - bool useTrigger = false, - std::string pythiaCfgMb = "", - std::string pythiaCfgSignal = "") + std::vector cfgGenDecayed, + bool injectOnePDGPerEvent = true, + int gapBetweenInjection = 0, + bool useTrigger = false, + bool useRapidity = false, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") { - GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(injectOnePDGPerEvent, gapBetweenInjection, useTrigger, pythiaCfgMb, pythiaCfgSignal); + GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(injectOnePDGPerEvent, gapBetweenInjection, useTrigger, useRapidity, pythiaCfgMb, pythiaCfgSignal); for (const auto& c : cfg) { LOGF(info, "Adding gun %i", multiGun->getNGuns()); c.print(); @@ -536,11 +616,12 @@ FairGenerator* generateLFRapidity(std::vectorExpandPathName(configuration.c_str()); LOGF(info, "Using configuration file '%s'", configuration.c_str()); @@ -558,9 +639,9 @@ FairGenerator* generateLFRapidity(std::string configuration = "${O2DPG_MC_CONFIG std::cout << param << std::endl; // cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{paramfile[n].template get(), param}); if (param["genDecayed"]) { - cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param}); + cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param, useRapidity}); } else { - cfgVec.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param}); + cfgVec.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param, useRapidity}); } } } else { @@ -584,21 +665,22 @@ FairGenerator* generateLFRapidity(std::string configuration = "${O2DPG_MC_CONFIG } } } - return generateLFRapidity(cfgVec, cfgVecGenDecayed, injectOnePDGPerEvent, gapBetweenInjection, useTrigger, pythiaCfgMb, pythiaCfgSignal); + return generateLFRapidity(cfgVec, cfgVecGenDecayed, injectOnePDGPerEvent, gapBetweenInjection, useTrigger, useRapidity, pythiaCfgMb, pythiaCfgSignal); } ///___________________________________________________________ /// Create generator via input file for the triggered mode FairGenerator* generateLFRapidityTriggered(std::string configuration = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun", - int gapBetweenInjection = 0, - std::string pythiaCfgMb = "", - std::string pythiaCfgSignal = "") + int gapBetweenInjection = 0, + bool useRapidity = false, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") { - return generateLFRapidity(configuration, /*injectOnePDGPerEvent=*/true, gapBetweenInjection, /*useTrigger=*/true, pythiaCfgMb, pythiaCfgSignal); + return generateLFRapidity(configuration, /*injectOnePDGPerEvent=*/true, gapBetweenInjection, /*useTrigger=*/true, useRapidity, pythiaCfgMb, pythiaCfgSignal); } ///___________________________________________________________ -void generator_pythia8_LF_rapidity(bool testInj = true, bool testTrg = false, const char* particleListFile = "cfg_rapidity.json") +void generator_pythia8_LF_rapidity(bool testInj = true, bool testTrg = false, bool useRapidity = false, const char* particleListFile = "cfg_rapidity.json") { LOG(info) << "Compiled correctly!"; if (!testInj && !testTrg) { @@ -607,7 +689,7 @@ void generator_pythia8_LF_rapidity(bool testInj = true, bool testTrg = false, co // Injected mode if (testInj) { LOG(info) << "Testing the injected mode"; - auto* gen = static_cast(generateLFRapidity(particleListFile)); + auto* gen = static_cast(generateLFRapidity(particleListFile, true, 0, false, useRapidity)); gen->setVerbose(); gen->Print(); gen->print(); @@ -620,9 +702,10 @@ void generator_pythia8_LF_rapidity(bool testInj = true, bool testTrg = false, co if (testTrg) { LOG(info) << "Testing the triggered mode"; GeneratorPythia8LFRapidity* gen = static_cast(generateLFRapidityTriggered(particleListFile, - /*gapBetweenInjection=*/0, - /*pythiaCfgMb=*/"inel136tev.cfg", - /*pythiaCfgSignal=*/"inel136tev.cfg")); + /*gapBetweenInjection=*/0, + useRapidity, + /*pythiaCfgMb=*/"inel136tev.cfg", + /*pythiaCfgSignal=*/"inel136tev.cfg")); gen->setVerbose(); gen->Print(); gen->print(); From 5dbd96c27cc7180078afe4c69d2414aa11dab038 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Sat, 17 Jan 2026 08:13:05 +0100 Subject: [PATCH 201/362] [PWGLF] Add generator for strangeness in jets (#2234) * [PWGLF] Add generator for strangeness in jets * replace primary with physical primary or from HF decays * added missing namespace qualifier * fix headers * fix selection of physical primary particles * remove redundant includes * change jet definition * fix typo --- .../GeneratorLF_StrangenessInJets_gap4.ini | 6 + .../GeneratorLF_StrangenessInJets_gap4.C | 27 +++ .../generator_pythia8_strangeness_in_jets.C | 192 ++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_StrangenessInJets_gap4.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_StrangenessInJets_gap4.C create mode 100644 MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_StrangenessInJets_gap4.ini b/MC/config/PWGLF/ini/GeneratorLF_StrangenessInJets_gap4.ini new file mode 100644 index 000000000..80b0235b8 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_StrangenessInJets_gap4.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C +funcName = generateStrangenessInJets(10.0,0.4,4) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_StrangenessInJets_gap4.C b/MC/config/PWGLF/ini/tests/GeneratorLF_StrangenessInJets_gap4.C new file mode 100644 index 000000000..12f069f3c --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_StrangenessInJets_gap4.C @@ -0,0 +1,27 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nXi = tree->Scan("MCTrack.GetPdgCode()", "TMath::Abs(MCTrack.GetPdgCode()) == 3312"); + auto nOmega = tree->Scan("MCTrack.GetPdgCode()", "TMath::Abs(MCTrack.GetPdgCode()) == 3334"); + auto nStr = nXi+nOmega; + + if (nStr == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C b/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C new file mode 100644 index 000000000..8075d27cb --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C @@ -0,0 +1,192 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include "TSystem.h" +#include "TVector2.h" +#include "fairlogger/Logger.h" +#include +#include +#include +#include +using namespace Pythia8; +#endif + +/// Event generator using Pythia ropes for Ξ and Ω production in jets. +/// Jets are defined as particles within a cone around the highest-pT particle +/// (approximate jet axis) and include charged final-state particles that are +/// either physical primaries or from heavy-flavor decays. +/// Jets must be fully within the acceptance and have pT > 10 GeV. +/// One event of interest is generated after 4 minimum-bias events. + +class GeneratorPythia8StrangenessInJet : public o2::eventgen::GeneratorPythia8 { +public: + /// Constructor + GeneratorPythia8StrangenessInJet(double ptJetMin = 10.0, double Rjet = 0.4, int gapSize = 4) + : o2::eventgen::GeneratorPythia8(), + mptJetMin(ptJetMin), + mRjet(Rjet), + mGapSize(gapSize) + { + fmt::printf( + ">> Pythia8 generator: Xi/Omega inside jets with pt_{jet} > %.1f GeV, R_{jet} = %.1f, gap = %d\n", + ptJetMin, Rjet, gapSize); + } + /// Destructor + ~GeneratorPythia8StrangenessInJet() = default; + + bool Init() override { + addSubGenerator(0, "Pythia8 events with Xi/Omega inside jets"); + return o2::eventgen::GeneratorPythia8::Init(); + } + +protected: + /// Check if particle is physical primary or from HF decay + bool isPhysicalPrimaryOrFromHF(const Pythia8::Particle& p, const Pythia8::Event& event) + { + // Select only final-state particles + if (!p.isFinal()) { + return false; + } + + // Particle species selection + const int absPdg = std::abs(p.id()); + if (absPdg!=211 && absPdg!=321 && absPdg!= 2212 && absPdg!=1000010020 && absPdg!=11 && absPdg!=13) + return false; + + // Walk up ancestry + int motherId = p.mother1(); + + while (motherId > 0) { + + // Get mother + const auto& mother = event[motherId]; + const int absMotherPdg = std::abs(mother.id()); + + // Check if particle is from HF decay + if ((absMotherPdg / 100 == 4) || (absMotherPdg / 100 == 5) || (absMotherPdg / 1000 == 4) || (absMotherPdg / 1000 == 5)) { + return true; + } + + // Reject non-physical primary hadrons + if (mother.isHadron() && mother.tau0() > 1.0) { + return false; + } + motherId = mother.mother1(); + } + return true; + } + + // Compute delta phi + double getDeltaPhi(double a1, double a2) + { + double deltaPhi{0.0}; + double phi1 = TVector2::Phi_0_2pi(a1); + double phi2 = TVector2::Phi_0_2pi(a2); + double diff = std::fabs(phi1 - phi2); + + if (diff <= M_PI) + deltaPhi = diff; + if (diff > M_PI) + deltaPhi = 2.0 * M_PI - diff; + + return deltaPhi; + } + + bool generateEvent() override { + fmt::printf(">> Generating event %d\n", mGeneratedEvents); + + bool genOk = false; + int localCounter{0}; + constexpr int kMaxTries{100000}; + + // Accept mGapSize events unconditionally, then one triggered event + if (mGeneratedEvents % (mGapSize + 1) < mGapSize) { + genOk = GeneratorPythia8::generateEvent(); + fmt::printf(">> Gap-trigger accepted event (no strangeness check)\n"); + } else { + while (!genOk && localCounter < kMaxTries) { + if (GeneratorPythia8::generateEvent()) { + genOk = selectEvent(mPythia.event); + } + localCounter++; + } + if (!genOk) { + fmt::printf("Failed to generate triggered event after %d tries\n",kMaxTries); + return false; + } + fmt::printf(">> Event accepted after %d iterations (Xi/Omega in jet)\n", localCounter); + } + + notifySubGenerator(0); + mGeneratedEvents++; + return true; + } + + bool selectEvent(Pythia8::Event &event) { + + double etaJet{-999.0}, phiJet{-999.0}, ptMax{0.0}; + std::vector particleID; + bool containsXiOrOmega{false}; + + for (int i = 0; i < event.size(); i++) { + const auto& p = event[i]; + if (std::abs(p.id()) == 3312 || std::abs(p.id()) == 3334) + containsXiOrOmega = true; + + if (std::abs(p.eta()) > 0.8 || p.pT() < 0.1) continue; + if (!isPhysicalPrimaryOrFromHF(p, event)) continue; + particleID.emplace_back(i); + + if (p.pT() > ptMax) { + ptMax = p.pT(); + etaJet = p.eta(); + phiJet = p.phi(); + } + } + if (ptMax == 0.0) + return false; + if (std::abs(etaJet) + mRjet > 0.8) + return false; + if (!containsXiOrOmega) + return false; + + double ptJet{0.0}; + for (int i = 0 ; i < particleID.size() ; i++) { + int id = particleID[i]; + const auto& p = event[id]; + + double deltaEta = std::abs(p.eta() - etaJet); + double deltaPhi = getDeltaPhi(p.phi(),phiJet); + double deltaR = std::sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); + if (deltaR < mRjet) { + ptJet += p.pT(); + } + } + if (ptJet < mptJetMin) + return false; + + return true; + } + +private: + double mptJetMin{10.0}; + double mRjet{0.4}; + int mGapSize{4}; + uint64_t mGeneratedEvents{0}; +}; + +///___________________________________________________________ +FairGenerator *generateStrangenessInJets(double ptJet = 10.0, double rJet = 0.4, int gap = 4) { + + auto myGenerator = new GeneratorPythia8StrangenessInJet(ptJet,rJet,gap); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGenerator->readString("Random:setSeed on"); + myGenerator->readString("Random:seed " + std::to_string(seed)); + return myGenerator; +} From ccc4ad69e4141d1990d019e688a4ef206521cb50 Mon Sep 17 00:00:00 2001 From: Francesca Ercolessi Date: Mon, 19 Jan 2026 15:33:41 +0100 Subject: [PATCH 202/362] Add generator for LambdaB to deuteron (#2237) * add generator for LambdaB to deuteron * Update MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini Co-authored-by: Fabrizio * Update MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C Co-authored-by: Fabrizio --------- Co-authored-by: Fabrizio --- .../GeneratorHFTrigger_LambdaBToDeuteron.ini | 7 ++ .../GeneratorHFTrigger_LambdaBToDeuteron.C | 57 ++++++++++++++ .../generator/pythia8_lambdab_probQQtoQ.cfg | 76 +++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini new file mode 100644 index 000000000..fab061515 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini @@ -0,0 +1,7 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C +funcName=generateHFHadToNuclei(3, {5122}, {1000010020}, true, 0.5) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C new file mode 100644 index 000000000..3df607574 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C @@ -0,0 +1,57 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector checkPdgHadron{5122}; // Lambda_b + std::vector nucleiDauPdg{1000010020}; // d, 3He, 3H + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) // found signal + { + // count signal PDG + if(std::abs(track.GetRapidity()) > 1.5) continue; // skip if outside rapidity window + nSignals++; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + if (std::find(nucleiDauPdg.begin(), nucleiDauPdg.end(), std::abs(pdgDau)) != nucleiDauPdg.end()) + { + nSignalGoodDecay++; + } + } + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying into nuclei: " << nSignalGoodDecay << "\n"; + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.2 + uncFracForcedDecays) // we put some tolerance (lambdaB in MB events do not coalesce) + { + std::cerr << "Fraction of signals decaying into nuclei: " << fracForcedDecays << ", lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg new file mode 100644 index 000000000..58acb17c4 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg @@ -0,0 +1,76 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +# enable deuteron production by coalescence collisions +HadronLevel:DeuteronProduction = on +DeuteronProduction:channels = {2212 2112 > 22} +DeuteronProduction:models = {0} +DeuteronProduction:norm = 1 +DeuteronProduction:parms = {0.5 1} # coalescence momentum p0 in GeV/c + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +#StringFlav:probQQtoQ 0.078 +StringFlav:probQQtoQ 0.17 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +## Lb decay modes +5122:onMode = off +5122:oneChannel = 1 9.03e-05 0 2212 2212 -2212 -2212 2112 +5122:addChannel = 1 0.00181 0 2212 2212 -2212 -2212 2112 111 +5122:addChannel = 1 0.0181 0 2212 2212 -2212 -2212 2112 111 111 +5122:addChannel = 1 0.0271 0 2212 2212 -2212 -2212 2112 211 -211 +5122:addChannel = 1 0.0181 0 2212 2212 -2212 -2212 2112 211 211 -211 -211 +5122:addChannel = 1 0.181 0 2212 2212 -2212 -2212 2112 211 -211 111 +5122:addChannel = 1 0.199 0 2212 2212 -2212 -2212 2112 211 -211 111 111 +5122:addChannel = 1 0.0271 0 2212 2212 -2212 -2212 2112 211 211 -211 -211 111 +5122:addChannel = 1 0.00452 0 2212 2212 -2212 -2212 2112 211 111 +5122:addChannel = 1 0.0361 0 2212 2212 2112 -2212 -2112 -211 111 +5122:addChannel = 1 0.0452 0 2212 2212 2112 -2212 -2112 -211 111 111 +5122:addChannel = 1 0.0542 0 2212 2212 2112 -2212 -2112 -211 -211 211 +5122:addChannel = 1 0.361 0 2212 2212 2112 -2212 -2112 -211 -211 211 111 +5122:addChannel = 1 0.0271 0 2212 2212 2112 -2212 -2112 -211 -211 211 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 +5122:onIfMatch = 2212 2212 2212 2212 2112 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 211 211 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 211 211 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 111 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 111 111 From 7f111934b79c6db8c101dd8abbb7191f89eecb94 Mon Sep 17 00:00:00 2001 From: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:56:49 +0100 Subject: [PATCH 203/362] Adding generators for non-prompt charmonia in light ions (#2235) * Adding generators for non-prompt charmonia in light ions * Adding mid-y and test files --------- Co-authored-by: Maurice Coquet --- ...hia8_NonPromptSignals_OO_gaptriggered_dq.C | 312 ++++++++++++++++++ ...hia8_NonPromptSignals_pO_gaptriggered_dq.C | 312 ++++++++++++++++++ ...bbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini | 15 + ...bar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini | 15 + ...bbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini | 15 + ...bar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini | 15 + ..._bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C | 93 ++++++ ...bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C | 93 ++++++ ..._bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C | 92 ++++++ ...bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C | 92 ++++++ .../pythia8/generator/pythia8_hf_OO_536.cfg | 19 ++ .../pythia8/generator/pythia8_hf_pO_961.cfg | 19 ++ 12 files changed, 1092 insertions(+) create mode 100644 MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C create mode 100644 MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C create mode 100644 MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini create mode 100644 MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini create mode 100644 MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini create mode 100644 MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini create mode 100644 MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C create mode 100644 MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C create mode 100644 MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C create mode 100644 MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C create mode 100644 MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg create mode 100644 MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C new file mode 100644 index 000000000..bacf31747 --- /dev/null +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C @@ -0,0 +1,312 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) +#include "GeneratorEvtGen.C" + +#include + +using namespace o2::eventgen; + +namespace o2 +{ +namespace eventgen +{ + +class GeneratorPythia8NonPromptInjectedOOGapTriggeredDQ : public o2::eventgen::GeneratorPythia8 { +public: + + /// constructor + GeneratorPythia8NonPromptInjectedOOGapTriggeredDQ(int inputTriggerRatio = 5) { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + // define minimum bias event generator + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg"); + pythiaMBgen.readFile(pathconfigMB.Data()); + pythiaMBgen.readString("Random:setSeed on"); + pythiaMBgen.readString("Random:seed " + std::to_string(seed)); + mConfigMBdecays = ""; + mPDG = 5; + mRapidityMin = -1.; + mRapidityMax = 1.; + mHadronMultiplicity = -1; + mHadronRapidityMin = -1.; + mHadronRapidityMax = 1.; + mVerbose = false; + } + + /// Destructor + ~GeneratorPythia8NonPromptInjectedOOGapTriggeredDQ() = default; + + void setPDG(int val) { mPDG = val; }; + void addHadronPDGs(int pdg) { mHadronsPDGs.push_back(pdg); }; + void setHadronMultiplicity(int val) { mHadronMultiplicity = val; }; + void setRapidity(double valMin, double valMax) + { + mRapidityMin = valMin; + mRapidityMax = valMax; + }; + + void setRapidityHadron(double valMin, double valMax) + { + mHadronRapidityMin = valMin; + mHadronRapidityMax = valMax; + }; + + void setConfigMBdecays(TString val){mConfigMBdecays = val;} + + void setVerbose(bool val) { mVerbose = val; }; + +protected: + +Bool_t generateEvent() override + { + // reset event + bool genOk = false; + if (mGeneratedEvents % mInverseTriggerRatio == 0){ + bool ancestor = false; + while (! (genOk && ancestor) ){ + /// reset event + mPythia.event.reset(); + genOk = GeneratorPythia8::generateEvent(); + // find the q-qbar ancestor + ancestor = findHeavyQuarkPair(mPythia.event); + } + } else { + /// reset event + pythiaMBgen.event.reset(); + while (!genOk) { + genOk = pythiaMBgen.next(); + } + mPythia.event = pythiaMBgen.event; + } + mGeneratedEvents++; + if (mVerbose) mOutputEvent.list(); + return true; + } + +Bool_t Init() override + { + if(mConfigMBdecays.Contains("cfg")) pythiaMBgen.readFile(mConfigMBdecays.Data()); + GeneratorPythia8::Init(); + pythiaMBgen.init(); + return true; + } + + // search for q-qbar mother with at least one q in a selected rapidity window + bool findHeavyQuarkPair(Pythia8::Event& event) + { + int countH[mHadronsPDGs.size()]; for(int ipdg=0; ipdg < mHadronsPDGs.size(); ipdg++) countH[ipdg]=0; + bool hasq = false, hasqbar = false, atSelectedY = false, isOkAtPartonicLevel = false; + for (int ipa = 0; ipa < event.size(); ++ipa) { + + if(!isOkAtPartonicLevel){ + auto daughterList = event[ipa].daughterList(); + hasq = false; hasqbar = false; atSelectedY = false; + for (auto ida : daughterList) { + if (event[ida].id() == mPDG) + hasq = true; + if (event[ida].id() == -mPDG) + hasqbar = true; + if ((event[ida].y() > mRapidityMin) && (event[ida].y() < mRapidityMax)) + atSelectedY = true; + } + if (hasq && hasqbar && atSelectedY) isOkAtPartonicLevel = true; + } + + if( (mHadronMultiplicity <= 0) && isOkAtPartonicLevel) return true; // no selection at hadron level + + /// check at hadron level if needed + int ipdg=0; + for (auto& pdgVal : mHadronsPDGs){ + if ( (TMath::Abs(event[ipa].id()) == pdgVal) && (event[ipa].y() > mHadronRapidityMin) && (event[ipa].y() < mHadronRapidityMax) ) countH[ipdg]++; + if(isOkAtPartonicLevel && countH[ipdg] >= mHadronMultiplicity) return true; + ipdg++; + } + } + return false; + }; + + +private: +// Interface to override import particles +Pythia8::Event mOutputEvent; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + Pythia8::Pythia pythiaMBgen; // minimum bias event + TString mConfigMBdecays; + int mPDG; + std::vector mHadronsPDGs; + int mHadronMultiplicity; + double mRapidityMin; + double mRapidityMax; + double mHadronRapidityMin; + double mHadronRapidityMax; + bool mVerbose; + }; + +} + +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenMidY_OO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(-1.5,1.5); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenMidY_OO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenFwdY_OO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_OO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C new file mode 100644 index 000000000..f4aab2fea --- /dev/null +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C @@ -0,0 +1,312 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) +#include "GeneratorEvtGen.C" + +#include + +using namespace o2::eventgen; + +namespace o2 +{ +namespace eventgen +{ + +class GeneratorPythia8NonPromptInjectedpOGapTriggeredDQ : public o2::eventgen::GeneratorPythia8 { +public: + + /// constructor + GeneratorPythia8NonPromptInjectedpOGapTriggeredDQ(int inputTriggerRatio = 5) { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + // define minimum bias event generator + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg"); + pythiaMBgen.readFile(pathconfigMB.Data()); + pythiaMBgen.readString("Random:setSeed on"); + pythiaMBgen.readString("Random:seed " + std::to_string(seed)); + mConfigMBdecays = ""; + mPDG = 5; + mRapidityMin = -1.; + mRapidityMax = 1.; + mHadronMultiplicity = -1; + mHadronRapidityMin = -1.; + mHadronRapidityMax = 1.; + mVerbose = false; + } + + /// Destructor + ~GeneratorPythia8NonPromptInjectedpOGapTriggeredDQ() = default; + + void setPDG(int val) { mPDG = val; }; + void addHadronPDGs(int pdg) { mHadronsPDGs.push_back(pdg); }; + void setHadronMultiplicity(int val) { mHadronMultiplicity = val; }; + void setRapidity(double valMin, double valMax) + { + mRapidityMin = valMin; + mRapidityMax = valMax; + }; + + void setRapidityHadron(double valMin, double valMax) + { + mHadronRapidityMin = valMin; + mHadronRapidityMax = valMax; + }; + + void setConfigMBdecays(TString val){mConfigMBdecays = val;} + + void setVerbose(bool val) { mVerbose = val; }; + +protected: + +Bool_t generateEvent() override + { + // reset event + bool genOk = false; + if (mGeneratedEvents % mInverseTriggerRatio == 0){ + bool ancestor = false; + while (! (genOk && ancestor) ){ + /// reset event + mPythia.event.reset(); + genOk = GeneratorPythia8::generateEvent(); + // find the q-qbar ancestor + ancestor = findHeavyQuarkPair(mPythia.event); + } + } else { + /// reset event + pythiaMBgen.event.reset(); + while (!genOk) { + genOk = pythiaMBgen.next(); + } + mPythia.event = pythiaMBgen.event; + } + mGeneratedEvents++; + if (mVerbose) mOutputEvent.list(); + return true; + } + +Bool_t Init() override + { + if(mConfigMBdecays.Contains("cfg")) pythiaMBgen.readFile(mConfigMBdecays.Data()); + GeneratorPythia8::Init(); + pythiaMBgen.init(); + return true; + } + + // search for q-qbar mother with at least one q in a selected rapidity window + bool findHeavyQuarkPair(Pythia8::Event& event) + { + int countH[mHadronsPDGs.size()]; for(int ipdg=0; ipdg < mHadronsPDGs.size(); ipdg++) countH[ipdg]=0; + bool hasq = false, hasqbar = false, atSelectedY = false, isOkAtPartonicLevel = false; + for (int ipa = 0; ipa < event.size(); ++ipa) { + + if(!isOkAtPartonicLevel){ + auto daughterList = event[ipa].daughterList(); + hasq = false; hasqbar = false; atSelectedY = false; + for (auto ida : daughterList) { + if (event[ida].id() == mPDG) + hasq = true; + if (event[ida].id() == -mPDG) + hasqbar = true; + if ((event[ida].y() > mRapidityMin) && (event[ida].y() < mRapidityMax)) + atSelectedY = true; + } + if (hasq && hasqbar && atSelectedY) isOkAtPartonicLevel = true; + } + + if( (mHadronMultiplicity <= 0) && isOkAtPartonicLevel) return true; // no selection at hadron level + + /// check at hadron level if needed + int ipdg=0; + for (auto& pdgVal : mHadronsPDGs){ + if ( (TMath::Abs(event[ipa].id()) == pdgVal) && (event[ipa].y() > mHadronRapidityMin) && (event[ipa].y() < mHadronRapidityMax) ) countH[ipdg]++; + if(isOkAtPartonicLevel && countH[ipdg] >= mHadronMultiplicity) return true; + ipdg++; + } + } + return false; + }; + + +private: +// Interface to override import particles +Pythia8::Event mOutputEvent; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + Pythia8::Pythia pythiaMBgen; // minimum bias event + TString mConfigMBdecays; + int mPDG; + std::vector mHadronsPDGs; + int mHadronMultiplicity; + double mRapidityMin; + double mRapidityMax; + double mHadronRapidityMin; + double mHadronRapidityMax; + bool mVerbose; + }; + +} + +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenMidY_pO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(-1.5,1.5); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenMidY_pO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenFwdY_pO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_pO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini new file mode 100644 index 000000000..a76404bb9 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_OO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-4.3,-2.3) + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini new file mode 100644 index 000000000..1e4c5b84e --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_pO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-4.3,-2.3) + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini new file mode 100644 index 000000000..8643e68d6 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenMidY_OO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-1.5,1.5) + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini new file mode 100644 index 000000000..ca57f2515 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenMidY_pO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-1.5,1.5) + diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C new file mode 100644 index 000000000..d68eb1bcf --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C @@ -0,0 +1,93 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C new file mode 100644 index 000000000..d68eb1bcf --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C @@ -0,0 +1,93 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C new file mode 100644 index 000000000..8a0964910 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C @@ -0,0 +1,92 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C new file mode 100644 index 000000000..8a0964910 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C @@ -0,0 +1,92 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg new file mode 100644 index 000000000..c2f4e063d --- /dev/null +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg @@ -0,0 +1,19 @@ +### OO beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +Random:setSeed = on + +### processes +HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg new file mode 100644 index 000000000..4a1b25f2e --- /dev/null +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg @@ -0,0 +1,19 @@ +### OO beams +Beams:frameType 2 # back-to-back beams of different energies and particles +Beams:idA 2212 # proton +Beams:idB 1000080160 # Oxygen +Beams:eA 6800. # Energy of proton beam in GeV moving in the +z direction +Beams:eB 3400. # Energy in GeV per Oxygen nucleon (6.8 Z TeV) moving in the -z direction + +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.17,17.56,0.30 + +Random:setSeed = on + +### processes +HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar From fd0475090109fd0f69028a7d697bd1782ed15bd4 Mon Sep 17 00:00:00 2001 From: Ravindra Singh <56298081+singhra1994@users.noreply.github.com> Date: Tue, 20 Jan 2026 09:28:02 +0100 Subject: [PATCH 204/362] Change useIsGoodZvtxFT0vsPV to false (#2230) --- .../json/dpl/o2-analysis-hf-candidate-creator-2prong.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json index 16db4aa70..d45ab8eb0 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json @@ -21,7 +21,7 @@ "useTvxTrigger": "false", "useTimeFrameBorderCut": "false", "useItsRofBorderCut": "false", - "useIsGoodZvtxFT0vsPV": "true", + "useIsGoodZvtxFT0vsPV": "false", "useNoSameBunchPileup": "true", "useOccupancyCut": "false", "occEstimator": "1", From 57aa0467b27590eb1d9cc4eb2de55d81c2ad0059 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 20 Jan 2026 16:26:05 +0100 Subject: [PATCH 205/362] rawTF2raw: fix typo in rawTF2raw converter script --- UTILS/rawTF2raw/generate_rawtf_indices.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UTILS/rawTF2raw/generate_rawtf_indices.sh b/UTILS/rawTF2raw/generate_rawtf_indices.sh index e68a9ffb3..49a32e4e5 100644 --- a/UTILS/rawTF2raw/generate_rawtf_indices.sh +++ b/UTILS/rawTF2raw/generate_rawtf_indices.sh @@ -24,10 +24,10 @@ print_help() { - param1: rawtf input file list - param2: output directory - param3: number of TFs to process - - param4: tfCounter id of first TF to process + - param4: tfCounter id of first TF to process - param5: number of Blocks to be expected per TF to select only TFs with all inputs / detectors present - if number of inputs is irrelevant, it can be set to 0 to be ignored - + Example usage: source $O2DPG_ROOT/UTILS/rawTF2raw/generate_rawtf_indices.sh rawtflist_LHC25ab_563041.txt 2025-05-19-pp-750khz-replay-LHC25ab-563041 125 3500 14 @@ -81,7 +81,7 @@ sort_tfs() { fi firstTFtmp=${firstTF} while true; do - firstLine=$(grep -nr tfCounter:${firstTFtmp} ${tfs_sorted} | awk -F ':' '{print $1}') + firstLine=$(grep -nr "tfCounter:${firstTFtmp} " ${tfs_sorted} | awk -F ':' '{print $1}') [[ ! -z ${firstLine} ]] && break firstTFtmp=$((firstTFtmp+1)) done From 0d76211e5de336f13fe4126664ef92d79d6c82a4 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 20 Jan 2026 09:17:05 +0100 Subject: [PATCH 206/362] qc-workflow.sh: fix missing TOF clusters input if using only global tracks for K0 QC --- DATA/common/gen_topo_helper_functions.sh | 5 +++++ DATA/production/qc-workflow.sh | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/DATA/common/gen_topo_helper_functions.sh b/DATA/common/gen_topo_helper_functions.sh index e24b8553c..c868411b2 100755 --- a/DATA/common/gen_topo_helper_functions.sh +++ b/DATA/common/gen_topo_helper_functions.sh @@ -59,6 +59,11 @@ has_secvtx_source() [[ $SVERTEXING_SOURCES =~ (^|,)"ALL"(,|$) ]] || [[ $SVERTEXING_SOURCES =~ (^|,)"$1"(,|$) ]] } +has_detector_in_secvtx_sources() +{ + [[ $SVERTEXING_SOURCES =~ (^|,)"ALL"(,|$) ]] || [[ $SVERTEXING_SOURCES =~ (^|,|-)"$1"(-|,|$) ]] +} + has_detector_qc() { has_detector $1 && [[ $WORKFLOW_DETECTORS_QC =~ (^|,)"$1"(,|$) ]] diff --git a/DATA/production/qc-workflow.sh b/DATA/production/qc-workflow.sh index 245389a76..62a35622e 100755 --- a/DATA/production/qc-workflow.sh +++ b/DATA/production/qc-workflow.sh @@ -310,9 +310,9 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then ITSTPCMatchQuery+=";matchTPCTRDTOF/TOF/MTC_TPCTRD/0" TRACKSOURCESK0+=",TPC-TRD-TOF" fi - if has_secvtx_source TOF; then + if has_detector_in_secvtx_sources TOF; then ITSTPCMatchQuery+=";tofcluster:TOF/CLUSTERS/0" - TRACKSOURCESK0+=",TOF" + has_secvtx_source TOF && TRACKSOURCESK0+=",TOF" fi if has_secvtx_source TRD; then TRACKSOURCESK0+=",TRD" From 0deec05aed87bf16a5861d44bab6cbc8691801c6 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 20 Jan 2026 10:16:13 +0100 Subject: [PATCH 207/362] gen_topo: fix exporting gen_topo tmp dir when debugging topology generation --- DATA/tools/epn/gen_topo_o2dpg.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DATA/tools/epn/gen_topo_o2dpg.sh b/DATA/tools/epn/gen_topo_o2dpg.sh index d67b7381a..217ddba21 100755 --- a/DATA/tools/epn/gen_topo_o2dpg.sh +++ b/DATA/tools/epn/gen_topo_o2dpg.sh @@ -24,10 +24,10 @@ if [[ -z "$DDSHMSIZE" ]]; then echo \$DDSHMSIZE missing; exit 1; fi # SHM Size f # In case of debug mode, overwrite some settings if [[ "${DEBUG_TOPOLOGY_GENERATION:=0}" == "1" ]]; then echo "Debugging mode enabled. Setting options accordingly" 1>&2 - RECO_NUM_NODES_OVERRIDE=1 # to avoid slurm query, specify number of nodes to fixed value - GEN_TOPO_MI100_NODES=1 # also for MI100 nodes - GEN_TOPO_OVERRIDE_TEMPDIR=$PWD # keep temporary files like QC jsons in local directory - EPN2EOS_METAFILES_DIR=/tmp # nothing is written here, just needs to be set to something + export RECO_NUM_NODES_OVERRIDE=1 # to avoid slurm query, specify number of nodes to fixed value + export GEN_TOPO_MI100_NODES=1 # also for MI100 nodes + export GEN_TOPO_OVERRIDE_TEMPDIR=$PWD # keep temporary files like QC jsons in local directory + export EPN2EOS_METAFILES_DIR=/tmp # nothing is written here, just needs to be set to something unset ECS_ENVIRONMENT_ID unset GEN_TOPO_CACHE_HASH fi From db9759bfe44a311cbe7553eb145c7ad63fdd60cc Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 14 Jan 2026 08:23:41 +0100 Subject: [PATCH 208/362] Change requireIsGoodZvtxFT0VsPV value to false for K0s QC To suppress the missing slewing calibration for FT0 during QC passes in 25. --- .../json/dpl/o2-analysis-perf-k0s-resolution.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json b/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json index ba0c8142b..5bf02b5bd 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json @@ -80,7 +80,7 @@ "rejectITSROFBorder": "1", "rejectTFBorder": "1", "requireIsVertexITSTPC": "0", - "requireIsGoodZvtxFT0VsPV": "1", + "requireIsGoodZvtxFT0VsPV": "0", "requireIsVertexTOFmatched": "0", "requireIsVertexTRDmatched": "0", "rejectSameBunchPileup": "1", From e6b7007d4468d973520ad24113ab265616170384 Mon Sep 17 00:00:00 2001 From: RuiqiYin <25110190115@m.fudan.edu.cn> Date: Wed, 21 Jan 2026 16:51:39 +0800 Subject: [PATCH 209/362] Add replacement config to generator_pythia8 to replace D*/Sigmac+ by Xic0/Omegac0 (#2186) --------- Co-authored-by: Fabrizio Grosa --- .../generator/generator_pythia8_embed_hf.C | 34 +-- .../generator_pythia8_gaptriggered_hf.C | 15 +- ...orHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini | 9 + ..._D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini | 2 +- ...bar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini | 2 +- .../ini/tests/GeneratorHFTrigger_Bforced.C | 5 +- .../GeneratorHFTrigger_LambdaBToNuclei.C | 5 +- .../ini/tests/GeneratorHFTrigger_bbbar.C | 5 +- .../ini/tests/GeneratorHFTrigger_ccbar.C | 5 +- ...GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C | 5 +- .../GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C | 5 +- .../GeneratorHF_D2H_bbbar_Mode2_OmegaC.C | 5 +- ...GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C | 5 +- .../ini/tests/GeneratorHF_D2H_bbbar_gap5.C | 5 +- .../GeneratorHF_D2H_ccbar_Mode2_OmegaC.C | 5 +- ...GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C | 5 +- ...rHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C | 7 +- .../GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C | 5 +- ...ratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C | 5 +- ...orHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C | 5 +- ...atorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C | 210 ++++++++++++++++++ ...ratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C | 5 +- ...ratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C | 5 +- .../GeneratorHF_D2H_ccbar_and_bbbar_gap3.C | 5 +- ...neratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C | 5 +- ...torHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C | 5 +- .../GeneratorHF_D2H_ccbar_and_bbbar_gap5.C | 5 +- ...neratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C | 5 +- ...HF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C | 15 +- ...neratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C | 5 +- ..._ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C | 5 +- ...and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C | 5 +- ...torHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C | 5 +- ...2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C | 5 +- ...F_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C | 5 +- ...ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C | 23 +- ...HF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C | 5 +- .../GeneratorHF_D2H_ccbar_and_bbbar_gap8.C | 5 +- ...torHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C | 5 +- .../ini/tests/GeneratorHF_D2H_ccbar_gap5.C | 5 +- ...ic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg | 156 +++++++++++++ 41 files changed, 520 insertions(+), 108 deletions(-) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C index 423c4509e..7a28d631a 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C @@ -10,6 +10,7 @@ using namespace Pythia8; +#include namespace hf_generators { enum GenType : int { @@ -35,7 +36,13 @@ public: //} /// Destructor - ~GeneratorPythia8EmbedHF() = default; + ~GeneratorPythia8EmbedHF() { + // Clean up the internally created HF generator if any + if (mGeneratorEvHF) { + delete mGeneratorEvHF; + mGeneratorEvHF = nullptr; + } + } /// Init bool Init() override @@ -51,29 +58,30 @@ public: /// \param yHadronMin minimum hadron rapidity /// \param yHadronMax maximum hadron rapidity /// \param hadronPdgList list of PDG codes for hadrons to be used in trigger - void setupGeneratorEvHF(int genType, bool usePtHardBins, float yQuarkMin, float yQuarkMax, float yHadronMin, float yHadronMax, std::vector hadronPdgList = {}) { + /// \param quarkPdgList list of PDG codes for quarks to be enriched in the trigger + void setupGeneratorEvHF(int genType, bool usePtHardBins, float yQuarkMin, float yQuarkMax, float yHadronMin, float yHadronMax, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { mGeneratorEvHF = nullptr; switch (genType) { case hf_generators::GapTriggeredCharm: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredCharm **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharm(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharm(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; case hf_generators::GapTriggeredBeauty: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredBeauty **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; case hf_generators::GapTriggeredCharmAndBeauty: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredCharmAndBeauty **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharmAndBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharmAndBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; case hf_generators::GapHF: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapHF **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapHF(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; default: LOG(fatal) << "********** [GeneratorPythia8EmbedHF] bad configuration, fix it! **********"; @@ -111,7 +119,7 @@ public: LOG(info) << "[notifyEmbedding] ----- Collision impact parameter: " << x; /// number of events to be embedded in a background event - mNumSigEvs = 5 + 0.886202881*std::pow(std::max(0.0f, 17.5f - x),1.7); + mNumSigEvs = static_cast(std::lround(5.0 + 0.886202881 * std::pow(std::max(0.0f, 17.5f - x), 1.7))); LOG(info) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std::endl; }; @@ -380,34 +388,34 @@ private: }; // Charm enriched -FairGenerator * GeneratorPythia8EmbedHFCharm(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator * GeneratorPythia8EmbedHFCharm(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { auto myGen = new GeneratorPythia8EmbedHF(); /// setup the internal generator for HF events - myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharm, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList); + myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharm, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, quarkPdgList, hadronPdgList, partPdgToReplaceList, freqReplaceList); return myGen; } // Beauty enriched -FairGenerator * GeneratorPythia8EmbedHFBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator * GeneratorPythia8EmbedHFBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { auto myGen = new GeneratorPythia8EmbedHF(); /// setup the internal generator for HF events - myGen->setupGeneratorEvHF(hf_generators::GapTriggeredBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList); + myGen->setupGeneratorEvHF(hf_generators::GapTriggeredBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, quarkPdgList, hadronPdgList, partPdgToReplaceList, freqReplaceList); return myGen; } // Charm and beauty enriched (with same ratio) -FairGenerator * GeneratorPythia8EmbedHFCharmAndBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator * GeneratorPythia8EmbedHFCharmAndBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { auto myGen = new GeneratorPythia8EmbedHF(); /// setup the internal generator for HF events - myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharmAndBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList); + myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharmAndBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, quarkPdgList, hadronPdgList, partPdgToReplaceList, freqReplaceList); return myGen; } diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C index cdf472096..8d5060251 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -258,17 +258,14 @@ protected: bool replaceParticle(int iPartToReplace, int pdgCodeNew) { - auto mothers = mPythia.event[iPartToReplace].motherList(); - - std::array pdgDiquarks = {1103, 2101, 2103, 2203, 3101, 3103, 3201, 3203, 3303, 4101, 4103, 4201, 4203, 4301, 4303, 4403, 5101, 5103, 5201, 5203, 5301, 5303, 5401, 5403, 5503}; - - for (auto const& mother: mothers) { - auto pdgMother = std::abs(mPythia.event[mother].id()); - if (pdgMother > 100 && std::find(pdgDiquarks.begin(), pdgDiquarks.end(), pdgMother) == pdgDiquarks.end()) { - return false; - } + // Check status code: particles with status 91-99 come from decays and should not be replaced + int statusMother = std::abs(mPythia.event[iPartToReplace].status()); + if (statusMother >= 91 && statusMother <= 99) { + return false; } + auto mothers = mPythia.event[iPartToReplace].motherList(); + int charge = mPythia.event[iPartToReplace].id() / std::abs(mPythia.event[iPartToReplace].id()); float px = mPythia.event[iPartToReplace].px(); float py = mPythia.event[iPartToReplace].py(); diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini new file mode 100644 index 000000000..e0cd149eb --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C +funcName=GeneratorPythia8EmbedHFCharmAndBeauty(false, -1.5, 1.5, -1.5, 1.5, std::vector{}, std::vector{}, std::vector>{{423,4132},{423,4232},{4212,4332}}, std::vector{0.5,0.5,1}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini index 93c74daa2..4ec024367 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini @@ -1,4 +1,4 @@ -#NEV_TEST> 20 +#NEV_TEST> 40 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini index 8dd04bc87..f7f3307bc 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini @@ -1,4 +1,4 @@ -#NEV_TEST> 20 +#NEV_TEST> 40 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C index c3cb9bcfb..7f0eca77f 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C @@ -90,8 +90,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.75) // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.3 + uncFracForcedDecays) // we put some tolerance (e.g. due to oscillations which might change the final state) { std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToNuclei.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToNuclei.C index 18a7dff79..be1ef1b56 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToNuclei.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToNuclei.C @@ -45,8 +45,9 @@ int External() std::cout <<"# signal hadrons: " << nSignals << "\n"; std::cout <<"# signal hadrons decaying into nuclei: " << nSignalGoodDecay << "\n"; - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.8) // we put some tolerance (lambdaB in MB events do not coalesce) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.2 + uncFracForcedDecays) // we put some tolerance (lambdaB in MB events do not coalesce) { std::cerr << "Fraction of signals decaying into nuclei: " << fracForcedDecays << ", lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C index d67a9b48d..05a465e6d 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C @@ -82,8 +82,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) // we put some tolerance (e.g. due to oscillations which might change the final state) { std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C index 234b51bbe..22863be41 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C @@ -82,8 +82,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.85) // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) // we put some tolerance (e.g. due to oscillations which might change the final state) { std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C index b5264c370..629aa3ae1 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C @@ -105,8 +105,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.85) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.3 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C index 36019e022..07f70bfd7 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C @@ -105,8 +105,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.85) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C index e55bb2709..d4c8fdf56 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C @@ -95,8 +95,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C index f2c79c2ad..27591c842 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C @@ -106,8 +106,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C index 7fb3eacb6..9d4e1574e 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C @@ -102,8 +102,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.7) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C index 081dfecae..5734e02da 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C @@ -95,8 +95,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C index e2f818fb2..17987c9a0 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C @@ -106,8 +106,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C index 11cb92fc3..4a3fba732 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C @@ -123,13 +123,14 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } - if (averagePt < 6.5) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) + if (averagePt < 6) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) std::cerr << "Average pT of charmed hadrons " << averagePt << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C index d3f861f24..0edd85513 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C @@ -181,8 +181,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C index 4437bf04f..be57a1439 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C @@ -172,8 +172,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C index d3f861f24..0edd85513 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C @@ -181,8 +181,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C new file mode 100644 index 000000000..ac01f2afc --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C @@ -0,0 +1,210 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + //std::string path{"tf1/sgn_Kine.root"}; + + // Particle replacement configuration: {original, replacement}, frequencies + std::array, 3> pdgReplParticles = { + std::array{423, 4132}, // D*0 -> Xic0 + std::array{423, 4232}, // D*0 -> Xic+ + std::array{4212, 4332} // Sigmac+ -> Omegac0 + }; + std::array, 3> pdgReplPartCounters = { + std::array{0, 0}, + std::array{0, 0}, + std::array{0, 0} + }; + std::array freqRepl = {0.5, 0.5, 1.0}; + std::map sumOrigReplacedParticles = {{423, 0}, {4212, 0}}; + + // Signal hadrons to check (only final charm baryons after replacement) + std::array checkPdgHadron{4122, 4132, 4232, 4332}; + + // Expected decay channels - will be sorted automatically + // Define both particle and antiparticle versions + std::map>> checkHadronDecaysRaw{ + // Λc+ decays (from cfg: 4122:addChannel + resonance decays) + {4122, { + {2212, 311}, {-2212, -311}, // p K0s + {2212, -321, 211}, {-2212, 321, -211}, // p K- π+ (non-resonant) + {2212, 313}, {-2212, -313}, // p K*0 (not decayed) + {2212, 321, 211}, {-2212, -321, -211}, // p K*0 -> p (K- π+) [K*0 decayed] + {2224, -321}, {-2224, 321}, // Delta++ K- (not decayed) + {2212, 211, -321}, {-2212, -211, 321}, // Delta++ K- -> (p π+) K- [Delta decayed] + {102134, 211}, {-102134, -211}, // Lambda(1520) π+ (not decayed) + {2212, 321, 211}, {-2212, -321, -211}, // Lambda(1520) π+ -> (p K-) π+ [Lambda* decayed] + {2212, -321, 211, 111}, {-2212, 321, -211, 111}, // p K- π+ π0 + {2212, -211, 211}, {-2212, 211, -211}, // p π- π+ (cfg line 61: 2212 -211 211) + {2212, 333}, {-2212, 333}, // p φ (not decayed) + {2212, 321, -321}, {-2212, -321, 321} // p φ -> p (K+ K-) [φ decayed] + }}, + // Ξc0 decays (from cfg: 4132:onIfMatch) + {4132, { + {3312, 211}, {-3312, -211}, // Ξ- π+ + {3334, 321}, {-3334, -321} // Ω- K+ + }}, + // Ξc+ decays (from cfg: 4232:onIfMatch + resonance decays) + {4232, { + {2212, -321, 211}, {-2212, 321, -211}, // p K- π+ + {2212, -313}, {-2212, 313}, // p K̄*0 (not decayed) + {2212, -321, 211}, {-2212, 321, -211}, // p K̄*0 -> p (K+ π-) [K*0 decayed] + {2212, 333}, {-2212, 333}, // p φ (not decayed) + {2212, 321, -321}, {-2212, -321, 321}, // p φ -> p (K+ K-) [φ decayed] + {3222, -211, 211}, {-3222, 211, -211}, // Σ+ π- π+ + {3324, 211}, {-3324, -211}, // Ξ*0 π+ + {3312, 211, 211}, {-3312, -211, -211} // Ξ- π+ π+ + }}, + // Ωc0 decays (from cfg: 4332:onIfMatch) + {4332, { + {3334, 211}, {-3334, -211}, // Ω- π+ + {3312, 211}, {-3312, -211}, // Ξ- π+ + {3334, 321}, {-3334, -321} // Ω- K+ + }} + }; + + // Sort all decay channels + std::map>> checkHadronDecays; + for (auto &[pdg, decays] : checkHadronDecaysRaw) { + for (auto decay : decays) { + std::sort(decay.begin(), decay.end()); + checkHadronDecays[pdg].push_back(decay); + } + } + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nSignals{}, nSignalGoodDecay{}; + std::map failedDecayCount{{4122, 0}, {4132, 0}, {4232, 0}, {4332, 0}}; + std::map>> unknownDecays; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + auto absPdg = std::abs(pdg); + + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) + { + nSignals++; // count signal PDG + + // Count replacement particles (single-match per track) + int matchedIdx = -1; + bool matchedIsReplacement = false; + for (int iRepl{0}; iRepl < 3; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { + matchedIdx = iRepl; + matchedIsReplacement = false; + break; + } + if (absPdg == pdgReplParticles[iRepl][1]) { + matchedIdx = iRepl; + matchedIsReplacement = true; + break; + } + } + if (matchedIdx >= 0) { + if (matchedIsReplacement) { + pdgReplPartCounters[matchedIdx][1]++; + } else { + pdgReplPartCounters[matchedIdx][0]++; + } + // Count the original-particle population once for this matched group + sumOrigReplacedParticles[pdgReplParticles[matchedIdx][0]]++; + } + + // Collect decay products + std::vector pdgsDecay{}; + if (track.getFirstDaughterTrackId() >= 0 && track.getLastDaughterTrackId() >= 0) { + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + + // Check if decay matches expected channels + bool foundMatch = false; + for (auto &decay : checkHadronDecays[absPdg]) { + if (pdgsDecay == decay) { + nSignalGoodDecay++; + foundMatch = true; + break; + } + } + + // Record failed decays for debugging + if (!foundMatch && pdgsDecay.size() > 0) { + failedDecayCount[absPdg]++; + unknownDecays[absPdg].insert(pdgsDecay); + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# signal charm baryons: " << nSignals << "\n"; + std::cout << "# signal charm baryons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + // Print failed decay statistics + std::cout << "\nFailed decay counts:\n"; + for (auto &[pdg, count] : failedDecayCount) { + if (count > 0) { + std::cout << "PDG " << pdg << ": " << count << " failed decays\n"; + std::cout << " Unknown decay channels (first 5):\n"; + int printed = 0; + for (auto &decay : unknownDecays[pdg]) { + if (printed++ >= 5) break; + std::cout << " ["; + for (size_t i = 0; i < decay.size(); ++i) { + std::cout << decay[i]; + if (i < decay.size()-1) std::cout << ", "; + } + std::cout << "]\n"; + } + } + } + std::cout << "\n"; + + std::cout << "# D*0 (original): " << pdgReplPartCounters[0][0] << "\n"; + std::cout << "# Xic0 (replaced from D*0): " << pdgReplPartCounters[0][1] << "\n"; + std::cout << "# Xic+ (replaced from D*0): " << pdgReplPartCounters[1][1] << "\n"; + std::cout << "# Sigmac+ (original): " << pdgReplPartCounters[2][0] << "\n"; + std::cout << "# Omegac0 (replaced from Sigmac+): " << pdgReplPartCounters[2][1] << "\n"; + + // Check forced decay fraction + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + std::cout << "# fraction of signals decaying into the correct channel: " << fracForcedDecays + << " (" << fracForcedDecays * 100.0f << "%)\n"; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // 85% threshold with tolerance + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + // Check particle replacement ratios (2-sigma statistical compatibility) + for (int iRepl{0}; iRepl<6; ++iRepl) { + float numPart = sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; + float fracMeas = numPart ? float(pdgReplPartCounters[iRepl][1]) / numPart : 0.0f; + float fracMeasUnc = fracMeas ? std::sqrt(pdgReplPartCounters[iRepl][1]) / numPart : 1.0f; + + if (std::abs(fracMeas - freqRepl[iRepl]) > fracMeasUnc) { + std::cerr << "Fraction of replaced " << pdgReplParticles[iRepl][0] << " into " << pdgReplParticles[iRepl][1] << " is " << fracMeas <<" (expected "<< freqRepl[iRepl] << ")\n"; + return 1; + } + } + + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C index 5cc0e18e6..07c5f8837 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C @@ -179,8 +179,9 @@ int External(std::string path = "o2sim_Kine.root") { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C index 5cc0e18e6..07c5f8837 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C @@ -179,8 +179,9 @@ int External(std::string path = "o2sim_Kine.root") { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C index d29245b32..10f9b8ccb 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C @@ -118,8 +118,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C index 5735c969d..3d5a21e0b 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C @@ -170,8 +170,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.85) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C index c99426354..9d6cbac69 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C @@ -112,8 +112,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C index e5c0bf08d..f36c8a02f 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C @@ -118,8 +118,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C index 3c1cfd492..ed1021a5d 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C @@ -130,8 +130,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C index f70d958d5..702c1ddad 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C @@ -124,18 +124,19 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } for (int iRepl{0}; iRepl<6; ++iRepl) { - if (std::abs(pdgReplPartCounters[iRepl][1] - freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]) > 2 * std::sqrt(freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]])) { // 2 sigma compatibility - float fracMeas = 0.; - if (sumOrigReplacedParticles[pdgReplParticles[iRepl][0]] > 0.) { - fracMeas = float(pdgReplPartCounters[iRepl][1]) / sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; - } + float numPart = sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; + float fracMeas = numPart ? float(pdgReplPartCounters[iRepl][1]) / numPart : 0.0f; + float fracMeasUnc = (fracMeas && numPart != 1) ? std::sqrt(pdgReplPartCounters[iRepl][1]) / numPart : 1.0f; + + if (std::abs(fracMeas - freqRepl[iRepl]) > fracMeasUnc) { std::cerr << "Fraction of replaced " << pdgReplParticles[iRepl][0] << " into " << pdgReplParticles[iRepl][1] << " is " << fracMeas <<" (expected "<< freqRepl[iRepl] << ")\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C index 73ca51134..3f348adb3 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C @@ -180,8 +180,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C index e8a678315..951f38df2 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C @@ -128,8 +128,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C index 9e8456fad..ad9f15bfe 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C @@ -179,8 +179,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C index b9b398cfe..2c56754d6 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C @@ -112,8 +112,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C index 909ba4ccb..ab13f5c41 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C @@ -113,8 +113,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C index eeb37acfc..0b40d30fd 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C @@ -170,8 +170,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.8) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C index 31aba24ad..e6622a0fa 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C @@ -199,23 +199,22 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.5) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.5 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } - for (int iRepl{0}; iRepl<2; ++iRepl) { - - std::cout << " --- pdgReplPartCounters[" << iRepl << "][1] = " << pdgReplPartCounters[iRepl][1] << ", freqRepl[" << iRepl <<"] = " << freqRepl[iRepl] << ", sumOrigReplacedParticles[pdgReplParticles[" << iRepl << "][0]] = " << sumOrigReplacedParticles[pdgReplParticles[iRepl][0]] << std::endl; - - if (std::abs(pdgReplPartCounters[iRepl][1] - freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]) > 2 * std::sqrt(freqRepl[iRepl] * sumOrigReplacedParticles[pdgReplParticles[iRepl][0]])) { // 2 sigma compatibility - float fracMeas = 0.; - if (sumOrigReplacedParticles[pdgReplParticles[iRepl][0]] > 0.) { - fracMeas = float(pdgReplPartCounters[iRepl][1]) / sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; - } + // Check particle replacement ratios + for (int iRepl{0}; iRepl < 3; ++iRepl) { + float numPart = sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; + float fracMeas = numPart ? float(pdgReplPartCounters[iRepl][1]) / numPart : 0.0f; + float fracMeasUnc = (fracMeas && numPart != 1) ? std::sqrt(pdgReplPartCounters[iRepl][1]) / numPart : 1.0f; + + if (std::abs(fracMeas - freqRepl[iRepl]) > fracMeasUnc) { std::cerr << "Fraction of replaced " << pdgReplParticles[iRepl][0] << " into " << pdgReplParticles[iRepl][1] << " is " << fracMeas <<" (expected "<< freqRepl[iRepl] << ")\n"; - return 1; + return 1; } } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C index 6f13ae05e..a6f9ed435 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C @@ -180,8 +180,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C index b6828e205..b4a723630 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C @@ -118,8 +118,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C index 596639d12..4e143c055 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C @@ -112,8 +112,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C index 99a039e6f..38cc604cc 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C @@ -101,8 +101,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg new file mode 100644 index 000000000..84ac21536 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg @@ -0,0 +1,156 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Ruiqi Yin (ruiqi.yin@cern.ch) +### last update: October 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes: c-cbar and b-bbar processes +HardQCD:hardccbar on +HardQCD:hardbbbar on +HardQCD:gg2ccbar on +HardQCD:qqbar2ccbar on +HardQCD:gg2bbbar on +HardQCD:qqbar2bbbar on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force charm baryon decay modes (Ξc and Ωc) +### D mesons use default PYTHIA8 branching ratios + +## Λc decays (optional, can be kept for reference) +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 + +### add OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +# Allow the decay of resonances in the decay chain (only for charm baryons) +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 +### for Λc -> p K*0(892) +313:onMode = off +313:onIfAll = 321 211 +### for Λc -> p phi +333:onMode = off +333:onIfAll = 321 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +3122:onMode = off +3122:onIfAll = 2212 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 + +# Switch off charm baryon decay channels (D mesons use PYTHIA8 defaults) +4122:onMode = off +4232:onMode = off +4132:onMode = off +4332:onMode = off + +# Allow the decay of charm baryons +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 +### Xic0 -> Omega- Ka+ +4132:onIfMatch = 3334 321 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 +### Omega_c -> Omega- Ka+ +4332:onIfMatch = 3334 321 \ No newline at end of file From 3cd6b38126aebfa31edc8fca5286b6bda7c01ffe Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Wed, 21 Jan 2026 19:09:14 +0100 Subject: [PATCH 210/362] Less demanding version of GeneratorPythia8POWHEG_jetjet_13600.ini (#2241) --- .../powheg/powheg_jetjet_13600_mini.input | 90 +++++++++++++++++++ ...neratorPythia8POWHEG_jetjet_13600_mini.ini | 11 +++ 2 files changed, 101 insertions(+) create mode 100755 MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input create mode 100644 MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600_mini.ini diff --git a/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input new file mode 100755 index 000000000..e151c10d9 --- /dev/null +++ b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input @@ -0,0 +1,90 @@ +numevts 10 ! number of events to be generated +ih1 1 ! hadron 1 (1 for protons, -1 for antiprotons) +ih2 1 ! hadron 2 (1 for protons, -1 for antiprotons) +ebeam1 6800d0 ! energy of beam 1 +ebeam2 6800d0 ! energy of beam 2 + +bornktmin 10d0 ! (default 0d0) Generation cut: minimum kt in underlying Born +bornsuppfact 120d0 ! (default 0d0) Mass parameter for Born suppression factor. + ! If < 0 suppfact = 1. + + +! To be set only if using internal (mlm) pdfs +! 131 cteq6m +! ndns1 131 ! pdf set for hadron 1 (mlm numbering) +! ndns2 131 ! pdf set for hadron 2 (mlm numbering) + +! To be set only if using LHA pdfs +! 10050 cteq6m +! 10550 cteq66 +! 13100 CT14nlo +! 14400 CT18nlo +lhans1 14400 ! pdf set for hadron 1 (LHA numbering) +lhans2 14400 ! pdf set for hadron 2 (LHA numbering) + +! To be set only if using different pdf sets for the two incoming hadrons +# QCDLambda5 0.25 ! for not equal pdf sets + +#renscfact 1d0 ! (default 1d0) ren scale factor: muren = muref * renscfact +#facscfact 1d0 ! (default 1d0) fac scale factor: mufact = muref * facscfact + +! Parameters to allow or not the use of stored data +use-old-grid 1 ! If 1 use old grid if file pwggrids.dat is present (<> 1 regenerate) +use-old-ubound 1 ! If 1 use norm of upper bounding function stored + ! in pwgubound.dat, if present; <> 1 regenerate + +! A typical call uses 1/1400 seconds (1400 calls per second) +ncall1 20000 ! No. calls for the construction of the importance sampling grid +itmx1 5 ! No. iterations for grid: total 100000 calls ~ 70 seconds +ncall2 10000 ! No. calls for the computation of the upper bounding + ! envelope for the generation of radiation +itmx2 3 ! No. iterations for the above + +! Notice: the total number of calls is ncall2*itmx2*foldcsi*foldy*foldphi +! these folding numbers yield a negative fraction of 0.5% with bornktmin=10 GeV. +! With these settings: ncall2*itmx2*foldcsi*foldy*foldphi=5M, 60 minutes +foldcsi 2 ! No. folds on csi integration +foldy 2 ! No. folds on y integration +foldphi 1 ! No. folds on phi integration + +nubound 100000 ! No. calls to set up the upper bounding norms for radiation. + ! This is performed using only the Born cross section (fast) + +! OPTIONAL PARAMETERS + +withnegweights 0 ! (default 0). If 1 use negative weights. +#bornonly 1 ! (default 0). If 1 compute underlying Born using LO + ! cross section only. + +#ptsqmin 0.8 ! (default 0.8 GeV) minimum pt for generation of radiation +#charmthr 1.5 ! (default 1.5 GeV) charm treshold for gluon splitting +#bottomthr 5.0 ! (default 5.0 GeV) bottom treshold for gluon splitting +#testplots 1 ! (default 0, do not) do NLO and PWHG distributions +#charmthrpdf 1.5 ! (default 1.5 GeV) pdf charm treshold +#bottomthrpdf 5.0 ! (default 5.0 GeV) pdf bottom treshold + +#xupbound 2d0 ! increase upper bound for radiation generation + +#iseed 5421 ! Start the random number generator with seed iseed +#rand1 0 ! skipping rand2*100000000+rand1 numbers (see RM48 +#rand2 0 ! short writeup in CERNLIB). +#manyseeds 1 ! Used to perform multiple runs with different random + ! seeds in the same directory. + ! If set to 1, the program asks for an integer j; + ! The file pwgseeds.dat at line j is read, and the + ! integer at line j is used to initialize the random + ! sequence for the generation of the event. + ! The event file is called pwgevents-'j'.lhe + +doublefsr 1 ! Default 0; if 1 use new mechanism to generate regions + ! such that the emitted harder than the + ! emitter in FSR is suppressed. If doublefsr=0 this is + ! only the case for emitted gluons (old behaviour). If + ! 1 it is also applied to emitted quarks. + ! If set, it strongly reduces spikes on showered output. + + + +par_diexp 4 ! default is 2. With 4 there is a stronger separation +par_dijexp 4 ! of regions, it may help to reduce spikes when generating +par_2gsupp 4 ! weighted events. diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600_mini.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600_mini.ini new file mode 100644 index 000000000..7cedd849e --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600_mini.ini @@ -0,0 +1,11 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +## The option '3' which is given to getGeneratorJEPythia8POWHEG selects the pwhg_main_dijet process +## This is a less computing intensive alternative to the original GeneratorPythia8POWHEG_jetjet_13600.ini. It keeps the event generation close to 5 minutes +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input","",3) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg From 8b165c56afa6d4a386a03ea0e730a9ab1a1cabfc Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 23 Jan 2026 09:57:28 +0100 Subject: [PATCH 211/362] MC/PWGEM: add cfg and init for vm2ll in pp/PbPb (#2244) --- .../PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini | 10 ++++ .../PWGEM/ini/pythia8_pp_13600_VM2ll.ini | 10 ++++ MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini | 10 ++++ .../PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C | 56 +++++++++++++++++++ .../PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C | 56 +++++++++++++++++++ .../PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C | 56 +++++++++++++++++++ .../generator/pythia8_PbPb_5360_VM2ll.cfg | 23 ++++++++ .../generator/pythia8_pp_13600_VM2ll.cfg | 23 ++++++++ .../generator/pythia8_pp_5360_VM2ll.cfg | 23 ++++++++ 9 files changed, 267 insertions(+) create mode 100644 MC/config/PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini create mode 100644 MC/config/PWGEM/ini/pythia8_pp_13600_VM2ll.ini create mode 100644 MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini create mode 100644 MC/config/PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C create mode 100644 MC/config/PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C create mode 100644 MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini new file mode 100644 index 000000000..503e77188 --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_13600_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_pp_13600_VM2ll.ini new file mode 100644 index 000000000..e261498c4 --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_13600_VM2ll.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini new file mode 100644 index 000000000..49be058cf --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C new file mode 100644 index 000000000..b00728e80 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000822080) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 lead ions\n"; + return 1; + } + } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C new file mode 100644 index 000000000..aaee11ffc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // // check if each event has at least two oxygen ions + // for (int i = 0; i < nEvents; i++) + // { + // auto check = tree->GetEntry(i); + // int count = 0; + // for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + // { + // auto track = tracks->at(idxMCTrack); + // if (track.GetPdgCode() == 1000080160) + // { + // count++; + // } + // } + // if (count < 2) + // { + // std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + // return 1; + // } + // } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C new file mode 100644 index 000000000..aaee11ffc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // // check if each event has at least two oxygen ions + // for (int i = 0; i < nEvents; i++) + // { + // auto check = tree->GetEntry(i); + // int count = 0; + // for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + // { + // auto track = tracks->at(idxMCTrack); + // if (track.GetPdgCode() == 1000080160) + // { + // count++; + // } + // } + // if (count < 2) + // { + // std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + // return 1; + // } + // } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg new file mode 100644 index 000000000..d356956f7 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 1000822080 +Beams:idB = 1000822080 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Initialize the Angantyr model to fit the total and semi-includive +### cross sections in Pythia within some tolerance. +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 + +### These parameters are typicall suitable for sqrt(S_NN)=5TeV +HeavyIon:SigFitDefPar = 17.24,2.15,0.33,0.0,0.0,0.0,0.0,0.0 + +Random:setSeed = on + +# change omega, phi meson's BR below +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg new file mode 100644 index 000000000..b8a0c3923 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13600. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# change eta, omega, phi meson's BR below +221:oneChannel = 1 0.5 0 -13 13 +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg new file mode 100644 index 000000000..6d9191759 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# change eta, omega, phi meson's BR below +221:oneChannel = 1 0.5 0 -13 13 +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 From 1da166aab4a8b230b8588110ff0596687a4c228c Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Wed, 21 Jan 2026 11:47:04 +0100 Subject: [PATCH 212/362] TPC laser: add ccdp-populator path for laser replay run --- DATA/production/calib/tpc-laser-aggregator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/production/calib/tpc-laser-aggregator.sh b/DATA/production/calib/tpc-laser-aggregator.sh index 8d0acc5bf..e409850eb 100755 --- a/DATA/production/calib/tpc-laser-aggregator.sh +++ b/DATA/production/calib/tpc-laser-aggregator.sh @@ -10,7 +10,7 @@ PROXY_INSPEC="A:TPC/LASERTRACKS;B:TPC/CEDIGITS;D:TPC/CLUSREFS" CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=300;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=602;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" -CCDB_PATH="http://o2-ccdb.internal" +[[ $RUNTYPE == "SYNTHETIC" ]] && CCDB_PATH="http://ccdb-test.cern.ch:8080" || CCDB_PATH="http://o2-ccdb.internal" HOST=localhost From dcfc5aba7daf7e51b06952f8c0e6769ff858bb89 Mon Sep 17 00:00:00 2001 From: Piotr Konopka Date: Mon, 26 Jan 2026 13:11:34 +0100 Subject: [PATCH 213/362] Add missing default Activity fields for HMP simulation QC (#2242) In particular, a missing `"provenance" : "qc_mc"` was making the HMP results go to the default "qc" folder in the MC QCDB. --- MC/config/QC/json/hmp.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MC/config/QC/json/hmp.json b/MC/config/QC/json/hmp.json index 03915cb13..2995fef64 100644 --- a/MC/config/QC/json/hmp.json +++ b/MC/config/QC/json/hmp.json @@ -9,8 +9,11 @@ "name":"not_applicable" }, "Activity":{ - "number":"42", - "type":"2" + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" }, "monitoring":{ "url":"infologger:///debug?qc" From 4120f2d4613f34639e2d47e460ea85224e708f89 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Mon, 26 Jan 2026 11:34:17 +0100 Subject: [PATCH 214/362] anchorMC: Fix bug in restoring custom env variable This fixes https://its.cern.ch/jira/browse/O2-6621 The `export $var=$b` command, used to restore environment variables was executed in a sub-shell because we piped into the while loop. This is avoiding by not using a pipe. Instead the while loop iterations are taken from `< <()` notation. --- MC/run/ANCHOR/anchorMC.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 732cc7505..9425f8dfb 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -275,14 +275,17 @@ if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then # Restore overwritten O2DPG variables set by modules but changed by user # (in particular custom O2DPG_ROOT and O2DPG_MC_CONFIG_ROOT) + # We must avoid piping into a while loop (otherwise the internal export is executed in sub-shell) printenv > env_after_restore.printenv - comm -12 <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ - <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort) | while read -r var; do b=$(grep "^$var=" env_before_stashing.printenv | cut -d= -f2-) a=$(grep "^$var=" env_after_restore.printenv | cut -d= -f2-) [[ "$b" != "$a" ]] && export "$var=$b" && echo "Reapplied: $var to ${b}" - done + done < <( + comm -12 \ + <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ + <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort)) + fi #<----- END OF part that should run under a clean alternative software environment if this was given ------ From 8b31af4f1233c516be74d07c489de1f28caafc8d Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Mon, 24 Nov 2025 20:24:35 +0100 Subject: [PATCH 215/362] Add TPC Loopers collision system confKey --- MC/bin/o2dpg_sim_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index 028dd0bfd..1f5696e75 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -134,6 +134,7 @@ def add(cfg, flatconfig): # ----- add default settings ----- add(config, {"MFTBase.buildAlignment" : "true"}) + add(config, {"GenTPCLoopers.colsys" : args.col}) # ----- apply external overwrites from command line ------- for keyval in externalConfigString.split(";"): From 44e1c0ddb3532c307837d5562fa99e5829b967a3 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:30:40 +0100 Subject: [PATCH 216/362] add EPOS4 with URQMD switched off (#2249) --- .../pp_136TeV_hydro_cascade_off.optns | 32 +++++++++++++++++++ .../ini/GeneratorEPOS4_pp136TeV_nohacas.ini | 12 +++++++ 2 files changed, 44 insertions(+) create mode 100644 MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns create mode 100644 MC/config/examples/ini/GeneratorEPOS4_pp136TeV_nohacas.ini diff --git a/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns new file mode 100644 index 000000000..e02b08b3f --- /dev/null +++ b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 13.6 TeV with hydro and hadronic cascade switched off +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13600 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas off !hadronic cascade activated (UrQMD) +set nfreeze 10 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/ini/GeneratorEPOS4_pp136TeV_nohacas.ini b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV_nohacas.ini new file mode 100644 index 000000000..f1efd0687 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV_nohacas.ini @@ -0,0 +1,12 @@ +#---> GeneratorEPOS4 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns", 214748364) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 From f8a96ded504585025967515c0b00c6e0bfc3127e Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 16 Dec 2025 14:42:38 +0100 Subject: [PATCH 217/362] Refactor of TPC clusterization configuration * beautification of configuration * coupling to task-finalizer to be able to inject config-keys from outside * make sensitive to GPU_proc_nn for the ML clusterization keys --- MC/bin/o2dpg_sim_workflow.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index aea495b48..657e613c8 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1255,7 +1255,22 @@ def getDigiTaskName(det): tpcclustertasks.append(taskname) tpcclussect = createTask(name=taskname, needs=tpcclusterneed, tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='2', mem='8000') digitmergerstr = '${O2_ROOT}/bin/o2-tpc-chunkeddigit-merger --tpc-sectors ' + str(s)+'-'+str(s+sectorpertask-1) + ' --tpc-lanes ' + str(NWORKERS_TF) + ' | ' - tpcclussect['cmd'] = (digitmergerstr,'')[args.no_tpc_digitchunking] + ' ${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options(bigshm=True) + ' --input-type ' + ('digitizer','digits')[args.no_tpc_digitchunking] + ' --output-type clusters,send-clusters-per-sector --tpc-native-cluster-writer \" --outfile tpc-native-clusters-part'+ str((int)(s/sectorpertask)) + '.root\" --tpc-sectors ' + str(s)+'-'+str(s+sectorpertask-1) + ' ' + putConfigValues(["GPU_global"], {"GPU_proc.ompThreads" : 4}) + ('',' --disable-mc')[args.no_mc_labels] + tpcclussect['cmd'] = (digitmergerstr,'')[args.no_tpc_digitchunking] + task_finalizer( + [ + '${O2_ROOT}/bin/o2-tpc-reco-workflow', + getDPL_global_options(bigshm=True), + '--input-type ' + ('digitizer','digits')[args.no_tpc_digitchunking], + '--output-type clusters,send-clusters-per-sector', + f'--tpc-native-cluster-writer \" --outfile tpc-native-clusters-part{(int)(s/sectorpertask)}.root\"', + f'--tpc-sectors {s}-{s+sectorpertask-1}', + putConfigValues(["GPU_global", + "GPU_proc_nn", + "TPCCorrMap", + "TPCGasParam"], {"GPU_proc.ompThreads" : 4}), + '--disable-mc' if args.no_mc_labels else None + ], configname="tpcclusterizertask" + ) + tpcclussect['env'] = { "OMP_NUM_THREADS" : "4" , "TBB_NUM_THREADS" : "4" } tpcclussect['semaphore'] = "tpctriggers.root" tpcclussect['retry_count'] = 2 # the task has a race condition --> makes sense to retry @@ -1266,6 +1281,7 @@ def getDigiTaskName(det): workflow['stages'].append(TPCCLUSMERGEtask) tpcreconeeds.append(TPCCLUSMERGEtask['name']) else: + # TODO: adapt this to the case above and merge code / avoid code duplication tpcclus = createTask(name='tpccluster_' + str(tf), needs=tpcclusterneed, tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=NWORKERS_TF, mem='2000') tpcclus['cmd'] = '${O2_ROOT}/bin/o2-tpc-chunkeddigit-merger --tpc-lanes ' + str(NWORKERS_TF) tpcclus['cmd'] += ' | ${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options() + ' --input-type digitizer --output-type clusters,send-clusters-per-sector ' + putConfigValues(["GPU_global","TPCGasParam","TPCCorrMap"],{"GPU_proc.ompThreads" : 1}) + ('',' --disable-mc')[args.no_mc_labels] From dac9ee92684bf7c608e29749d7f4165277f4f37e Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 16 Dec 2025 14:47:43 +0100 Subject: [PATCH 218/362] Example script to run workflow with ML clusterizer --- MC/run/ANCHOR/tests/ML_clusterizer/run.sh | 68 +++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 MC/run/ANCHOR/tests/ML_clusterizer/run.sh diff --git a/MC/run/ANCHOR/tests/ML_clusterizer/run.sh b/MC/run/ANCHOR/tests/ML_clusterizer/run.sh new file mode 100755 index 000000000..9f800d868 --- /dev/null +++ b/MC/run/ANCHOR/tests/ML_clusterizer/run.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +#JDL_OUTPUT=*.txt@disk=1,AO2D*.root@disk=2,*.log@disk=1,*stat*@disk=1,*.json@disk=1,debug*tgz@disk=2,tf*/coll*.root +#JDL_ERROROUTPUT=*.txt@disk=1,AO2D*.root@disk=2,*.log@disk=1,*.json@disk=1,debug*tgz@disk=2 +#JDL_PACKAGE=O2PDPSuite::daily-20251215-0000-1 + +# +# An **EXAMPLE** showing injection of GPU_proc_nn config_keys into the workflow creation, so +# that TPC clusterizer runs with ML kernel. +# + +# example anchoring +export ALIEN_JDL_LPMANCHORPASSNAME=apass4 +export ALIEN_JDL_MCANCHOR=apass4 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=544124 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=PbPb +export ALIEN_JDL_LPMPRODUCTIONTAG=MLClusterTest +export ALIEN_JDL_LPMANCHORRUN=544124 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC23zz +export ALIEN_JDL_LPMANCHORYEAR=2023 + +export NTIMEFRAMES=1 +export PRODSPLIT=${ALIEN_O2DPG_GRIDSUBMIT_PRODSPLIT:-100} +export SPLITID=${ALIEN_O2DPG_GRIDSUBMIT_SUBJOBID:-50} +export CYCLE=0 + +# this file modifies few config key values for GPU_proc_nn for application in TPC clusterization +LOCAL_CONFIG="customize_ml_clusterizing.json" +cat > ${LOCAL_CONFIG} < Date: Thu, 29 Jan 2026 12:55:45 +0100 Subject: [PATCH 219/362] Add Strangeness (cascades) generator pythia ropes + jet gap 4 (#2251) --- .../GeneratorLFCascadesInJets_pp536TeV.ini | 10 ++++ .../GeneratorLFCascadesInJets_pp536TeV.C | 58 +++++++++++++++++++ .../generator/pythia8_jet_ropes_536tev.cfg | 29 ++++++++++ 3 files changed, 97 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLFCascadesInJets_pp536TeV.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLFCascadesInJets_pp536TeV.C create mode 100644 MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFCascadesInJets_pp536TeV.ini b/MC/config/PWGLF/ini/GeneratorLFCascadesInJets_pp536TeV.ini new file mode 100644 index 000000000..7f96b4461 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFCascadesInJets_pp536TeV.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C +# funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 0) +funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 4) + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFCascadesInJets_pp536TeV.C b/MC/config/PWGLF/ini/tests/GeneratorLFCascadesInJets_pp536TeV.C new file mode 100644 index 000000000..49ba5d4e2 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFCascadesInJets_pp536TeV.C @@ -0,0 +1,58 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + std::vector injectedPDGs = { + 3334, + -3334, + 3312, + -3312}; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) { + nSignal.push_back(0); + } + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) { + std::cout << "# Injected nuclei \n"; + std::cout << injectedPDGs[i] << ": " << nSignal[i] << "\n"; + if (nSignal[i] == 0) { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + return 1; // At least one of the injected particles should be generated + } + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg new file mode 100644 index 000000000..eb7aa7a86 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg @@ -0,0 +1,29 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 5360. # GeV + +### processes +SoftQCD:inelastic = off +HardQCD:all = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 8 +PhaseSpace:pTHatMax = 600 +PhaseSpace:bias2Selection = on +PhaseSpace:bias2SelectionPow = 4 + +Random:setSeed = on +Random:seed = 0 + +Ropewalk:RopeHadronization = on +Ropewalk:doShoving = off +Ropewalk:doFlavour = on +Ropewalk:r0 = 0.5 +Ropewalk:m0 = 0.2 +Ropewalk:beta = 0.1 +PartonVertex:setVertex = on \ No newline at end of file From 9927be4935fc50f22a9789f91088cd5c5336e32a Mon Sep 17 00:00:00 2001 From: Antonio Palasciano <52152842+apalasciano@users.noreply.github.com> Date: Thu, 29 Jan 2026 17:48:13 +0100 Subject: [PATCH 220/362] Configs for Lc resonance prod. (#2246) * Configs for Lc resonance prod. * Fixing PDG numbering scheme for PDG codes --- .../generator_pythia8_gaptriggered_hf.C | 12 +- ...D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini | 10 ++ ...F_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C | 131 ++++++++++++++++++ ...harmhadronic_with_decays_LcResoTrigger.cfg | 118 ++++++++++++++++ 4 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C index 8d5060251..578323d02 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -33,8 +33,8 @@ public: mHadronPdgList = hadronPdgList; mPartPdgToReplaceList = partPdgToReplaceList; mFreqReplaceList = freqReplaceList; - // Ds1*(2700), Ds1*(2860), Ds3*(2860), Xic(3055)+, Xic(3080)+, Xic(3055)0, Xic(3080)0, LambdaC(2625), LambdaC(2595) - mCustomPartPdgs = {30433, 40433, 437, 4315, 4316, 4325, 4326, 4124, 14122}; + // Ds1*(2700), Ds1*(2860), Ds3*(2860), Xic(3055)+, Xic(3080)+, Xic(3055)0, Xic(3080)0, LambdaC(2625), LambdaC(2595), LambdaC(2860), LambdaC(2880), LambdaC(2940), ThetaC(3100) + mCustomPartPdgs = {30433, 40433, 437, 4315, 4316, 4325, 4326, 4124, 14122, 24124, 24126, 4125, 9422111}; mCustomPartMasses[30433] = 2.714f; mCustomPartMasses[40433] = 2.859f; mCustomPartMasses[437] = 2.860f; @@ -44,6 +44,10 @@ public: mCustomPartMasses[4326] = 3.0772f; mCustomPartMasses[4124] = 2.62810f; mCustomPartMasses[14122] = 2.59225f; + mCustomPartMasses[24124] = 2.8561f; + mCustomPartMasses[24126] = 2.8816; + mCustomPartMasses[4125] = 2.9396f; + mCustomPartMasses[9422111] = 3.099f; mCustomPartWidths[30433] = 0.122f; mCustomPartWidths[40433] = 0.160f; mCustomPartWidths[437] = 0.053f; @@ -53,6 +57,10 @@ public: mCustomPartWidths[4326] = 0.0036f; mCustomPartWidths[4124] = 0.00052f; mCustomPartWidths[14122] = 0.0026f; + mCustomPartWidths[24124] = 0.0676f; + mCustomPartWidths[24126] = 0.0056f; + mCustomPartWidths[4125] = 0.017f; + mCustomPartWidths[9422111] = 0.0000083f; Print(); } diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini new file mode 100644 index 000000000..cbd913e01 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.5, 1.5, {24124, 24126, 4125, 9422111}, {{4122, 24124}, {4122, 24126}, {4122, 4125}, {4122, 9422111}}, {0.1, 0.1, 0.1, 0.1}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg +includePartonEvent=false +### not needed for jet studies, hence no need to keep parton event diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C new file mode 100644 index 000000000..a2c5fa546 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C @@ -0,0 +1,131 @@ +int ExternalLc() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; // c quark injection + int checkPdgQuarkTwo{5}; // b quark injection + float ratioTrigger = 1./5.; // one event triggered out of 5 + + // PDG replacements: Λc(4122) -> resonances + std::array, 4> pdgReplParticles = { + std::array{4122, 24124}, // Λc -> Λc(2860) + std::array{4122, 24126}, // Λc -> Λc(2880) + std::array{4122, 4125}, // Λc -> Λc(2940) + std::array{4122, 9422111} // Λc -> Tc(3100) + }; + + // Counters for replacements + std::array, 4> pdgReplPartCounters = { + std::array{0,0}, std::array{0,0}, std::array{0,0}, std::array{0,0} + }; + + std::array freqRepl = {0.2, 0.2, 0.2, 0.2}; + std::map sumOrigReplacedParticles = {{4122,0}}; + + // Hadrons to check + std::array checkPdgHadron{24124, 24126, 4125, 9422111, 5122}; + + // Correct decays + std::map>> checkHadronDecays{ + {24124, {{421, 2212}}}, + {24126, {{421, 2212}}}, + {4125, {{421, 2212}}}, + {9422111, {{413, 2212}}}, + {5122, {{421, 2212, -211}, {41221, -211}, {24124, -211}, {24126, -211}, {4125, -211}}} + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { std::cerr << "Cannot open ROOT file " << path << "\n"; return 1; } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader* eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + std::map signalHadronsPerType; + std::map signalGoodDecayPerType; + for (auto pdg : checkPdgHadron) { signalHadronsPerType[pdg] = 0; signalGoodDecayPerType[pdg] = 0; } + + for (int i=0; iGetEntry(i); + + int subGeneratorId{-1}; + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid=false; + subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId==0) nEventsMB++; + else if (subGeneratorId==checkPdgQuarkOne) nEventsInjOne++; + else if (subGeneratorId==checkPdgQuarkTwo) nEventsInjTwo++; + } + + for (auto& track : *tracks) { + int pdg = track.GetPdgCode(); + int absPdg = std::abs(pdg); + + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) { + nSignals++; + signalHadronsPerType[absPdg]++; + + if (subGeneratorId==checkPdgQuarkOne) { + for (int iRepl=0; iRepl<3; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { pdgReplPartCounters[iRepl][0]++; sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; } + else if (absPdg == pdgReplParticles[iRepl][1]) { pdgReplPartCounters[iRepl][1]++; sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; } + } + } + + std::vector pdgsDecay; + std::vector pdgsDecayAnti; + if (track.getFirstDaughterTrackId()>=0) { + for (int j=track.getFirstDaughterTrackId(); j<=track.getLastDaughterTrackId(); ++j) { + int pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + pdgsDecayAnti.push_back((pdgDau==111||pdgDau==333)? pdgDau : -pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAnti.begin(), pdgsDecayAnti.end()); + + bool matchedDecay = false; + for (auto& decay : checkHadronDecays[absPdg]) { + std::vector decayCopy = decay; + std::sort(decayCopy.begin(), decayCopy.end()); + if (pdgsDecay == decayCopy || pdgsDecayAnti == decayCopy) { + matchedDecay = true; + nSignalGoodDecay++; + signalGoodDecayPerType[absPdg]++; + break; + } + } + + // Print daughters + std::cout << "Particle " << absPdg << " daughters: "; + for (auto d : pdgsDecay) std::cout << d << " "; + if (matchedDecay) std::cout << "(matches expected decay)"; + else std::cout << "(does NOT match expected decay)"; + std::cout << "\n"; + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << "# events injected with " << checkPdgQuarkOne << ": " << nEventsInjOne << "\n"; + std::cout << "# events injected with " << checkPdgQuarkTwo << ": " << nEventsInjTwo << "\n"; + std::cout << "# signal hadrons: " << nSignals << "\n"; + std::cout << "# signal hadrons decaying in correct channels: " << nSignalGoodDecay << "\n"; + + for (auto& [pdg, count] : signalHadronsPerType) { + int good = signalGoodDecayPerType[pdg]; + float frac = count>0 ? float(good)/count : 0.; + std::cout << "Particle " << pdg << ": " << count << " signals, " << good << " good decays, fraction: " << frac << "\n"; + } + + // Optional: sanity checks... + return 0; +} diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg new file mode 100644 index 000000000..274d4b22b --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg @@ -0,0 +1,118 @@ +### author: Antonio Palasciano (antonio.palasciano@cern.ch) +### since: July 2024 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### add resonances not present in PYTHIA +### id:all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 + +### LambdaC(2860) +24124:all = Lambda_c(2860)+ Lambda_c(2860)- 3 1 0 2.8561 0.0676 2.7 10. 0. +24124:mayDecay = on + +### LambdaC(2880) +24126:all = Lambda_c(2880)+ Lambda_c(2880)- 5 1 0 2.8816 0.0056 2.85 10. 0. +24126:mayDecay = on + +### LambdaC(2940) +4125:all = Lambda_c(2940)+ Lambda_c(2940)- 3 1 0 2.9396 0.020 2.9 10. 0. +4125:mayDecay = on + +### TC(3100) +9422111:all = Theta_c(3100) 3 0 0 3.099 0.0000083 2.95 10. 0. +9422111:mayDecay = on + +### turn off all charm resonances decays +# 24124:onMode = off # LambdaC(2860) +# 24126:onMode = off # LambdaC(2880) +# 4125:onMode = off # LambdaC(2940) +# 9422111:onMode = off # Theta_c(3100) + +### turn off all beauty hadron decays +531:onMode = off +521:onMode = off +5122:onMode = off + +### add LambdaC(2860) +24124:oneChannel = 1 1 0 421 2212 +24124:onIfMatch = 421 2212 + +### add LambdaC(2880) +24126:oneChannel = 1 1 0 421 2212 +24126:onIfMatch = 421 2212 + +### add LambdaC(2940) +4125:oneChannel = 1 1 0 421 2212 +4125:onIfMatch = 421 2212 + +### add ThetaC(3100) +9422111:oneChannel = 1 1 0 413 2212 +9422111:onIfMatch = 413 2212 + +### add Lb +5122:addChannel = 1 0.2 0 421 2212 -211 # Lb -> D0 p pi- non resonant +5122:addChannel = 1 0.4 0 24124 -211 # Lb -> LambdaC(2860)+ pi- +5122:addChannel = 1 0.25 0 24126 -211 # Lb -> LambdaC(2880)+ pi- +5122:addChannel = 1 0.15 0 4125 -211 # Lb -> LambdaC(2940)+ pi- + +5122:onIfMatch = 421 2212 -211 # D0 p pi- +5122:onIfMatch = 24124 -211 # LambdaC(2860)+ pi- +5122:onIfMatch = 24126 -211 # LambdaC(2880)+ pi- +5122:onIfMatch = 4125 -211 # LambdaC(2940)+ pi- + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +### set D0 BRs +421:oneChannel = 1 0.9 0 -321 211 +421:addChannel = 1 0.1 0 -321 211 111 + +### K* -> K pi +313:onMode = off +313:onIfAll = 321 211 + +### switch off all decay channels +411:onMode = off +413:onMode = off +421:onMode = off + +### D0 -> K pi +421:onIfMatch = 321 211 +### D0 -> K pi pi0 +421:onIfMatch = 321 211 111 +### D*+0 -> D0 pi +413:onIfMatch = 421 211 From eb760580e383a3c953167ed1592ee08b7b022b57 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Fri, 30 Jan 2026 08:07:43 +0100 Subject: [PATCH 221/362] setenv_calib.sh: add residuals-aggregator input DETINFORES to barrel_tf proxy dataspec --- DATA/common/setenv_calib.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index 637f4fb1f..3b8dcf6a2 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -51,17 +51,17 @@ if [[ $BEAMTYPE != "cosmic" ]] || [[ ${FORCECALIBRATIONS:-} == 1 ]] ; then # Cal if [[ $CAN_DO_CALIB_PRIMVTX_MEANVTX == 1 ]]; then if [[ -z ${CALIB_PRIMVTX_MEANVTX+x} ]]; then CALIB_PRIMVTX_MEANVTX=1; fi fi - + # calibrations for ITS if [[ $CAN_DO_CALIB_ITS_DEADMAP_TIME == 1 ]]; then if [[ -z ${CALIB_ITS_DEADMAP_TIME+x} ]]; then CALIB_ITS_DEADMAP_TIME=1; fi fi - + # calibrations for MFT if [[ $CAN_DO_CALIB_MFT_DEADMAP_TIME == 1 ]]; then if [[ -z ${CALIB_MFT_DEADMAP_TIME+x} ]]; then CALIB_MFT_DEADMAP_TIME=1; fi fi - + # calibrations for TOF if [[ $CAN_DO_CALIB_TOF_DIAGNOSTICS == 1 ]]; then if [[ -z ${CALIB_TOF_DIAGNOSTICS+x} ]]; then CALIB_TOF_DIAGNOSTICS=1; fi @@ -260,7 +260,7 @@ if [[ -z ${CALIBDATASPEC_BARREL_TF:-} ]]; then # MFT if [[ $CALIB_MFT_DEADMAP_TIME == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "mftChipStatus:MFT/CHIPSSTATUS/0"; fi - + # TOF if [[ $CALIB_TOF_LHCPHASE == 1 ]] || [[ $CALIB_TOF_CHANNELOFFSETS == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "calibTOF:TOF/CALIBDATA/0"; fi if [[ $CALIB_TOF_DIAGNOSTICS == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "diagWords:TOF/DIAFREQ/0"; fi @@ -268,6 +268,7 @@ if [[ -z ${CALIBDATASPEC_BARREL_TF:-} ]]; then # TPC if [[ $CALIB_TPC_SCDCALIB == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "unbinnedTPCResiduals:GLO/UNBINNEDRES/0" + add_semicolon_separated CALIBDATASPEC_BARREL_TF "detectorInfoResiduals:GLO/DETINFORES/0" add_semicolon_separated CALIBDATASPEC_BARREL_TF "trackReferences:GLO/TRKREFS/0" fi if [[ $CALIB_TPC_SCDCALIB == 1 ]] && [[ ${CALIB_TPC_SCDCALIB_SENDTRKDATA:-} == "1" ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "tpcInterpTrkData:GLO/TRKDATA/0"; fi From acbcc784a606f9739eac69a50b3494699f74ddaf Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Sun, 1 Feb 2026 16:15:55 +0100 Subject: [PATCH 222/362] Add generators for light-ion systems based on EPOS4 (#2253) --- .../epos4/generator/NeNe_536TeV_EPOS4.optns | 32 ++++++++ .../epos4/generator/OO_536TeV_EPOS4.optns | 32 ++++++++ .../examples/ini/GeneratorEPOS4OO536TeV.ini | 12 +++ .../ini/tests/GeneratorEPOS4OO536TeV.C | 78 +++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns create mode 100644 MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns create mode 100644 MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini create mode 100644 MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C diff --git a/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns new file mode 100644 index 000000000..9c7df71a3 --- /dev/null +++ b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! Neon-Neon collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 10 !projectile atomic number +set maproj 20 !projectile mass number +set latarg 10 !target atomic number +set matarg 20 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns new file mode 100644 index 000000000..254a1e4a4 --- /dev/null +++ b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! Oxygen-Oxygen collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 8 !projectile atomic number +set maproj 16 !projectile mass number +set latarg 8 !target atomic number +set matarg 16 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini new file mode 100644 index 000000000..c05718ff0 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 1 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C new file mode 100644 index 000000000..97798d7e2 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C @@ -0,0 +1,78 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + // Check if there is 1 event, as customly set in the ini file + // Heavy-ion collisions with hydro and hadronic cascade are very slow to simulate + if (nEvents != 1) + { + std::cerr << "Expected 1 event, got " << nEvents << "\n"; + return 1; + } + + // ---- Oxygen-Oxygen parameters ---- + constexpr int kOxygenPDG = 1000080160; // O-16 ion + constexpr double kEnucleon = 5360.; // GeV per nucleon + constexpr int kA = 16; // Oxygen mass number + constexpr double kOxygenEnergy = kA * kEnucleon / 2.0; // 85760 / 2 GeV + + // Check if each event has two oxygen ions at expected energy + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int count = 0; + + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + + // 50 MeV tolerance (floating point safety) + if (std::abs(energy - kOxygenEnergy) < 5e-2 && + track.GetPdgCode() == kOxygenPDG) + { + count++; + } + } + + if (count < 2) + { + std::cerr << "Event " << i + << " has less than 2 oxygen ions at " + << kOxygenEnergy << " GeV\n"; + return 1; + } + } + + return 0; +} From f942880c5115e44a877907cb0688481fdfa7c147 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner <48915672+matthias-kleiner@users.noreply.github.com> Date: Mon, 2 Feb 2026 09:15:21 +0100 Subject: [PATCH 223/362] Add possibility to enable time gain calibration (#2247) * Add possibility to enable time gain calibration This PR enables the option to create the time gain calibration objects by setting ALIEN_JDL_DOTPCTIMEGAINCALIB=1. The output files are named `o2tpc_CalibratordEdx_Histos_____.root` and need to be merged afterwards to get enough statistics for the fits. * Add option to specify scale events and tracks --- DATA/production/configurations/asyncReco/async_pass.sh | 4 ++++ .../configurations/asyncReco/setenv_extra.sh | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index 5e2729223..e2b92fa34 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -205,6 +205,10 @@ if [[ "$ALIEN_JDL_EXTRACTTIMESERIES" == "1" ]]; then export ADD_CALIB=1 fi +if [[ "$ALIEN_JDL_DOTPCTIMEGAINCALIB" == "1" ]]; then + export ADD_CALIB=1 +fi + # AOD file size if [[ -n "$ALIEN_JDL_AODFILESIZE" ]]; then export AOD_FILE_SIZE="$ALIEN_JDL_AODFILESIZE" diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index f66cbe24b..f9369cce1 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -761,6 +761,16 @@ if [[ $ADD_CALIB == "1" ]]; then if [[ $ALIEN_JDL_DOUPLOADSLOCALLY == 1 ]]; then export CCDB_POPULATOR_UPLOAD_PATH="file://$PWD" fi + + # enable time gain calibration + if [[ $ALIEN_JDL_DOTPCTIMEGAINCALIB == 1 ]]; then + echo "Enabling TPC time gain calibration" + export CALIB_TPC_TIMEGAIN=1 + export ARGS_EXTRA_PROCESS_o2_tpc_calibrator_dedx+=" --dump-histograms 1 --min-entries 1" # write full calibration objects for time gain without rejecting low statistics timeslots + export ARGS_EXTRA_PROCESS_o2_tpc_miptrack_filter+=" --use-global-tracks" + export SCALEEVENTS_TPC_TIMEGAIN=${SCALEEVENTS_TPC_TIMEGAIN:-1} # use all TFs + export SCALETRACKS_TPC_TIMEGAIN=${SCALETRACKS_TPC_TIMEGAIN:--1} # use all tracks + fi fi # Enabling AOD From 29cde9dbbf44bac80181aafa1b3b390cfe0689da Mon Sep 17 00:00:00 2001 From: shahoian Date: Sat, 31 Jan 2026 21:41:32 +0100 Subject: [PATCH 224/362] USETHROTTLING imposes TIMEFRAME_RATE_LIMIT=1 only if latter is not set --- .../configurations/asyncReco/async_pass.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index e2b92fa34..56201e190 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -284,16 +284,13 @@ fi ln -sf $O2DPG_ROOT/DATA/common/setenv.sh ln -sf $O2DPG_ROOT/DATA/common/getCommonArgs.sh -# TFDELAY and throttling -export TFDELAYSECONDS=40 -if [[ -n "$ALIEN_JDL_TFDELAYSECONDS" ]]; then - TFDELAYSECONDS="$ALIEN_JDL_TFDELAYSECONDS" -# ...otherwise, it depends on whether we have throttling -elif [[ -n "$ALIEN_JDL_USETHROTTLING" ]]; then - TFDELAYSECONDS=1 - if [[ -n "$ALIEN_JDL_NOTFDELAY" ]]; then - TFDELAYSECONDS=0 - fi +# throttling and TF-delay +: ${TFDELAYSECONDS:=0} +if [[ -n "$ALIEN_JDL_NOTFDELAY" ]] && [[ "$ALIEN_JDL_NOTFDELAY" -gt 0 ]] ; then + TFDELAYSECONDS=0 +fi + +if [[ -n "$ALIEN_JDL_USETHROTTLING" ]] && [[ -z "$TIMEFRAME_RATE_LIMIT" ]] ; then export TIMEFRAME_RATE_LIMIT=1 fi From d2c9311831420da68f13d6e2b7a4e9dd61d066dd Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Mon, 2 Feb 2026 12:05:08 +0100 Subject: [PATCH 225/362] new ini for gap triggerd strangeness MC for pp ref energy (#2245) * new ini for gap triggerd strangeness MC for pp ref energy * adding test --------- Co-authored-by: Lucia Anna Tarasovicova --- .../ini/GeneratorLFStrangenessTriggered_5360gev.ini | 10 ++++++++++ .../tests/GeneratorLFStrangenessTriggered_5360gev.C | 1 + 2 files changed, 11 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLFStrangenessTriggered_5360gev.ini create mode 120000 MC/config/PWGLF/ini/tests/GeneratorLFStrangenessTriggered_5360gev.C diff --git a/MC/config/PWGLF/ini/GeneratorLFStrangenessTriggered_5360gev.ini b/MC/config/PWGLF/ini/GeneratorLFStrangenessTriggered_5360gev.ini new file mode 100644 index 000000000..09d05da74 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFStrangenessTriggered_5360gev.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C +# funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 0) +funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 4) + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessTriggered_5360gev.C b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessTriggered_5360gev.C new file mode 120000 index 000000000..363dcd11d --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessTriggered_5360gev.C @@ -0,0 +1 @@ +GeneratorLFStrangenessTriggered.C \ No newline at end of file From 9237d4be2d193bea4330dde10317ce3c1c3ddda8 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 3 Feb 2026 08:43:41 +0100 Subject: [PATCH 226/362] make anchor testing more configurable --- MC/run/ANCHOR/tests/test_looper.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MC/run/ANCHOR/tests/test_looper.sh b/MC/run/ANCHOR/tests/test_looper.sh index f9db7b110..eddfbd22f 100755 --- a/MC/run/ANCHOR/tests/test_looper.sh +++ b/MC/run/ANCHOR/tests/test_looper.sh @@ -91,9 +91,9 @@ TOPWORKDIR="" TOPWORKDIR=2tag_release_testing_${BUILD_TAG:-${SOFTWARETAG_SIM}} - # we submit the test to the GRID (multiplicity of 4) + # we submit the test to the GRID (with some multiplicity) # ${WORKING_DIR}/submit_case${count}_${SOFTWARETAG_ASYNC//::/-} - echo "${O2DPG_ROOT}/GRID/utils/grid_submit.sh --prodsplit 4 --singularity --ttl 3600 --script ${OUTPUT_FILE_FINAL} \ + echo "${O2DPG_ROOT}/GRID/utils/grid_submit.sh --prodsplit ${PRODSPLIT:-4} --singularity --ttl ${TTL:-3600} --script ${OUTPUT_FILE_FINAL} \ --jobname "anchorTest_${count}" --wait-any --topworkdir ${TOPWORKDIR}" > ${WORKING_DIR}/submit_case${count}.sh # TODO: optional local execution with --local option From a2792e3cdc0769a22a60fff4bb204cca5cd88e80 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 24 Jul 2025 13:36:55 +0200 Subject: [PATCH 227/362] ITSMFT: rerun clusterizer Signed-off-by: Felix Schlepper --- DATA/production/configurations/asyncReco/setenv_extra.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index f9369cce1..0f78ed907 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -147,8 +147,7 @@ fi # other settings echo RUN = $RUNNUMBER if [[ $RUNNUMBER -ge 521889 ]]; then - export ARGS_EXTRA_PROCESS_o2_ctf_reader_workflow+=" --its-digits --mft-digits" - export DISABLE_DIGIT_CLUSTER_INPUT="--digits-from-upstream" + export ITSMFT_RECO_RERUN_CLUSTERIZER=1 MAXBCDIFFTOMASKBIAS_ITS="ITSClustererParam.maxBCDiffToMaskBias=-10" # this explicitly disables ITS masking MAXBCDIFFTOSQUASHBIAS_ITS="ITSClustererParam.maxBCDiffToSquashBias=10" # this explicitly enables ITS squashing MAXBCDIFFTOMASKBIAS_MFT="MFTClustererParam.maxBCDiffToMaskBias=-10" # this explicitly disables MFT masking From 4a395337ae1eaa6cf227a0510d2327bfab1b5516 Mon Sep 17 00:00:00 2001 From: Francesca Ercolessi Date: Tue, 3 Feb 2026 19:09:06 +0100 Subject: [PATCH 228/362] [PWGLF] Add Ropes and EPOS config files for pp 5.36 TeV (#2259) * Add generator for Ropes in pp 5.36 TeV * Add EPOS generator for pp 5.36 TeV * fix epos ini file --- .../PWGLF/epos/pp_536TeV_hydro_cascade.optns | 32 ++++++++++ .../PWGLF/ini/GeneratorEPOS4_pp536TeV.ini | 11 ++++ .../PWGLF/ini/GeneratorLF_pp536_Ropes.ini | 6 ++ .../PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C | 64 +++++++++++++++++++ .../PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C | 28 ++++++++ .../generator/pythia8_inel_ropes_536tev.cfg | 26 ++++++++ 6 files changed, 167 insertions(+) create mode 100644 MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns create mode 100644 MC/config/PWGLF/ini/GeneratorEPOS4_pp536TeV.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_pp536_Ropes.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C create mode 100644 MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg diff --git a/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns b/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns new file mode 100644 index 000000000..502cdc217 --- /dev/null +++ b/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 5.36 TeV with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/PWGLF/ini/GeneratorEPOS4_pp536TeV.ini b/MC/config/PWGLF/ini/GeneratorEPOS4_pp536TeV.ini new file mode 100644 index 000000000..5958fb64c --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorEPOS4_pp536TeV.ini @@ -0,0 +1,11 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/PWGLF/ini/GeneratorLF_pp536_Ropes.ini b/MC/config/PWGLF/ini/GeneratorLF_pp536_Ropes.ini new file mode 100644 index 000000000..2bfa5df9f --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_pp536_Ropes.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C b/MC/config/PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C new file mode 100644 index 000000000..5f9432f9e --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C @@ -0,0 +1,64 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + // check if each event has two protons with 2680 GeV of energy + // exits if the particle is not a proton + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + // Check if track energy is approximately equal to 2680 GeV (a tolerance of 65 keV is considered, straight equality does not work due to floating point precision) + if (std::abs(energy - 2680) < 1e-4) + { + if (track.GetPdgCode() != 2212){ + std::cerr << "Found 2680 GeV particle with pdgID " << track.GetPdgCode() << "\n"; + return 1; + } + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 protons at 2680 GeV\n"; + return 1; + } + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg new file mode 100644 index 000000000..9e4a73bcb --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg @@ -0,0 +1,26 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 5360. # GeV + +### processes +SoftQCD:inelastic = on # all inelastic processes + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 0.000000 +PhaseSpace:pTHatMax = -1.000000 + +Random:setSeed = on +Random:seed = 0 + +Ropewalk:RopeHadronization = on +Ropewalk:doShoving = off +Ropewalk:doFlavour = on +Ropewalk:r0 = 0.5 +Ropewalk:m0 = 0.2 +Ropewalk:beta = 0.1 +PartonVertex:setVertex = on \ No newline at end of file From ce0c917026f7a2cd1877d098a27c98188420db4f Mon Sep 17 00:00:00 2001 From: Chuntai <48704924+wuctlby@users.noreply.github.com> Date: Thu, 5 Feb 2026 12:53:43 +0100 Subject: [PATCH 229/362] Update tune from SCCR to QCDCR for pO and OO (#2256) --- ...rHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini} | 4 +-- ...rHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini} | 4 +-- ...torHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.C} | 0 ...torHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.C} | 0 ...a8_charmhadronic_with_decays_QCDCR_OO.cfg} | 30 +++++++++---------- ...a8_charmhadronic_with_decays_QCDCR_pO.cfg} | 30 +++++++++---------- 6 files changed, 34 insertions(+), 34 deletions(-) rename MC/config/PWGHF/ini/{GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini => GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini} (82%) rename MC/config/PWGHF/ini/{GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini => GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini} (80%) rename MC/config/PWGHF/ini/tests/{GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C => GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.C} (100%) rename MC/config/PWGHF/ini/tests/{GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C => GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.C} (100%) rename MC/config/PWGHF/pythia8/generator/{pythia8_charmhadronic_with_decays_SCCR_OO.cfg => pythia8_charmhadronic_with_decays_QCDCR_OO.cfg} (95%) rename MC/config/PWGHF/pythia8/generator/{pythia8_charmhadronic_with_decays_SCCR_pO.cfg => pythia8_charmhadronic_with_decays_QCDCR_pO.cfg} (95%) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini similarity index 82% rename from MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini rename to MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini index 1c74bb53d..854f810a1 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini @@ -5,5 +5,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(2, -1.5, 1.5) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg -includePartonEvent=true \ No newline at end of file +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini similarity index 80% rename from MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini rename to MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini index 80e2bc876..838a4a4f4 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini @@ -4,5 +4,5 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_py funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(2, -1.5, 1.5) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg -includePartonEvent=true \ No newline at end of file +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.C similarity index 100% rename from MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_OO.C rename to MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.C diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.C similarity index 100% rename from MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_SCCR_pO.C rename to MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.C diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg similarity index 95% rename from MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg rename to MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg index ab5e02f46..255cdfbd4 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_OO.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg @@ -20,27 +20,27 @@ HeavyIon:SigFitDefPar 2.15,18.42,0.33 Random:setSeed on -### switching on spatially constrained QCD colour reconnection (SC-CR) mode -ColourReconnection:mode = 1 -ColourReconnection:timeDilationMode = 0 -ColourReconnection:allowDoubleJunRem = off -ColourReconnection:m0 = 1.05 -ColourReconnection:allowJunctions = on -ColourReconnection:lambdaForm = 1 -ColourReconnection:mPseudo = 1.05 -ColourReconnection:junctionCorrection = 1.37 -ColourReconnection:dipoleMaxDist = 0.5 +### switching on QCD colour reconnection mode StringPT:sigma = 0.335 StringZ:aLund = 0.36 StringZ:bLund = 0.56 StringFlav:probQQtoQ = 0.078 -StringFlav:ProbStoUD = 0.4 -StringFlav:probQQ1toQQ0join = 0.5,0.7,0.9,1.0 -MultiPartonInteractions:pT0Ref = 2.37 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 BeamRemnants:remnantMode = 1 BeamRemnants:saturation = 5 -BeamRemnants:beamJunction = on -ColourReconnection:heavyLambdaForm = 1 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:allowJunctions = on +ColourReconnection:timeDilationMode = 0 +ColourReconnection:reconnect = on +ColourReconnection:forceHadronLevelCR = off +MultiPartonInteractions:pT0Ref = 2.12 +ColourReconnection:m0 = 2.9 +ColourReconnection:junctionCorrection = 1.43 +HIMultipartonInteractions:pT0Ref = 2.12 +BeamRemnants:beamJunction = off +HIBeamRemnants:beamJunction = off # Correct decay lengths (wrong in PYTHIA8 decay table) # Lb diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg similarity index 95% rename from MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg rename to MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg index e59c79da7..89c1c5d9e 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_SCCR_pO.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg @@ -21,27 +21,27 @@ HeavyIon:SigFitDefPar 2.15,18.42,0.33 Random:setSeed on -### switching on spatially constrained QCD colour reconnection (SC-CR) mode -ColourReconnection:mode = 1 -ColourReconnection:timeDilationMode = 0 -ColourReconnection:allowDoubleJunRem = off -ColourReconnection:m0 = 1.05 -ColourReconnection:allowJunctions = on -ColourReconnection:lambdaForm = 1 -ColourReconnection:mPseudo = 1.05 -ColourReconnection:junctionCorrection = 1.37 -ColourReconnection:dipoleMaxDist = 0.5 +### switching on QCD colour reconnection mode StringPT:sigma = 0.335 StringZ:aLund = 0.36 StringZ:bLund = 0.56 StringFlav:probQQtoQ = 0.078 -StringFlav:ProbStoUD = 0.4 -StringFlav:probQQ1toQQ0join = 0.5,0.7,0.9,1.0 -MultiPartonInteractions:pT0Ref = 2.37 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 BeamRemnants:remnantMode = 1 BeamRemnants:saturation = 5 -BeamRemnants:beamJunction = on -ColourReconnection:heavyLambdaForm = 1 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:allowJunctions = on +ColourReconnection:timeDilationMode = 0 +ColourReconnection:reconnect = on +ColourReconnection:forceHadronLevelCR = off +MultiPartonInteractions:pT0Ref = 2.12 +ColourReconnection:m0 = 2.9 +ColourReconnection:junctionCorrection = 1.43 +HIMultipartonInteractions:pT0Ref = 2.12 +BeamRemnants:beamJunction = off +HIBeamRemnants:beamJunction = off # Correct decay lengths (wrong in PYTHIA8 decay table) # Lb From 2d83347683fe4f29015036bee9029b4a36d6f02b Mon Sep 17 00:00:00 2001 From: rbailhac Date: Fri, 6 Feb 2026 09:24:50 +0100 Subject: [PATCH 230/362] PbPb cocktail (#2264) * PbPbCocktail * fix --- ...i => GeneratorEMCocktail_502PbPb_0005.ini} | 0 .../ini/GeneratorEMCocktail_502PbPb_0510.ini | 6 + .../ini/GeneratorEMCocktail_502PbPb_3040.ini | 6 + .../ini/GeneratorEMCocktail_502PbPb_4050.ini | 6 + .../ini/GeneratorEMCocktail_502PbPb_5060.ini | 6 + .../ini/GeneratorEMCocktail_502PbPb_6070.ini | 6 + .../ini/GeneratorEMCocktail_502PbPb_7080.ini | 6 + .../ini/GeneratorEMCocktail_502PbPb_8090.ini | 6 + .../PWGEM/ini/tests/GeneratorEMCocktail.C | 179 ---------- .../tests/GeneratorEMCocktail_502PbPb_0005.C | 64 ++++ .../tests/GeneratorEMCocktail_502PbPb_0510.C | 64 ++++ .../tests/GeneratorEMCocktail_502PbPb_3040.C | 64 ++++ .../tests/GeneratorEMCocktail_502PbPb_4050.C | 64 ++++ .../tests/GeneratorEMCocktail_502PbPb_5060.C | 64 ++++ .../tests/GeneratorEMCocktail_502PbPb_6070.C | 64 ++++ .../tests/GeneratorEMCocktail_502PbPb_7080.C | 64 ++++ .../tests/GeneratorEMCocktail_502PbPb_8090.C | 64 ++++ .../parametrizations/PbPb5TeV_central.json | 338 ++++++------------ .../parametrizations/PbPb5TeV_peripheral.json | 282 +++++++++++++++ 19 files changed, 955 insertions(+), 398 deletions(-) rename MC/config/PWGEM/ini/{GeneratorEMCocktail.ini => GeneratorEMCocktail_502PbPb_0005.ini} (100%) create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0510.ini create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_3040.ini create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_4050.ini create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_5060.ini create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_6070.ini create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_7080.ini create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_8090.ini delete mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0005.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0510.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_3040.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_4050.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_5060.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_6070.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_7080.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_8090.C create mode 100644 MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0005.ini similarity index 100% rename from MC/config/PWGEM/ini/GeneratorEMCocktail.ini rename to MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0005.ini diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0510.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0510.ini new file mode 100644 index 000000000..2e26ba807 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0510.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_0510_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_3040.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_3040.ini new file mode 100644 index 000000000..73960d0e8 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_3040.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_3040_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_4050.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_4050.ini new file mode 100644 index 000000000..25d78e2f1 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_4050.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_4050_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_5060.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_5060.ini new file mode 100644 index 000000000..4e74682df --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_5060.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_5060_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_6070.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_6070.ini new file mode 100644 index 000000000..0cc3b1065 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_6070.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_6070_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_7080.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_7080.ini new file mode 100644 index 000000000..524067a5e --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_7080.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_7080_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_8090.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_8090.ini new file mode 100644 index 000000000..596653424 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_8090.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_8090_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail.C deleted file mode 100644 index 600908d2e..000000000 --- a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail.C +++ /dev/null @@ -1,179 +0,0 @@ -int External() -{ - - std::string path{"o2sim_Kine.root"}; - TFile file(path.c_str(), "READ"); - if (file.IsZombie()) { - std::cerr << "Cannot open ROOT file " << path << "\n"; - return 1; - } - - auto tree = (TTree*)file.Get("o2sim"); - std::vector* tracks{}; - tree->SetBranchAddress("MCTrack", &tracks); - - int nElectrons = 0; - int nPositrons = 0; - int nPions = 0; - int nEtas = 0; - int nEtaPrimes = 0; - int nRhos = 0; - int nPhis = 0; - int nOmegas = 0; - int nJPsis = 0; - int nPhotons = 0; - int nElectronsFromPion = 0; - int nElectronsFromEta = 0; - int nElectronsFromEtaPrime = 0; - int nElectronsFromOmega = 0; - int nElectronsFromRho = 0; - int nElectronsFromPhi = 0; - int nElectronsFromJPsi = 0; - int nLeptonsToBeDone = 0; - auto nEvents = tree->GetEntries(); - for (int i = 0; i < nEvents; i++) { - tree->GetEntry(i); - for (auto& track : *tracks) { - bool hasMother = track.getMotherTrackId()>-1; - auto pdg = track.GetPdgCode(); - switch (pdg){ - case 11: - nElectrons++; - if (track.getToBeDone()){ - nLeptonsToBeDone++; - } - break; - case -11: - nPositrons++; - if (track.getToBeDone()){ - nLeptonsToBeDone++; - } - break; - case 111: - if (!hasMother) - nPions++; - break; - case 221: - if (!hasMother) - nEtas++; - break; - case 331: - if (!hasMother) - nEtaPrimes++; - break; - case 113: - if (!hasMother) - nRhos++; - break; - case 223: - if (!hasMother) - nOmegas++; - break; - case 333: - if (!hasMother) - nPhis++; - break; - case 443: - if (!hasMother) - nJPsis++; - break; - case 22: - nPhotons++; - } - if (pdg == 11){ - int imother = track.getMotherTrackId(); - if (imother > -1) { - auto mother = (*tracks)[imother]; - int mpdg = mother.GetPdgCode(); - switch (mpdg){ - case 111: - nElectronsFromPion++; - break; - case 221: - nElectronsFromEta++; - break; - case 331: - nElectronsFromEtaPrime++; - break; - case 113: - nElectronsFromRho++; - break; - case 223: - nElectronsFromOmega++; - break; - case 333: - nElectronsFromPhi++; - break; - case 443: - nElectronsFromJPsi++; - break; - default: - std::cout << "Found electron with mother pdg " << mpdg << "\n"; - } - } else { - std::cerr << "Found electron with no mother" << "\n"; - return 1; - } - } - } - } - int nMothers = nPions+nEtas+nEtaPrimes+nRhos+nOmegas+nPhis+nJPsis; - std::cout << "#Events: " << nEvents << "\n" - << "#Electrons: " << nElectrons << "\n" - << "#Positrons: " << nPositrons << "\n" - << "#Leptons: " << nElectrons+nPositrons << ", #LeptonsToDone: " << nLeptonsToBeDone << "\n" - << "#Photons: " << nPhotons << "\n" - << "#Pions: " << nPions << ", #ElectronsFromPion: " << nElectronsFromPion << "\n" - << "#Etas: " << nEtas << ", #ElectronsFromEta: " << nElectronsFromEta << "\n" - << "#EtaPrimes: " << nEtaPrimes << ", #ElectronsFromEtaPrime: " << nElectronsFromEtaPrime << "\n" - << "#Rhos: " << nRhos << ", #ElectronsFromRho: " << nElectronsFromRho << "\n" - << "#Omegas: " << nOmegas << ", #ElectronsFromOmega: " << nElectronsFromOmega << "\n" - << "#Phis: " << nPhis << ", #ElectronsFromPhi: " << nElectronsFromPhi << "\n" - << "#JPsis: " << nJPsis << ", #ElectronsFromJPsi: " << nElectronsFromJPsi << "\n"; - if (nElectrons == 0) { - std::cerr << "No electrons found\n"; - return 1; - } - if (nElectrons != nPositrons) { - std::cerr << "Number of electrons should match number of positrons\n"; - return 1; - } - if (nLeptonsToBeDone != nElectrons+nPositrons) { - std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; - return 1; - } - if (nMothers < nEvents) { - std::cerr << "The number of mother particles (pi0, eta, etaprime, rho, omega, phi, JPsi) must be at least the number of events\n"; - return 1; - } - if (nElectronsFromPion < nPions) { - std::cerr << "Number of of electrons from pions has to be at least the number of pions\n"; - return 1; - } - if (nElectronsFromEta < nEtas) { - std::cerr << "Number of of electrons from etas has to be at least the number of etas\n"; - return 1; - } - if (nElectronsFromEtaPrime < nEtaPrimes) { - std::cerr << "Number of of electrons from etaprimes has to be at least the number of etaprimes\n"; - return 1; - } - if (nElectronsFromRho < nRhos) { - std::cerr << "Number of of electrons from rhos has to be at least the number of rhos\n"; - return 1; - } - if (nElectronsFromOmega < nOmegas) { - std::cerr << "Number of of electrons from omegas has to be at least the number of omegas\n"; - return 1; - } - if (nElectronsFromPhi < nPhis) { - std::cerr << "Number of of electrons from phis has to be at least the number of phis\n"; - return 1; - } - if (nElectronsFromJPsi < nJPsis) { - std::cerr << "Number of of electrons from JPsis has to be at least the number of JPsis\n"; - return 1; - } - - return 0; -} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0005.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0005.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0005.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0510.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0510.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0510.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_3040.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_3040.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_3040.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_4050.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_4050.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_4050.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_5060.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_5060.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_5060.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_6070.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_6070.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_6070.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_7080.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_7080.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_7080.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_8090.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_8090.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_8090.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json b/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json index 6cc9cb0bd..8f724cdf3 100644 --- a/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json +++ b/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json @@ -1,283 +1,233 @@ { - "5TeV_0005_wRatio": { + "5TeV_0005_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", + "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio": { + "5TeV_0005_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 1.02, + "223": 0.84, + "331": 0.48 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", + "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<9.168)*(TMath::Max(TMath::Max(0.00147786*TMath::Power((exp(- -0.297384*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0282388*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.464407/0.00147786,-1./1.14468)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0102013),-1.14468)/TMath::Power((exp(- -0.297384*x-0.0282388*x*x)+x/0.0102013),-1.14468)+2.16163*TMath::Landau(x,3.97083,1.44648),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267)),TMath::Max(0.000175259*TMath::Power((exp(- -2.1325*sqrt(x*x+0.547*0.547-0.139*0.139)-0.591882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.482288/0.000175259,-1./15.7215)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.027171),-15.7215)/TMath::Power((exp(- -2.1325*x-0.591882*x*x)+x/0.027171),-15.7215)+1.7109*TMath::Landau(x,2.36532,0.973179),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267))))+(x>=9.168)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" }, - "5TeV_3040_wRatio": { + "5TeV_0005_wRatio_etatest_ratiosdown": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 0.68, + "223": 0.56, + "331": 0.32 }, - "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", - "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", - "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", - "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", - "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" + "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", + "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" }, - "5TeV_4050_wRatio": { + "5TeV_0005_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", - "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613))", + "221_pt": "(TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_4050_wRatio_pi0up": { + "5TeV_0005_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377))", - "221_pt": "(TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377)))*((0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279))", + "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_3040_wRatio_pi0up": { + "5TeV_0510_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121))", - "221_pt": "(TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121)))*((0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", - "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", - "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", - "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" + "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", + "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio_pi0up": { + "5TeV_0510_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 1.02, + "223": 0.84, + "331": 0.48 }, - "111_pt": "TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867))", - "221_pt": "(TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867)))*(((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", + "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<10.278)*(TMath::Max(TMath::Max(0.000295533*TMath::Power((exp(- -1.60043*sqrt(x*x+0.547*0.547-0.139*0.139)-0.655985*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.500931/0.000295533,-1./16.3545)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.130844),-16.3545)/TMath::Power((exp(- -1.60043*x-0.655985*x*x)+x/0.130844),-16.3545)+1.5704*TMath::Landau(x,2.17776,0.921819),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192)),TMath::Max(3.85365e-05*TMath::Power((exp(- -0.50908*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0438035*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.463429/3.85365e-05,-1./6.0698)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0472676),-6.0698)/TMath::Power((exp(- -0.50908*x-0.0438035*x*x)+x/0.0472676),-6.0698)+2.34475*TMath::Landau(x,3.86817,1.59145),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192))))+(x>=10.278)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" }, - "5TeV_0005_wRatio_pi0up": { + "5TeV_0510_wRatio_etatest_ratiosdown": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 0.68, + "223": 0.56, + "331": 0.32 }, - "111_pt": "TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613))", - "221_pt": "(TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613)))*(((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", + "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" }, - "5TeV_0005_wRatio_pi0down": { + "5TeV_0510_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279))", - "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*(((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867))", + "221_pt": "(TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio_pi0down": { + "5TeV_0510_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, "111_pt": "TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804))", - "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*(((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", + "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_3040_wRatio_pi0down": { + "5TeV_3040_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624))", - "221_pt": "(TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624)))*((0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", + "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", + "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_4050_wRatio_pi0down": { + "5TeV_3040_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361))", - "221_pt": "(TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361)))*((0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" - }, - "5TeV_4050_wRatio_ratiosdown": { - "histoMtScaleFactor": { - "113": 0.68, - "223": 0.56, - "331": 0.32 + "113": 1.02, + "223": 0.84, + "331": 0.48 }, - "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", - "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)+(x>0.5)*0.8*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985))", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", + "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(((x<11.3582)*(TMath::Max(TMath::Max(3.62635e-06*TMath::Power((exp(-1.04848*sqrt(x*x+0.547*0.547-0.139*0.139)-0.00760898*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.494194/3.62635e-06,-1./6.52441)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.37753),-6.52441)/TMath::Power((exp(-1.04848*x-0.00760898*x*x)+x/1.37753),-6.52441)+1.85024*TMath::Landau(x,2.3343,0.982346),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394)),TMath::Max(0.00152416*TMath::Power((exp(-1.50417*sqrt(x*x+0.547*0.547-0.139*0.139)- -0.0524029*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496824/0.00152416,-1./3.48956)*sqrt(x*x+0.547*0.547-0.139*0.139)/8.34972),-3.48956)/TMath::Power((exp(-1.50417*x- -0.0524029*x*x)+x/8.34972),-3.48956)+1.90397*TMath::Landau(x,2.2369,0.884653),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394))))+(x>=11.3582)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))))", + "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)+(x>0.5)*1.2*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071))", + "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", + "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", + "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_3040_wRatio_ratiosdown": { + "5TeV_3040_wRatio_etatest_ratiosdown": { "histoMtScaleFactor": { "113": 0.68, "223": 0.56, "331": 0.32 }, "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", - "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", + "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(((x<6.7544)*(0.9*(TMath::Min(TMath::Min(0.000624633*TMath::Power((exp(- -0.139403*sqrt(x*x+0.547*0.547-0.139*0.139)-0.883882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.000624633,-1./91.7456)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.27557),-91.7456)/TMath::Power((exp(- -0.139403*x-0.883882*x*x)+x/1.27557),-91.7456)+1.93275*TMath::Landau(x,2.96282,1.17967),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)),TMath::Min(0.0105235*TMath::Power((exp(- -0.843626*sqrt(x*x+0.547*0.547-0.139*0.139)-1.26105*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.450001/0.0105235,-1./22.4747)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.776751),-22.4747)/TMath::Power((exp(- -0.843626*x-1.26105*x*x)+x/0.776751),-22.4747)+0.774392*TMath::Landau(x,2.71895,1.26325),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)))))+(x>=6.7544)*0.426))", "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)+(x>0.5)*0.8*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071))", "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_0510_wRatio_ratiosdown": { - "histoMtScaleFactor": { - "113": 0.68, - "223": 0.56, - "331": 0.32 - }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" - }, - "5TeV_0005_wRatio_ratiosdown": { - "histoMtScaleFactor": { - "113": 0.68, - "223": 0.56, - "331": 0.32 - }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" - }, - "5TeV_0005_wRatio_ratiosup": { - "histoMtScaleFactor": { - "113": 1.02, - "223": 0.84, - "331": 0.48 - }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" - }, - "5TeV_0510_wRatio_ratiosup": { + "5TeV_3040_wRatio_etatest_pi0up": { "histoMtScaleFactor": { - "113": 1.02, - "223": 0.84, - "331": 0.48 + "113": 0.85, + "223": 0.7, + "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" + "111_pt": "TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121))", + "221_pt": "(TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", + "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", + "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", + "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_3040_wRatio_ratiosup": { + "5TeV_3040_wRatio_etatest_pi0down": { "histoMtScaleFactor": { - "113": 1.02, - "223": 0.84, - "331": 0.48 + "113": 0.85, + "223": 0.7, + "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", - "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861)", - "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)+(x>0.5)*1.2*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071))", + "111_pt": "TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624))", + "221_pt": "(TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_4050_wRatio_ratiosup": { + "5TeV_4050_wRatio_etatest": { + "histoMtScaleFactor": { + "113": 0.85, + "223": 0.7, + "331": 0.4 + }, + "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", + "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + }, + "5TeV_4050_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { "113": 1.02, "223": 0.84, "331": 0.48 }, "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", - "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236)", + "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(((x<11.3582)*(TMath::Max(TMath::Max(3.62635e-06*TMath::Power((exp(-1.04848*sqrt(x*x+0.547*0.547-0.139*0.139)-0.00760898*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.494194/3.62635e-06,-1./6.52441)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.37753),-6.52441)/TMath::Power((exp(-1.04848*x-0.00760898*x*x)+x/1.37753),-6.52441)+1.85024*TMath::Landau(x,2.3343,0.982346),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394)),TMath::Max(0.00152416*TMath::Power((exp(-1.50417*sqrt(x*x+0.547*0.547-0.139*0.139)- -0.0524029*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496824/0.00152416,-1./3.48956)*sqrt(x*x+0.547*0.547-0.139*0.139)/8.34972),-3.48956)/TMath::Power((exp(-1.50417*x- -0.0524029*x*x)+x/8.34972),-3.48956)+1.90397*TMath::Landau(x,2.2369,0.884653),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394))))+(x>=11.3582)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))))", "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)+(x>0.5)*1.2*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985))", "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" }, - "5TeV_0005_wRatio_etatest": { + "5TeV_4050_wRatio_etatest_ratiosdown": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, - "5TeV_0005_wRatio_etatestup": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<9.168)*(TMath::Max(TMath::Max(0.00147786*TMath::Power((exp(- -0.297384*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0282388*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.464407/0.00147786,-1./1.14468)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0102013),-1.14468)/TMath::Power((exp(- -0.297384*x-0.0282388*x*x)+x/0.0102013),-1.14468)+2.16163*TMath::Landau(x,3.97083,1.44648),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267)),TMath::Max(0.000175259*TMath::Power((exp(- -2.1325*sqrt(x*x+0.547*0.547-0.139*0.139)-0.591882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.482288/0.000175259,-1./15.7215)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.027171),-15.7215)/TMath::Power((exp(- -2.1325*x-0.591882*x*x)+x/0.027171),-15.7215)+1.7109*TMath::Landau(x,2.36532,0.973179),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267))))+(x>=9.168)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, - "5TeV_0005_wRatio_etatestdown": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 0.68, + "223": 0.56, + "331": 0.32 }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", + "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(((x<6.7544)*(0.9*(TMath::Min(TMath::Min(0.000624633*TMath::Power((exp(- -0.139403*sqrt(x*x+0.547*0.547-0.139*0.139)-0.883882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.000624633,-1./91.7456)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.27557),-91.7456)/TMath::Power((exp(- -0.139403*x-0.883882*x*x)+x/1.27557),-91.7456)+1.93275*TMath::Landau(x,2.96282,1.17967),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)),TMath::Min(0.0105235*TMath::Power((exp(- -0.843626*sqrt(x*x+0.547*0.547-0.139*0.139)-1.26105*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.450001/0.0105235,-1./22.4747)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.776751),-22.4747)/TMath::Power((exp(- -0.843626*x-1.26105*x*x)+x/0.776751),-22.4747)+0.774392*TMath::Landau(x,2.71895,1.26325),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)))))+(x>=6.7544)*0.426))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)+(x>0.5)*0.8*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985))", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" }, - "5TeV_0510_wRatio_etatest": { + "5TeV_4050_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377))", + "221_pt": "(TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" }, - "5TeV_0510_wRatio_etatestup": { + "5TeV_4050_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<10.278)*(TMath::Max(TMath::Max(0.000295533*TMath::Power((exp(- -1.60043*sqrt(x*x+0.547*0.547-0.139*0.139)-0.655985*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.500931/0.000295533,-1./16.3545)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.130844),-16.3545)/TMath::Power((exp(- -1.60043*x-0.655985*x*x)+x/0.130844),-16.3545)+1.5704*TMath::Landau(x,2.17776,0.921819),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192)),TMath::Max(3.85365e-05*TMath::Power((exp(- -0.50908*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0438035*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.463429/3.85365e-05,-1./6.0698)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0472676),-6.0698)/TMath::Power((exp(- -0.50908*x-0.0438035*x*x)+x/0.0472676),-6.0698)+2.34475*TMath::Landau(x,3.86817,1.59145),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192))))+(x>=10.278)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361))", + "221_pt": "(TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" }, "5TeV_0005_wRatio_etatestcenter_pp13": { "histoMtScaleFactor": { @@ -309,26 +259,6 @@ "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((0.000946307*TMath::Power((exp(- -0.678673*sqrt(x*x+0.547*0.547-0.139*0.139)-1.46197*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.475252/0.000946307,-1./42.0453)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.718978),-42.0453)/TMath::Power((exp(- -0.678673*x-1.46197*x*x)+x/0.718978),-42.0453)+1.5622*TMath::Landau(x,2.61642,1.08512)))", "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0005_wRatio_etatestpi0down": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279))", - "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, - "5TeV_0005_wRatio_etatestpi0up": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613))", - "221_pt": "(TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, "5TeV_0005_wRatio_etatestpi0up_pp13": { "histoMtScaleFactor": { "113": 0.85, @@ -349,26 +279,6 @@ "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*((0.000376932*TMath::Power((exp(-0.821512*sqrt(x*x+0.547*0.547-0.139*0.139)-0.143837*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.4615/0.000376932,-1./13.0537)*sqrt(x*x+0.547*0.547-0.139*0.139)/4.58538),-13.0537)/TMath::Power((exp(-0.821512*x-0.143837*x*x)+x/4.58538),-13.0537)+1.65536*TMath::Landau(x,2.12278,0.816391)))", "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio_etatestpi0down": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804))", - "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, - "5TeV_0510_wRatio_etatestpi0up": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867))", - "221_pt": "(TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, "5TeV_0510_wRatio_etatestpi0up_pp13": { "histoMtScaleFactor": { "113": 0.85, @@ -389,16 +299,6 @@ "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*((0.000946307*TMath::Power((exp(- -0.678673*sqrt(x*x+0.547*0.547-0.139*0.139)-1.46197*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.475252/0.000946307,-1./42.0453)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.718978),-42.0453)/TMath::Power((exp(- -0.678673*x-1.46197*x*x)+x/0.718978),-42.0453)+1.5622*TMath::Landau(x,2.61642,1.08512)))", "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio_etatestdown": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, "5TeV_0510_wRatio_etatestdown_pp13": { "histoMtScaleFactor": { "113": 0.85, diff --git a/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json b/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json new file mode 100644 index 000000000..937481744 --- /dev/null +++ b/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json @@ -0,0 +1,282 @@ +{ + "5TeV_5060_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931))))", + "223_pt": "(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225))))", + "223_pt": "(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(1.2*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189))" + }, + "5TeV_5060_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))))", + "113_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.8*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189))" + }, + "5TeV_6070_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(1.2*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258))" + }, + "5TeV_6070_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))))", + "113_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.8*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258))" + }, + "5TeV_7080_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(1.2*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634))" + }, + "5TeV_7080_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))))", + "113_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.8*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634))" + }, + "5TeV_8090_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(1.2*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734))" + }, + "5TeV_8090_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))))", + "113_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.8*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734))" + } +} From 999452744feb0654274f8cc4e0765ce3d148ef17 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 6 Feb 2026 17:23:04 +0100 Subject: [PATCH 231/362] Set TPCLoopers as debug generator (#2265) This change makes it possible to use the external generator for debug purposes. --- .../common/external/generator/TPCLoopers.C | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/MC/config/common/external/generator/TPCLoopers.C b/MC/config/common/external/generator/TPCLoopers.C index eb7916af8..8253fe091 100644 --- a/MC/config/common/external/generator/TPCLoopers.C +++ b/MC/config/common/external/generator/TPCLoopers.C @@ -7,12 +7,19 @@ #include "CCDB/CcdbApi.h" #include "DetectorsRaw/HBFUtils.h" +//** This external generator is now used for development purposes only. +//** Fast simulated TPC loopers are automatically integrated as detector effect in O2 +//** starting from the O2PDPSuite::MC-prod-2026-v3-1 official release (05/02/2026) +//** Previous cocktails configurations using this generator must not be used anymore for recent tags, +//** as they will increase the default TPC loopers contribution. +//** For support: Marco Giacalone . + // Static Ort::Env instance for multiple onnx model loading static Ort::Env global_env(ORT_LOGGING_LEVEL_WARNING, "GlobalEnv"); // This class is responsible for loading the scaler parameters from a JSON file // and applying the inverse transformation to the generated data. -struct Scaler +struct Scaler_debug { std::vector normal_min; std::vector normal_max; @@ -71,10 +78,10 @@ private: }; // This class loads the ONNX model and generates samples using it. -class ONNXGenerator +class ONNXGenerator_debug { public: - ONNXGenerator(Ort::Env &shared_env, const std::string &model_path) + ONNXGenerator_debug(Ort::Env &shared_env, const std::string &model_path) : env(shared_env), session(env, model_path.c_str(), Ort::SessionOptions{}) { // Create session options @@ -129,12 +136,12 @@ namespace o2 namespace eventgen { -class GenTPCLoopers : public Generator +class GenTPCLoopers_debug : public Generator { public: - GenTPCLoopers(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", - std::string poisson = "poisson.csv", std::string gauss = "gauss.csv", std::string scaler_pair = "scaler_pair.json", - std::string scaler_compton = "scaler_compton.json") + GenTPCLoopers_debug(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string poisson = "poisson.csv", std::string gauss = "gauss.csv", std::string scaler_pair = "scaler_pair.json", + std::string scaler_compton = "scaler_compton.json") { // Checking if the model files exist and are not empty std::ifstream model_file[2]; @@ -200,11 +207,11 @@ class GenTPCLoopers : public Generator mGaussSet = true; } } - mONNX_pair = std::make_unique(global_env, model_pairs); - mScaler_pair = std::make_unique(); + mONNX_pair = std::make_unique(global_env, model_pairs); + mScaler_pair = std::make_unique(); mScaler_pair->load(scaler_pair); - mONNX_compton = std::make_unique(global_env, model_compton); - mScaler_compton = std::make_unique(); + mONNX_compton = std::make_unique(global_env, model_compton); + mScaler_compton = std::make_unique(); mScaler_compton->load(scaler_compton); Generator::setTimeUnit(1.0); Generator::setPositionUnit(1.0); @@ -525,10 +532,10 @@ class GenTPCLoopers : public Generator } private: - std::unique_ptr mONNX_pair = nullptr; - std::unique_ptr mONNX_compton = nullptr; - std::unique_ptr mScaler_pair = nullptr; - std::unique_ptr mScaler_compton = nullptr; + std::unique_ptr mONNX_pair = nullptr; + std::unique_ptr mONNX_compton = nullptr; + std::unique_ptr mScaler_pair = nullptr; + std::unique_ptr mScaler_compton = nullptr; double mPoisson[3] = {0.0, 0.0, 0.0}; // Mu, Min and Max of Poissonian double mGauss[4] = {0.0, 0.0, 0.0, 0.0}; // Mean, Std, Min, Max std::vector> mGenPairs; @@ -629,7 +636,7 @@ FairGenerator * } model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; - auto generator = new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, poisson, gauss, scaler_pair, scaler_compton); + auto generator = new o2::eventgen::GenTPCLoopers_debug(model_pairs, model_compton, poisson, gauss, scaler_pair, scaler_compton); generator->SetNLoopers(nloopers_pairs, nloopers_compton); generator->SetMultiplier(mult); return generator; @@ -700,7 +707,7 @@ Generator_TPCLoopersFlat(std::string model_pairs = "tpcloopmodel.onnx", std::str } model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; - auto generator = new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); + auto generator = new o2::eventgen::GenTPCLoopers_debug(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); generator->setFractionPairs(fraction_pairs); generator->setFlatGas(flat_gas, loops_num, nloopers_orbit); return generator; @@ -772,7 +779,7 @@ Generator_TPCLoopersOrbitRef(std::string model_pairs = "tpcloopmodel.onnx", std: model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; nclxrate = isAlien[2] || isCCDB[2] ? local_names[2] : nclxrate; - auto generator = new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); + auto generator = new o2::eventgen::GenTPCLoopers_debug(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); generator->SetRate(nclxrate, isPbPb, intrate); // Adjust can be negative (-1 maximum) or positive to decrease or increase the number of loopers per orbit generator->SetAdjust(adjust); From 81286d288bb5b6db993c9ff078a34a4805b686d0 Mon Sep 17 00:00:00 2001 From: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:58:22 +0100 Subject: [PATCH 232/362] [PWGDQ] Shifting CM frame of generated charmonia in pO (#2262) * [PWGDQ] Extending rapidity range for charmonia in pO * Shifting generated rapidity * Same for Psi2S * fixing mistake and ading missing test * dummy commit --------- Co-authored-by: Maurice Coquet --- .../generator/GeneratorPromptCharmonia.C | 14 ++-- ...edPromptCharmoniaMidy_TriggerGap_pO96TeV.C | 84 +++++++++++++++++++ 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.C diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index bfca9acca..86a9fd47b 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -941,7 +941,7 @@ class O2_GeneratorParamJpsipp96TeV : public GeneratorTGenerator paramJpsi = new GeneratorParam(1, -1, PtJPsipp96TeV, YJPsipp96TeV, V2JPsipp96TeV, IpJPsipp96TeV); paramJpsi->SetMomentumRange(0., 1.e6); paramJpsi->SetPtRange(0, 999.); - paramJpsi->SetYRange(-4.2, -2.3); + paramJpsi->SetYRange(-4.2, -2.0); paramJpsi->SetPhiRange(0., 360.); paramJpsi->SetDecayer(new TPythia6Decayer()); paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed @@ -979,13 +979,15 @@ class O2_GeneratorParamJpsipp96TeV : public GeneratorTGenerator //-------------------------------------------------------------------------// static Double_t YJPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) { - // Parameters extrapolated linearly between 5 TeV and 13 TeV as a function of log(sqrt(s)) + // Parameters extrapolated linearly between 5 TeV and 13 TeV as a function of log(sqrt(s)), shifted by a rapidity boost dy=0.35 Double_t y = *py; + Double_t deltaY = 0.35; + Double_t yCM = y - deltaY; Float_t p0, p1, p2; p0 = 1; p1 = 0.0107769; p2 = 2.98205; - return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((yCM - p1) / p2), 2)); } //-------------------------------------------------------------------------// @@ -1014,7 +1016,7 @@ class O2_GeneratorParamPsipp96TeV : public GeneratorTGenerator paramPsi = new GeneratorParam(1, -1, PtPsipp96TeV, YPsipp96TeV, V2Psipp96TeV, IpPsipp96TeV); paramPsi->SetMomentumRange(0., 1.e6); paramPsi->SetPtRange(0, 999.); - paramPsi->SetYRange(-4.2, -2.3); + paramPsi->SetYRange(-4.2, -2.0); paramPsi->SetPhiRange(0., 360.); paramPsi->SetDecayer(new TPythia6Decayer()); paramPsi->SetForceDecay(kNoDecay); // particle left undecayed @@ -1054,11 +1056,13 @@ class O2_GeneratorParamPsipp96TeV : public GeneratorTGenerator { // Taking same parameters as Psi(2S) at 13 TeV Double_t y = *py; + Double_t deltaY = 0.35; + Double_t yCM = y - deltaY; Float_t p0, p1, p2; p0 = 1; p1 = 0; p2 = 2.98887; - return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((yCM - p1) / p2), 2)); } //-------------------------------------------------------------------------// diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From aa2877a3fadda141ae1361311d7745580cf7fdbf Mon Sep 17 00:00:00 2001 From: lgansbartl Date: Fri, 6 Feb 2026 21:11:33 +0100 Subject: [PATCH 233/362] [PWGEM] Add configs for Dalitz-decay MC (#2263) * first comit * Fix missing new line * Add Pythia8 Forced Dalitz test config for pp 13.6 TeV * update * update --------- Co-authored-by: Laura Gansbartl --- .../ini/pythia8_pp_13600_ForcedDalitz.ini | 5 +++ .../ini/tests/pythia8_pp_13600_ForcedDalitz.C | 39 +++++++++++++++++++ .../PWGEM/pythia8/decayer/force_dummy.cfg | 0 .../generator/configPythia_ForcedDalitz.cfg | 21 ++++++++++ 4 files changed, 65 insertions(+) create mode 100644 MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini create mode 100644 MC/config/PWGEM/ini/tests/pythia8_pp_13600_ForcedDalitz.C create mode 100644 MC/config/PWGEM/pythia8/decayer/force_dummy.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini b/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini new file mode 100644 index 000000000..17caba124 --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini @@ -0,0 +1,5 @@ +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_dummy.cfg diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_13600_ForcedDalitz.C b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_ForcedDalitz.C new file mode 100644 index 000000000..4829e48d5 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_ForcedDalitz.C @@ -0,0 +1,39 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + + return 0; + } + + int pythia8() + { + return External(); + } + \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/decayer/force_dummy.cfg b/MC/config/PWGEM/pythia8/decayer/force_dummy.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg b/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg new file mode 100644 index 000000000..d51c6f20e --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg @@ -0,0 +1,21 @@ +ProcessLevel:all on + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10 + + +#decay eta -> e+ e- gamma BR = 100% +221:onMode = off +221:onIfMatch = 22 11 -11 +#221:addChannel = 1 1 0 22 11 -11 + +#decay pi0 -> e+ e- gamma BR = 10% +111:addChannel = 1 0.10 0 22 11 -11" From ff554106ad9dfcd5a89ea4908252cdac311fd246 Mon Sep 17 00:00:00 2001 From: mbroz84 Date: Sun, 8 Feb 2026 14:55:58 +0100 Subject: [PATCH 234/362] New Tau decays (#2267) --- .../{TAUTAU.EL3PI.DEC => TAUTAU.6PI.DEC} | 2 +- .../generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC | 9 +++++++++ .../generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC | 9 +++++++++ .../generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC | 9 +++++++++ .../generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC | 7 ------- .../generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC | 9 +++++++++ MC/config/PWGUD/external/generator/GeneratorStarlight.C | 7 +++++-- .../external/generator/GeneratorStarlightToEvtGen.C | 7 +++++-- 8 files changed, 47 insertions(+), 12 deletions(-) rename MC/config/PWGUD/external/generator/DecayTablesEvtGen/{TAUTAU.EL3PI.DEC => TAUTAU.6PI.DEC} (58%) create mode 100644 MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC create mode 100644 MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC create mode 100644 MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC delete mode 100644 MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC create mode 100644 MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.EL3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.6PI.DEC similarity index 58% rename from MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.EL3PI.DEC rename to MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.6PI.DEC index 86fed720d..bbe75c401 100644 --- a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.EL3PI.DEC +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.6PI.DEC @@ -1,5 +1,5 @@ Decay tau- -1.0 e- anti-nu_e nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +1.0 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] Enddecay Decay tau+ 1.0 pi+ pi+ pi- anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC new file mode 100644 index 000000000..b8c453c67 --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 e- anti-nu_e nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.5 mu- anti-nu_mu nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +Enddecay +Decay tau+ +0.5 pi+ pi+ pi- anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 anti-nu_tau pi+ pi- pi+ pi0 PHSP; +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC new file mode 100644 index 000000000..8b45742ad --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 nu_tau pi- pi+ pi- pi0 PHSP; +Enddecay +Decay tau+ +0.5 e+ anti-nu_tau nu_e PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.5 mu+ anti-nu_tau nu_mu PHOTOS TAULNUNU; #[Reconstructed PDG2011] +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC new file mode 100644 index 000000000..a23f6bd84 --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 pi- nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.5 pi- pi0 nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400; #[Reconstructed PDG2011] +Enddecay +Decay tau+ +0.5 pi+ pi+ pi- anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 anti-nu_tau pi+ pi- pi+ pi0 PHSP; +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC deleted file mode 100644 index b17413d5c..000000000 --- a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC +++ /dev/null @@ -1,7 +0,0 @@ -Decay tau- -1.0 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] -Enddecay -Decay tau+ -1.0 e+ anti-nu_tau nu_e PHOTOS TAULNUNU; #[Reconstructed PDG2011] -Enddecay -End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC new file mode 100644 index 000000000..76bc14f80 --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 nu_tau pi- pi+ pi- pi0 PHSP; +Enddecay +Decay tau+ +0.5 pi+ anti-nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.5 pi+ pi0 anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400; #[Reconstructed PDG2011] +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlight.C b/MC/config/PWGUD/external/generator/GeneratorStarlight.C index 1cf323ff9..b2069c16b 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlight.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlight.C @@ -151,8 +151,11 @@ class GeneratorStarlight_class : public Generator {"kIncohUpsilonToEl", 4, 553011, 20, -1.0, -1.0, 553, 0 }, // {"kDpmjetSingleA", 5, 113, 20, -1.0, -1.0, -1, 0 }, // {"kDpmjetSingleC", 5, 113, 20, -1.0, -1.0, -1, 0 }, // - {"kTauLowToEl3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV - {"kTauLowToPo3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToL+3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToL-3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToPi+3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToPi-3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowTo6Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV {"kTauLowToElMu", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV {"kTauLowToElPiPi0", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV {"kTauLowToPoPiPi0", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C b/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C index dcb9a967f..9d59d3c44 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C @@ -48,8 +48,11 @@ FairGenerator* else if (configuration.find("RhoPrime") != std::string::npos) gen->SetDecayTable(Form("%s/RHOPRIME.RHOPIPI.DEC",pathO2.Data())); else if (configuration.find("OmegaTo3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/OMEGA.3PI.DEC",pathO2.Data())); else if (configuration.find("JpsiToElRad") != std::string::npos) gen->SetDecayTable(Form("%s/JPSI.EE.DEC",pathO2.Data())); - else if (configuration.find("ToEl3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.EL3PI.DEC",pathO2.Data())); - else if (configuration.find("ToPo3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.PO3PI.DEC",pathO2.Data())); + else if (configuration.find("ToL+3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LP3PI.DEC",pathO2.Data())); + else if (configuration.find("ToL-3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LN3PI.DEC",pathO2.Data())); + else if (configuration.find("ToPi+3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LP3PI.DEC",pathO2.Data())); + else if (configuration.find("ToPi-3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LN3PI.DEC",pathO2.Data())); + else if (configuration.find("To6Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.6PI.DEC",pathO2.Data())); else if (configuration.find("ToElMu") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.ELMU.DEC",pathO2.Data())); else if (configuration.find("ToElPiPi0") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.ELPI.DEC",pathO2.Data())); else if (configuration.find("ToPoPiPi0") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.POPI.DEC",pathO2.Data())); From c0386a167219a1c023c989708d77ca72c4bdd5ed Mon Sep 17 00:00:00 2001 From: Raymond Ehlers Date: Mon, 9 Feb 2026 02:38:27 -0800 Subject: [PATCH 235/362] Update 13.6 TeV config to use MB gap 2 (#2266) * Update 13.6 TeV config to use gap 2 With the improved understanding of track migration, we can reduce the gap to 2 for all productions * Corresponding update of test to use gap 2 * Unify naming scheeme to include sqrt_s This makes the difference between the 5.36 and 13.6 much clearer * Fix typo in name * Corresponding name update --- ...pgen5_hook.ini => GeneratorJE_gapgen2_hook_pp13600GeV.ini} | 4 ++-- ...E_gapgen5_hook.C => GeneratorJE_gapgen2_hook_pp13600GeV.C} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename MC/config/PWGGAJE/ini/{GeneratorJE_gapgen5_hook.ini => GeneratorJE_gapgen2_hook_pp13600GeV.ini} (81%) rename MC/config/PWGGAJE/ini/tests/{GeneratorJE_gapgen5_hook.C => GeneratorJE_gapgen2_hook_pp13600GeV.C} (97%) diff --git a/MC/config/PWGGAJE/ini/GeneratorJE_gapgen5_hook.ini b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen2_hook_pp13600GeV.ini similarity index 81% rename from MC/config/PWGGAJE/ini/GeneratorJE_gapgen5_hook.ini rename to MC/config/PWGGAJE/ini/GeneratorJE_gapgen2_hook_pp13600GeV.ini index 947b04251..ff17ff484 100644 --- a/MC/config/PWGGAJE/ini/GeneratorJE_gapgen5_hook.ini +++ b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen2_hook_pp13600GeV.ini @@ -1,8 +1,8 @@ -### jet-jet production with MB Gap 5 +### jet-jet production with MB Gap 2 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C -funcName = getGeneratorPythia8GapGenJE(5,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet.cfg") +funcName = getGeneratorPythia8GapGenJE(2,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet.cfg") [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet.cfg diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen5_hook.C b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C similarity index 97% rename from MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen5_hook.C rename to MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C index 5ac7f5173..6f32003fe 100644 --- a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen5_hook.C +++ b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - float ratioTrigger = 1./5; // one event triggered out of 5 + float ratioTrigger = 1./2; // one event triggered out of 5 TFile file(path.c_str(), "READ"); From bc6175062ab6b847572b3537a4318cebddaf1a9d Mon Sep 17 00:00:00 2001 From: smaff92 <33285879+smaff92@users.noreply.github.com> Date: Mon, 9 Feb 2026 21:17:26 +0900 Subject: [PATCH 236/362] =?UTF-8?q?Files=20required=20for=20an=20O2DPG=20p?= =?UTF-8?q?roduction=20of=20prompt-photon=20MC,=20with=20a=20ga=E2=80=A6?= =?UTF-8?q?=20(#2255)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Files required for an O2DPG production of prompt-photon MC, with a gap trigger * Changed production ratio in testing files --- .../generator_pythia8_gaptrigger_hook.C | 279 ++++++++++++++++++ ...or_pythia8_gaptrigger_promptphotons_hook.C | 279 ++++++++++++++++++ .../PWGGAJE/ini/hook_prompt_gamma_gap.ini | 7 + MC/config/PWGGAJE/ini/prompt_gamma_gap.ini | 7 + .../PWGGAJE/ini/tests/hook_prompt_gamma_gap.C | 71 +++++ .../PWGGAJE/ini/tests/prompt_gamma_gap.C | 71 +++++ .../generator/pythia8_promptphoton.cfg | 21 ++ 7 files changed, 735 insertions(+) create mode 100644 MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C create mode 100644 MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C create mode 100644 MC/config/PWGGAJE/ini/hook_prompt_gamma_gap.ini create mode 100644 MC/config/PWGGAJE/ini/prompt_gamma_gap.ini create mode 100644 MC/config/PWGGAJE/ini/tests/hook_prompt_gamma_gap.C create mode 100644 MC/config/PWGGAJE/ini/tests/prompt_gamma_gap.C create mode 100644 MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg diff --git a/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C new file mode 100644 index 000000000..bfcd55f45 --- /dev/null +++ b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C @@ -0,0 +1,279 @@ +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +///#include "FairGenerator.h" +//#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "MC/config/PWGGAJE/hooks/prompt_gamma_hook.C" +//#include "TRandom.h" +//#include +// +//#include +//#include + +// Prompt-photon custom event generator +// that alternates between 2 gun generators. This is the non-triggered version, without hooks, and would work with any PYTHIA cfg +// set up to inject MB events alongside prompt-photon events +// in 'MB-gap' mode. +// The number of MB events injected, and the PYTHIA config +// for each event type is defined by the user in the .ini +// generator file (e.g. GeneratorJE_gapgen5_hook.ini) +// +// Author: Adrian Fereydon Nassirpour (adrian.fereydon.nassirpour@cern.ch), based on code from Jaime Norman (jaime.norman@cern.ch) + +namespace o2 +{ +namespace eventgen +{ + +using namespace Pythia8; + + +/// A very simple gap generator alternating between 2 different particle guns +class GeneratorPythia8GapGenJEMB : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapGenJEMB(int inputTriggerRatio = 5,std::string pathMB = "",std::string pathSignal = "") { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName(TString(pathMB)); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(TString(pathSignal)); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + // Here we could loada hook, but we want to run MB for this production + // Pythia8::UserHooks *hook = pythia8_userhooks_promptgamma(); + // pythiaObjectSignal.setUserHooksPtr(std::shared_ptr(hook)); + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + // Add Sub generators + addSubGenerator(0, "MB generator"); + addSubGenerator(1, "jet-jet generator"); + } + + + /// Destructor + ~GeneratorPythia8GapGenJEMB() = default; + + void setUsedSeed(unsigned int seed) + { + mUsedSeed = seed; + }; + unsigned int getUsedSeed() const + { + return mUsedSeed; + }; + + bool generateEvent() override + { + + // Simple straightforward check to alternate generators + mPythia.event.reset(); + + if (mGeneratedEvents % mInverseTriggerRatio == 0) { + LOG(info) << "Event " << mGeneratedEvents << ", generate signal event"; + // Generate event of interest + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectSignal.next(); + } + mPythia.event = pythiaObjectSignal.event; + setEventHeaderProperties(pythiaObjectSignal); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectSignal); + notifySubGenerator(1); + } + else { + LOG(info) << "Event " << mGeneratedEvents << ", generate mb event"; + // Generate minimum-bias event + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + setEventHeaderProperties(pythiaObjectMinimumBias); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectMinimumBias); + notifySubGenerator(0); + } + mGeneratedEvents++; + return true; + } + + // for testing + void printEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + LOG(info) << "Info name = " << pythiaObject.info.name(); + LOG(info) << "Info code = " << pythiaObject.info.code(); + LOG(info) << "Info weight = " << pythiaObject.info.weight(); + LOG(info) << "Info id1pdf = " << pythiaObject.info.id1pdf(); + LOG(info) << "Info id2pdf = " << pythiaObject.info.id2pdf(); + + LOG(info) << "Info x1pdf = " << pythiaObject.info.x1pdf(); + LOG(info) << "Info x2pdf = " << pythiaObject.info.x2pdf(); + LOG(info) << "Info QFac = " << pythiaObject.info.QFac(); + LOG(info) << "Info pdf1 = " << pythiaObject.info.pdf1(); + LOG(info) << "Info pdf2 = " << pythiaObject.info.pdf2(); + + // Set cross section + LOG(info) << "Info sigmaGen = " << pythiaObject.info.sigmaGen(); + LOG(info) << "Info sigmaErr = " << pythiaObject.info.sigmaErr(); + + // Set event scale and nMPI + LOG(info) << "Info QRen = " << pythiaObject.info.QRen(); + LOG(info) << "Info nMPI = " << pythiaObject.info.nMPI(); + + // Set accepted and attempted values + LOG(info) << "Info accepted = " << pythiaObject.info.nAccepted(); + LOG(info) << "Info attempted = " << pythiaObject.info.nTried(); + + // Set weights (overrides cross-section for each weight) + size_t iw = 0; + auto xsecErr = pythiaObject.info.weightContainerPtr->getTotalXsecErr(); + for (auto w : pythiaObject.info.weightContainerPtr->getTotalXsec()) { + std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + LOG(info) << "Info weight by index = " << pythiaObject.info.weightValueByIndex(iw); + iw++; + } + + } + + // in order to save the event weight we need to override the following function + // from the inherited o2::eventgen::GeneratorPythia8 class. The event header properties + // are created as members of this class, and are set using the active event generator + // (MB or jet-jet), then propagated to the event header + void updateHeader(o2::dataformats::MCEventHeader* eventHeader) override { + /** update header **/ + using Key = o2::dataformats::MCInfoKeys; + + eventHeader->putInfo(Key::generator, "pythia8"); + eventHeader->putInfo(Key::generatorVersion, PYTHIA_VERSION_INTEGER); + eventHeader->putInfo(Key::processName, name); + eventHeader->putInfo(Key::processCode, code); + eventHeader->putInfo(Key::weight, weight); + + // Set PDF information + eventHeader->putInfo(Key::pdfParton1Id, id1pdf); + eventHeader->putInfo(Key::pdfParton2Id, id2pdf); + eventHeader->putInfo(Key::pdfX1, x1pdf); + eventHeader->putInfo(Key::pdfX2, x2pdf); + eventHeader->putInfo(Key::pdfScale, QFac); + eventHeader->putInfo(Key::pdfXF1, pdf1); + eventHeader->putInfo(Key::pdfXF2, pdf2); + + // Set cross section + eventHeader->putInfo(Key::xSection, sigmaGen * 1e9); + eventHeader->putInfo(Key::xSectionError, sigmaErr * 1e9); + + // Set event scale and nMPI + eventHeader->putInfo(Key::eventScale, QRen); + eventHeader->putInfo(Key::mpi, nMPI); + + // Set accepted and attempted events + eventHeader->putInfo(Key::acceptedEvents, accepted); + eventHeader->putInfo(Key::attemptedEvents, attempted); + + LOG(info) << "--- updated header weight = " << weight; + + // The following is also set in the base class updateHeader function + // but as far as I can tell, there is no Xsec weight in the default + // header so this is not copied over for now + + //size_t iw = 0; + //auto xsecErr = info.weightContainerPtr->getTotalXsecErr(); + //for (auto w : info.weightContainerPtr->getTotalXsec()) { + // std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + // eventHeader->putInfo(Key::weight + post, info.weightValueByIndex(iw)); + // eventHeader->putInfo(Key::xSection + post, w * 1e9); + // eventHeader->putInfo(Key::xSectionError + post, xsecErr[iw] * 1e9); + // iw++; + //} + } + + void setEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + + auto& info = pythiaObject.info; + + name = info.name(); + code = info.code(); + weight = info.weight(); + // Set PDF information + id1pdf = info.id1pdf(); + id2pdf = info.id2pdf(); + x1pdf = info.x1pdf(); + x2pdf = info.x2pdf(); + QFac = info.QFac(); + pdf1 = info.pdf1(); + pdf2 = info.pdf2(); + // Set cross section + sigmaGen = info.sigmaGen(); + sigmaErr = info.sigmaErr(); + // Set event scale and nMPI + QRen = info.QRen(); + nMPI = info.nMPI(); + // Set accepted and attempted events + accepted = info.nAccepted(); + attempted = info.nTried(); + } + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + unsigned int mUsedSeed; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + + // Handling generators + Pythia8::Pythia pythiaObjectMinimumBias; + Pythia8::Pythia pythiaObjectSignal; + + // header info - needed to save event properties + std::string name; + int code; + float weight; + // PDF information + int id1pdf; + int id2pdf; + float x1pdf; + float x2pdf; + float QFac; + float pdf1; + float pdf2; + // cross section + float sigmaGen; + float sigmaErr; + // event scale and nMPI + float QRen; + int nMPI; + // accepted and attempted events + int accepted; + int attempted; +}; + +} // namespace eventgen +} // namespace o2 + +/** generator instance and settings **/ + +FairGenerator* getGeneratorPythia8GapGenJEMB(int inputTriggerRatio = 5, std::string pathMB = "",std::string pathSignal = "") { + auto myGen = new o2::eventgen::GeneratorPythia8GapGenJEMB(inputTriggerRatio, pathMB, pathSignal); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->setUsedSeed(seed); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->readString("HardQCD:all = on"); + return myGen; +} diff --git a/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C new file mode 100644 index 000000000..b138fccb3 --- /dev/null +++ b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C @@ -0,0 +1,279 @@ +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +///#include "FairGenerator.h" +//#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "MC/config/PWGGAJE/hooks/prompt_gamma_hook.C" +//#include "TRandom.h" +//#include +// +//#include +//#include + +// Prompt-photon custom event generator +// that alternates between 2 gun generators. +// set up to inject MB events alongside prompt-photon events +// in 'MB-gap' mode. +// The number of MB events injected, and the PYTHIA config +// for each event type is defined by the user in the .ini +// generator file (e.g. GeneratorJE_gapgen5_hook.ini) +// +// Author: Adrian Fereydon Nassirpour (adrian.fereydon.nassirpour@cern.ch), based on code from Jaime Norman (jaime.norman@cern.ch) + +namespace o2 +{ +namespace eventgen +{ + +using namespace Pythia8; + + +/// A very simple gap generator alternating between 2 different particle guns +class GeneratorPythia8GapGenJEPhoton : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapGenJEPhoton(int inputTriggerRatio = 5,std::string pathMB = "",std::string pathSignal = "") { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName(TString(pathMB)); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(TString(pathSignal)); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + // load jet hook to ensure at least one prompt photon is within detector acceptance + Pythia8::UserHooks *hook = pythia8_userhooks_promptgamma(); + pythiaObjectSignal.setUserHooksPtr(std::shared_ptr(hook)); + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + // Add Sub generators + addSubGenerator(0, "MB generator"); + addSubGenerator(1, "jet-jet generator"); + } + + + /// Destructor + ~GeneratorPythia8GapGenJEPhoton() = default; + + void setUsedSeed(unsigned int seed) + { + mUsedSeed = seed; + }; + unsigned int getUsedSeed() const + { + return mUsedSeed; + }; + + bool generateEvent() override + { + + // Simple straightforward check to alternate generators + mPythia.event.reset(); + + if (mGeneratedEvents % mInverseTriggerRatio == 0) { + LOG(info) << "Event " << mGeneratedEvents << ", generate signal event"; + // Generate event of interest + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectSignal.next(); + } + mPythia.event = pythiaObjectSignal.event; + setEventHeaderProperties(pythiaObjectSignal); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectSignal); + notifySubGenerator(1); + } + else { + LOG(info) << "Event " << mGeneratedEvents << ", generate mb event"; + // Generate minimum-bias event + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + setEventHeaderProperties(pythiaObjectMinimumBias); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectMinimumBias); + notifySubGenerator(0); + } + mGeneratedEvents++; + return true; + } + + // for testing + void printEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + LOG(info) << "Info name = " << pythiaObject.info.name(); + LOG(info) << "Info code = " << pythiaObject.info.code(); + LOG(info) << "Info weight = " << pythiaObject.info.weight(); + LOG(info) << "Info id1pdf = " << pythiaObject.info.id1pdf(); + LOG(info) << "Info id2pdf = " << pythiaObject.info.id2pdf(); + + LOG(info) << "Info x1pdf = " << pythiaObject.info.x1pdf(); + LOG(info) << "Info x2pdf = " << pythiaObject.info.x2pdf(); + LOG(info) << "Info QFac = " << pythiaObject.info.QFac(); + LOG(info) << "Info pdf1 = " << pythiaObject.info.pdf1(); + LOG(info) << "Info pdf2 = " << pythiaObject.info.pdf2(); + + // Set cross section + LOG(info) << "Info sigmaGen = " << pythiaObject.info.sigmaGen(); + LOG(info) << "Info sigmaErr = " << pythiaObject.info.sigmaErr(); + + // Set event scale and nMPI + LOG(info) << "Info QRen = " << pythiaObject.info.QRen(); + LOG(info) << "Info nMPI = " << pythiaObject.info.nMPI(); + + // Set accepted and attempted values + LOG(info) << "Info accepted = " << pythiaObject.info.nAccepted(); + LOG(info) << "Info attempted = " << pythiaObject.info.nTried(); + + // Set weights (overrides cross-section for each weight) + size_t iw = 0; + auto xsecErr = pythiaObject.info.weightContainerPtr->getTotalXsecErr(); + for (auto w : pythiaObject.info.weightContainerPtr->getTotalXsec()) { + std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + LOG(info) << "Info weight by index = " << pythiaObject.info.weightValueByIndex(iw); + iw++; + } + + } + + // in order to save the event weight we need to override the following function + // from the inherited o2::eventgen::GeneratorPythia8 class. The event header properties + // are created as members of this class, and are set using the active event generator + // (MB or jet-jet), then propagated to the event header + void updateHeader(o2::dataformats::MCEventHeader* eventHeader) override { + /** update header **/ + using Key = o2::dataformats::MCInfoKeys; + + eventHeader->putInfo(Key::generator, "pythia8"); + eventHeader->putInfo(Key::generatorVersion, PYTHIA_VERSION_INTEGER); + eventHeader->putInfo(Key::processName, name); + eventHeader->putInfo(Key::processCode, code); + eventHeader->putInfo(Key::weight, weight); + + // Set PDF information + eventHeader->putInfo(Key::pdfParton1Id, id1pdf); + eventHeader->putInfo(Key::pdfParton2Id, id2pdf); + eventHeader->putInfo(Key::pdfX1, x1pdf); + eventHeader->putInfo(Key::pdfX2, x2pdf); + eventHeader->putInfo(Key::pdfScale, QFac); + eventHeader->putInfo(Key::pdfXF1, pdf1); + eventHeader->putInfo(Key::pdfXF2, pdf2); + + // Set cross section + eventHeader->putInfo(Key::xSection, sigmaGen * 1e9); + eventHeader->putInfo(Key::xSectionError, sigmaErr * 1e9); + + // Set event scale and nMPI + eventHeader->putInfo(Key::eventScale, QRen); + eventHeader->putInfo(Key::mpi, nMPI); + + // Set accepted and attempted events + eventHeader->putInfo(Key::acceptedEvents, accepted); + eventHeader->putInfo(Key::attemptedEvents, attempted); + + LOG(info) << "--- updated header weight = " << weight; + + // The following is also set in the base class updateHeader function + // but as far as I can tell, there is no Xsec weight in the default + // header so this is not copied over for now + + //size_t iw = 0; + //auto xsecErr = info.weightContainerPtr->getTotalXsecErr(); + //for (auto w : info.weightContainerPtr->getTotalXsec()) { + // std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + // eventHeader->putInfo(Key::weight + post, info.weightValueByIndex(iw)); + // eventHeader->putInfo(Key::xSection + post, w * 1e9); + // eventHeader->putInfo(Key::xSectionError + post, xsecErr[iw] * 1e9); + // iw++; + //} + } + + void setEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + + auto& info = pythiaObject.info; + + name = info.name(); + code = info.code(); + weight = info.weight(); + // Set PDF information + id1pdf = info.id1pdf(); + id2pdf = info.id2pdf(); + x1pdf = info.x1pdf(); + x2pdf = info.x2pdf(); + QFac = info.QFac(); + pdf1 = info.pdf1(); + pdf2 = info.pdf2(); + // Set cross section + sigmaGen = info.sigmaGen(); + sigmaErr = info.sigmaErr(); + // Set event scale and nMPI + QRen = info.QRen(); + nMPI = info.nMPI(); + // Set accepted and attempted events + accepted = info.nAccepted(); + attempted = info.nTried(); + } + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + unsigned int mUsedSeed; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + + // Handling generators + Pythia8::Pythia pythiaObjectMinimumBias; + Pythia8::Pythia pythiaObjectSignal; + + // header info - needed to save event properties + std::string name; + int code; + float weight; + // PDF information + int id1pdf; + int id2pdf; + float x1pdf; + float x2pdf; + float QFac; + float pdf1; + float pdf2; + // cross section + float sigmaGen; + float sigmaErr; + // event scale and nMPI + float QRen; + int nMPI; + // accepted and attempted events + int accepted; + int attempted; +}; + +} // namespace eventgen +} // namespace o2 + +/** generator instance and settings **/ + +FairGenerator* getGeneratorPythia8GapGenJEPhoton(int inputTriggerRatio = 5, std::string pathMB = "",std::string pathSignal = "") { + auto myGen = new o2::eventgen::GeneratorPythia8GapGenJEPhoton(inputTriggerRatio, pathMB, pathSignal); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->setUsedSeed(seed); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->readString("HardQCD:all = on"); + return myGen; +} diff --git a/MC/config/PWGGAJE/ini/hook_prompt_gamma_gap.ini b/MC/config/PWGGAJE/ini/hook_prompt_gamma_gap.ini new file mode 100644 index 000000000..7747e0ed5 --- /dev/null +++ b/MC/config/PWGGAJE/ini/hook_prompt_gamma_gap.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C +funcName = getGeneratorPythia8GapGenJEPhoton(2,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg +includePartonEvent=true diff --git a/MC/config/PWGGAJE/ini/prompt_gamma_gap.ini b/MC/config/PWGGAJE/ini/prompt_gamma_gap.ini new file mode 100644 index 000000000..dc69687f3 --- /dev/null +++ b/MC/config/PWGGAJE/ini/prompt_gamma_gap.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C +funcName = getGeneratorPythia8GapGenJEMB(2,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/hook_prompt_gamma_gap.C b/MC/config/PWGGAJE/ini/tests/hook_prompt_gamma_gap.C new file mode 100644 index 000000000..69cd83f86 --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/hook_prompt_gamma_gap.C @@ -0,0 +1,71 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + float ratioTrigger = 1./2; // one event triggered out of 5 + + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsJetJet{}; + float sumWeightsMB{}, sumWeightsJetJet{}; + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information and event weights + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (eventHeader->hasInfo(o2::dataformats::MCInfoKeys::weight)) { + float weight = eventHeader->getInfo(o2::dataformats::MCInfoKeys::weight,isValid); + if (subGeneratorId == 0) { + nEventsMB++; + sumWeightsMB += weight; + } + else if (subGeneratorId == 1) { + nEventsJetJet++; + sumWeightsJetJet += weight; + } + } + } + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << " sum of weights for MB events: " << sumWeightsMB << "\n"; + std::cout << "# prompt_photon events " << nEventsJetJet << "\n"; + std::cout << " sum of weights prompt_photon events: " << sumWeightsJetJet << "\n"; + std::cout << "# tracks summed over all events (prompt_photon + MB): " << sumTracks << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsJetJet < nEvents * ratioTrigger * 0.95 || nEventsJetJet > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of prompt_photon generated events different than expected\n"; + return 1; + } + if(nEventsMB < sumWeightsMB * 0.95 || nEventsMB > sumWeightsMB * 1.05) { + std::cerr << "Weights of MB events do not = 1 as expected\n"; + return 1; + } + if(sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGGAJE/ini/tests/prompt_gamma_gap.C b/MC/config/PWGGAJE/ini/tests/prompt_gamma_gap.C new file mode 100644 index 000000000..6f32003fe --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/prompt_gamma_gap.C @@ -0,0 +1,71 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + float ratioTrigger = 1./2; // one event triggered out of 5 + + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsJetJet{}; + float sumWeightsMB{}, sumWeightsJetJet{}; + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information and event weights + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (eventHeader->hasInfo(o2::dataformats::MCInfoKeys::weight)) { + float weight = eventHeader->getInfo(o2::dataformats::MCInfoKeys::weight,isValid); + if (subGeneratorId == 0) { + nEventsMB++; + sumWeightsMB += weight; + } + else if (subGeneratorId == 1) { + nEventsJetJet++; + sumWeightsJetJet += weight; + } + } + } + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << " sum of weights for MB events: " << sumWeightsMB << "\n"; + std::cout << "# Jet-jet events " << nEventsJetJet << "\n"; + std::cout << " sum of weights jet-jet events: " << sumWeightsJetJet << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsJetJet < nEvents * ratioTrigger * 0.95 || nEventsJetJet > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of jet-jet generated events different than expected\n"; + return 1; + } + if(nEventsMB < sumWeightsMB * 0.95 || nEventsMB > sumWeightsMB * 1.05) { + std::cerr << "Weights of MB events do not = 1 as expected\n"; + return 1; + } + if(sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg b/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg new file mode 100644 index 000000000..ff0258880 --- /dev/null +++ b/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg @@ -0,0 +1,21 @@ +# 2 -> 2 prompt photon production, oversampling by pThat^4 + +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 13600. # GeV + +### processes +SoftQCD:inelastic = off +HardQCD:all = off +PromptPhoton:all = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 5 +PhaseSpace:pTHatMax = 600 +PhaseSpace:bias2Selection = on +PhaseSpace:bias2SelectionPow = 4 \ No newline at end of file From 9e080298f5af8c241d41b180622f39b28cc1605f Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Mon, 9 Feb 2026 13:19:07 +0100 Subject: [PATCH 237/362] Parallelise o2dpg generator tests (#2250) * Implementation of parallel testing --- test/run_generator_tests.sh | 118 +++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index 579d0a696..a05f32fc5 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -46,24 +46,24 @@ TEST_COUNTER=1 # whether or not to delete everything except logs (default is to delete) KEEP_ONLY_LOGS=1 +# Number of workers for parallel test runs +JOBS=${JOBS:-8} +echo "Running tests with up to ${JOBS} parallel jobs" # Prepare some colored output SRED="\033[0;31m" SGREEN="\033[0;32m" SEND="\033[0m" - echo_green() { echo -e "${SGREEN}${*}${SEND}" } - echo_red() { echo -e "${SRED}${*}${SEND}" } - # Prevent the script from being soured to omit unexpected surprises when exit is used SCRIPT_NAME="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" if [ "${SCRIPT_NAME}" != "$(basename ${BASH_SOURCE[0]})" ] ; then @@ -71,12 +71,10 @@ if [ "${SCRIPT_NAME}" != "$(basename ${BASH_SOURCE[0]})" ] ; then return 1 fi - ################################## # Core and utility functionality # ################################## - get_test_script_path_for_ini() { local ini_path=${1} @@ -111,9 +109,10 @@ exec_test() local ini_path=${1} local generator=${2} # for now one of "Pythia8" or "External", at this point we know that settings for the generator are defined in this ini local generator_lower=$(echo "${generator}" | tr '[:upper:]' '[:lower:]') + local test_id=${3} # DPL session ID # TODO Potentially, one could run an external generator that derives from GeneratorPythia8 and so could probably use configuration for TriggerPythia8 - local trigger=${3:+-t ${generator_lower}} - local trigger_dpl=${3:+--trigger ${generator_lower}} + local trigger=${4:+-t ${generator_lower}} + local trigger_dpl=${4:+--trigger ${generator_lower}} local RET=0 # this is how our test script is expected to be called local test_script=$(get_test_script_path_for_ini ${ini_path}) @@ -126,13 +125,14 @@ exec_test() echo "### Testing DPL-eventgen ###" >> ${LOG_FILE_SIM} # run the event generation using the dpl-eventgen executable. # This is a basic running test, however it's important because the system running on Hyperloop - # is largely used for MCGEN productions and is currently tested only locally - o2-sim-dpl-eventgen --generator ${generator_lower} ${trigger_dpl} --nEvents ${nev} --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" -b >> ${LOG_FILE_SIM} 2>&1 + # is largely used for MCGEN productions and is currently tested only locally. + # Using unique session labels to prevent channel binding conflicts in parallel execution + o2-sim-dpl-eventgen --session test_${test_id} --generator ${generator_lower} ${trigger_dpl} --nEvents ${nev} --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" -b >> ${LOG_FILE_SIM} 2>&1 RET=${?} [[ "${RET}" != "0" ]] && { remove_artifacts ; return ${RET} ; } # run the simulation, fail if not successful echo "### Testing base o2-sim executable ###" >> ${LOG_FILE_SIM} - o2-sim -g ${generator_lower} ${trigger} --noGeant -n ${nev} -j 4 --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" >> ${LOG_FILE_SIM} 2>&1 + o2-sim -g ${generator_lower} ${trigger} --noGeant -n ${nev} -j 1 --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" >> ${LOG_FILE_SIM} 2>&1 RET=${?} [[ "${RET}" != "0" ]] && { remove_artifacts ; return ${RET} ; } @@ -151,6 +151,13 @@ exec_test() return ${RET} } +wait_for_slot() +{ + # Wait until the number of background jobs is within the limit + while (( $(jobs -r | wc -l) >= JOBS )) ; do + sleep 0.1 + done +} check_generators() { @@ -169,31 +176,37 @@ check_generators() local look_for=$(grep " ${g}.*\(\)" ${test_script}) local has_trigger="$(grep Trigger${g} ${ini_path})" [[ -z "${look_for}" ]] && continue - echo -n "Test ${TEST_COUNTER}: ${ini_path} with generator ${g}" tested_any=1 # prepare the test directory local test_dir=${TEST_COUNTER}_$(basename ${ini})_${g}_dir rm -rf ${test_dir} 2> /dev/null mkdir ${test_dir} - pushd ${test_dir} > /dev/null - # one single test - exec_test ${ini_path} ${g} ${has_trigger} - RET=${?} - popd > /dev/null - if [[ "${RET}" != "0" ]] ; then - echo_red " -> FAILED" - ret_this=${RET} - else - echo_green " -> PASSED" - fi + local test_num=${TEST_COUNTER} ((TEST_COUNTER++)) + + # Wait for an available slot before starting a new test + wait_for_slot + + echo "Test ${test_num}: ${ini_path} with generator ${g} - STARTED" + # Run test in background + ( + cd ${test_dir} + exec_test ${ini_path} ${g} ${test_num} ${has_trigger} + exit $? + ) & + local pid=$! + + # Store test information in global arrays + test_pids+=(${pid}) + test_numbers+=(${test_num}) + test_generators+=(${g}) + test_ini_paths+=("${ini_path}") fi done [[ -z "${tested_any}" ]] && { echo_red "No test scenario was found for any generator. There must be at least one generator to be tested." ; ret_this=1 ; } return ${ret_this} } - add_ini_files_from_macros() { # given a list of macros, collect all INI files which contain at least one of them @@ -216,7 +229,6 @@ add_ini_files_from_macros() done } - get_root_includes() { # check if some R__ADD_INCLUDE_PATH is used in the including macro and check the included file against that @@ -236,7 +248,6 @@ get_root_includes() echo ${full_includes} } - find_including_macros() { # figure out the macros that INCLUDE macros that have changed, so that in turn we can check @@ -283,7 +294,6 @@ find_including_macros() echo ${including_macros} } - add_ini_files_from_tests() { # Collect also those INI files for which the test has been changed @@ -302,7 +312,6 @@ add_ini_files_from_tests() done } - collect_ini_files() { # Collect all INI files which have changed @@ -336,7 +345,6 @@ collect_ini_files() add_ini_files_from_tests ${macros} } - get_git_repo_directory() { local repo= @@ -381,11 +389,11 @@ print_usage() # whether or not to exit after first test has failed fail_immediately= -[[ "${1}" == "--fail_immediately" ]] && fail_immediately=1 +[[ "${1}" == "--fail-immediately" ]] && fail_immediately=1 while [ "$1" != "" ] ; do case $1 in - --fail_immediately ) shift + --fail-immediately ) shift fail_immediately=1 ;; --keep-artifacts ) shift @@ -469,6 +477,12 @@ pushd ${TEST_PARENT_DIR} > /dev/null # global return code to be returned at the end ret_global=0 +# Global arrays to track all test jobs (across all INI files) +declare -a test_pids +declare -a test_numbers +declare -a test_generators +declare -a test_ini_paths + # check each of the INI files for ini in ${ini_files_full_paths} ; do @@ -495,6 +509,50 @@ for ini in ${ini_files_full_paths} ; do [[ "${fail_immediately}" == "1" ]] && break fi done + +# Wait for all test jobs to complete and collect results +total_tests=${#test_pids[@]} +completed=0 +while (( completed < total_tests )) ; do + # Wait for any background job to complete + wait -n + RET=$? + + # Find which job completed by checking which PID no longer exists + for idx in "${!test_pids[@]}" ; do + pid="${test_pids[$idx]}" + if ! kill -0 ${pid} 2>/dev/null ; then + # This job has completed, get its actual exit status + wait ${pid} 2>/dev/null + RET=$? + + test_num="${test_numbers[$idx]}" + generator="${test_generators[$idx]}" + ini_path="${test_ini_paths[$idx]}" + + if [[ "${RET}" != "0" ]] ; then + echo_red "Test ${test_num}: ${ini_path} with generator ${generator} -> FAILED" + ret_global=${RET} + if [[ "${fail_immediately}" == "1" ]] ; then + # Kill remaining background jobs + for remaining_pid in "${test_pids[@]}" ; do + kill ${remaining_pid} 2>/dev/null + done + completed=${total_tests} + break + fi + else + echo_green "Test ${test_num}: ${ini_path} with generator ${generator} -> PASSED" + fi + + # Remove this job from tracking + unset test_pids[$idx] + ((completed++)) + break + fi + done +done + # return to where we came from popd > /dev/null From ba914591ae36b6b85c8eedae3902390a30c07c7d Mon Sep 17 00:00:00 2001 From: sejeong8 Date: Wed, 11 Feb 2026 19:14:04 +0900 Subject: [PATCH 238/362] Creat a dedicated config for the ppref (#2260) --- .../generator/pythia8_HFe_Mode2_pp_ref.cfg | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg new file mode 100644 index 000000000..c13834cd5 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg @@ -0,0 +1,97 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Grazia Luparello (Grazia.Luparello@cern.ch) +### Antonio Palasciano (antonio.palasciano@cern.ch) +### Jonghan Park (jonghan@cern.ch) +### electrons from heavy-flavour hadrons and from light neutral mesons +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + + +### switch off all decay channels +111:onMode = off +221:onMode = off + +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4132:onMode = off +4232:onMode = off +4332:onMode = off + +511:onMode = off +521:onMode = off +531:onMode = off +5122:onMode = off +5132:onMode = off +5232:onMode = off +5332:onMode = off + +###Semimuonic decays of charm + +### D+/- -> e + X +411:onIfAny = 11 +### D0 -> e + X +421:onIfAny = 11 +### D_s -> e + X +431:onIfAny = 11 +### Lambda_c -> e + X +4122:onIfAny = 11 +### Xsi0_c -> e + X +4132:onIfAny = 11 +### Xsi+_c -> e + X +4232:onIfAny = 11 +### Omega_c -> e + X +4332:onIfAny = 11 + +### B0 -> e + X +511:onIfAny = 11 +### B+/- -> e + X +521:onIfAny = 11 +### B_s -> e + X +531:onIfAny = 11 +### Lambda_b -> e + X +5122:onIfAny = 11 +### Xsi_b -> e + X +5132:onIfAny = 11 +### Xsi0_b -> e + X +5232:onIfAny = 11 +### Omega_b -> e + X +5332:onIfAny = 11 From 1608b58363d91019f8447cdbe4b6805ca8957a99 Mon Sep 17 00:00:00 2001 From: Jesper Karlsson Gumprecht <113693781+jesgum@users.noreply.github.com> Date: Fri, 13 Feb 2026 06:07:39 +0100 Subject: [PATCH 239/362] Central PbPb generator with added strangeness (#2269) * Central PbPb generator with strangeness * update test --- .../ini/central_strangeness_PbPb_552tev.ini | 9 + .../tests/central_strangeness_PbPb_552tev.C | 36 ++ .../pythia8/generator/pythia8_central_hi.cfg | 20 + .../pythia8/generator/pythia8_central_hi.cmnd | 21 + ...tor_pythia8_central_strangeness_gun_PbPb.C | 611 ++++++++++++++++++ 5 files changed, 697 insertions(+) create mode 100644 MC/config/ALICE3/ini/central_strangeness_PbPb_552tev.ini create mode 100644 MC/config/ALICE3/ini/tests/central_strangeness_PbPb_552tev.C create mode 100755 MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg create mode 100755 MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cmnd create mode 100755 MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C diff --git a/MC/config/ALICE3/ini/central_strangeness_PbPb_552tev.ini b/MC/config/ALICE3/ini/central_strangeness_PbPb_552tev.ini new file mode 100644 index 000000000..30c665813 --- /dev/null +++ b/MC/config/ALICE3/ini/central_strangeness_PbPb_552tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C +funcName=generatePYTHIA() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg diff --git a/MC/config/ALICE3/ini/tests/central_strangeness_PbPb_552tev.C b/MC/config/ALICE3/ini/tests/central_strangeness_PbPb_552tev.C new file mode 100644 index 000000000..bdb092295 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/central_strangeness_PbPb_552tev.C @@ -0,0 +1,36 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + auto nEvents = tree->GetEntries(); + int nTracks = 0; + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + nTracks += tracks->size(); + } + + const int meanNTracksPerEvent = nTracks / nEvents; + + // Expecting only events with a 0-10% centrality + // 0-100% gives a mean of ~1350 + // 2300 should be enough + if (meanNTracksPerEvent < 2300) { + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg new file mode 100755 index 000000000..cb7e7cec0 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg @@ -0,0 +1,20 @@ +### Specify beams +Beams:idA = 1000822080 +Beams:idB = 1000822080 +Beams:eCM = 5520.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Initialize the Angantyr model to fit the total and semi-includive +### cross sections in Pythia within some tolerance. +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 + +### These parameters are typicall suitable for sqrt(S_NN)=5TeV +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 13.88,1.84,0.22,0.0,0.0,0.0,0.0,0.0 +HeavyIon:bWidth = 4.43 + + +Random:setSeed = on \ No newline at end of file diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cmnd b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cmnd new file mode 100755 index 000000000..713f1b36d --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cmnd @@ -0,0 +1,21 @@ +### beams +Beams:idA 1000822080 # Pb +Beams:idB 1000822080 # Pb +Beams:eCM 5520. # GeV + +### heavy-ion settings (valid for Pb-Pb 5520 only) +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 13.88,1.84,0.22,0.0,0.0,0.0,0.0,0.0 +HeavyIon:bWidth = 4.43 + +### processes (apparently not to be defined) + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 0.001 + +! 2) Seed settings +! Seed is set inside the generator +! If run on the grid, seed is set to job id +! If run locally, seed is set to 0 +Random:setSeed = on ! Random seed on diff --git a/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C b/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C new file mode 100755 index 000000000..150bfd3ab --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C @@ -0,0 +1,611 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include + +using namespace Pythia8; +#endif +class GeneratorPythia8Gun : public o2::eventgen::GeneratorPythia8{ +public: + /// default constructor + GeneratorPythia8Gun() = default; + + /// constructor + GeneratorPythia8Gun(int input_pdg){ + genMinPt=0.0; + genMaxPt=20.0; + genminY=-1.5; + genmaxY=1.5; + genminEta=-1.5; + genmaxEta=1.5; + + UEOverSampling = 20; + genEventCountUse = 2000; //start at large number: regen + + pdg = input_pdg; + E=0; + px=0; + py=0; + pz=0; + p=0; + y=0; + eta=0; + xProd=0; + yProd=0; + zProd=0; + xProd=0.; yProd=0.; zProd=0.; + //addFurtherPion=false; + + randomizePDGsign=false; + + //fSpectra = new TF1("fPtDist",myLevyPt,0.0,10,3); + fSpectra = STAR_BlastWave("fSpectra", m, 20); + fSpectra ->SetNpx( 1000 ); + fSpectraXi = STAR_BlastWave("fSpectraXi", 1.32171, 20); + fSpectraXi ->SetNpx( 1000 ); + fSpectraOm = STAR_BlastWave("fSpectraOm", 1.67245, 20); + fSpectraOm ->SetNpx( 1000 ); + + fSpectra->SetParameter(0, m); //mass: automatic! + fSpectra->SetParameter(1,0.6615); //beta-max + fSpectra->SetParameter(2,0.0905); //T + fSpectra->SetParameter(3,0.7355); //n + fSpectra->SetParameter(4,1000); //norm (not relevant) + + fSpectraXi->SetParameter(0,1.32171); //beta-max + fSpectraXi->SetParameter(1,0.6615); //beta-max + fSpectraXi->SetParameter(2,0.0905); //T + fSpectraXi->SetParameter(3,0.7355); //n + fSpectraXi->SetParameter(4,1000); //norm (not relevant) + + fSpectraOm->SetParameter(0,1.67245); //beta-max + fSpectraOm->SetParameter(1,0.6615); //beta-max + fSpectraOm->SetParameter(2,0.0905); //T + fSpectraOm->SetParameter(3,0.7355); //n + fSpectraOm->SetParameter(4,1000); //norm (not relevant) + + fLVHelper = new TLorentzVector(); + + if( input_pdg!=0 ) m = getMass(input_pdg); + if( input_pdg==4444 ) m = 4.797; + if( input_pdg==0 ) m = 1.0; + furtherPrim={}; + keys_furtherPrim={}; + cout<<"Initalizing extra PYTHIA object"<SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrandXi->Integral(0., 1.); + } + if(TMath::Abs(mass-1.67245)<0.002){ + if (!fIntegrandOm) + fIntegrandOm = new TF1("fIntegrandOm", this, &GeneratorPythia8Gun::STAR_BlastWave_Integrand_Improved, 0., 1., 5, "GeneratorPythia8Gun", "STAR_BlastWave_Integrand_Improved"); + fIntegrandOm->SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrandOm->Integral(0., 1.); + } + if(TMath::Abs(mass-1.67245)>0.002&&TMath::Abs(mass-1.32171)>0.002){ + if (!fIntegrand) + fIntegrand = new TF1("fIntegrand", this, &GeneratorPythia8Gun::STAR_BlastWave_Integrand_Improved, 0., 1., 5, "GeneratorPythia8Gun", "STAR_BlastWave_Integrand_Improved"); + fIntegrand->SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrand->Integral(0., 1.); + } + return norm * pt * integral; + } + + //___________________________________________________________________ + + Double_t STAR_BlastWave_Integrand_Improved(const Double_t *x, const Double_t *p) { + + /* + x[0] -> r (radius) + p[0] -> mT (transverse mass) + p[1] -> pT (transverse momentum) + p[2] -> beta_max (surface velocity) + p[3] -> T (freezout temperature) + p[4] -> n (velocity profile) + */ + + Double_t r = x[0]; + Double_t mt = p[0]; + Double_t pt = p[1]; + Double_t beta_max = p[2]; + Double_t temp_1 = 1. / p[3]; + Double_t n = p[4]; + + Double_t beta = beta_max * TMath::Power(r, n); + Double_t rho = TMath::ATanH(beta); + Double_t argI0 = pt * TMath::SinH(rho) * temp_1; + Double_t argK1 = mt * TMath::CosH(rho) * temp_1; + // if (argI0 > 100 || argI0 < -100) + // printf("r=%f, pt=%f, beta_max=%f, temp=%f, n=%f, mt=%f, beta=%f, rho=%f, argI0=%f, argK1=%f\n", r, pt, beta_max, 1. / temp_1, n, mt, beta, rho, argI0, argK1); + return r * mt * TMath::BesselI0(argI0) * TMath::BesselK1(argK1); + + } + + //___________________________________________________________________ + + TF1 *STAR_BlastWave(const Char_t *name, Double_t mass,Float_t upperlim, Double_t beta_max = 0.9, Double_t temp = 0.1, Double_t n = 1., Double_t norm = 1.e6) { + + //new TF1("fSpectra",this ,&GeneratorPythia8GunPbPb::myLevyPt, 0.0,20,3, "GeneratorPythia8GunPbPb","myLevyPt"); + TF1 *fBlastWave = new TF1(name, this, &GeneratorPythia8Gun::STAR_BlastWave_Func, 0., upperlim, 5, "GeneratorPythia8Gun", "STAR_BlastWave_Func"); + fBlastWave->SetParameters(mass, beta_max, temp, n, norm); + fBlastWave->SetParNames("mass", "beta_max", "T", "n", "norm"); + fBlastWave->FixParameter(0, mass); + fBlastWave->SetParLimits(1, 0.1, 0.9); // don't touch :) adding some 99 youu get floating point exception + fBlastWave->SetParLimits(2, 0.03,1.);//0.05, 1.); // no negative values!! for the following as well + fBlastWave->SetParLimits(3, 0.25,4.5); // was 2.5 // omega-->at limit even moving it to 4.5 but yield same + return fBlastWave; + } + + Double_t y2eta(Double_t pt, Double_t mass, Double_t y){ + Double_t mt = TMath::Sqrt(mass * mass + pt * pt); + return TMath::ASinH(mt / pt * TMath::SinH(y)); + } + + /// set mass + void setMass(int input_m){m=input_m;} + + /// set 4-momentum + void set4momentum(double input_px, double input_py, double input_pz){ + px = input_px; + py = input_py; + pz = input_pz; + E = sqrt( m*m+px*px+py*py+pz*pz ); + fourMomentum.px(px); + fourMomentum.py(py); + fourMomentum.pz(pz); + fourMomentum.e(E); + p = sqrt( px*px+py*py+pz*pz ); + y = 0.5*log( (E+pz)/(E-pz) ); + eta = 0.5*log( (p+pz)/(p-pz) ); + + ////std::cout << "##### Particle #####" << std::endl; + ////std::cout << " - PDG code: " << pdg << std::endl; + ////std::cout << " - mass: " << m << std::endl; + ////std::cout << " - (px,py,pz): (" << px << "," << py << "," << pz << ")" << std::endl; + ////std::cout << " - momentum: " << p << std::endl; + ////std::cout << " - energy: " << E << std::endl; + ////std::cout << " - rapidity: " << y << std::endl; + ////std::cout << " - pseudorapidity: " << eta << std::endl; + ////std::cout << " - production vertex: (" << xProd << "," << yProd << "," << zProd << ")" << std::endl; + } + + /// set 3-momentum + void setMomentum(double input_p){p=input_p;} + + /// set x,y,z of production vertex + void setProdVtx(double input_xProd, double input_yProd, double input_zProd){xProd=input_xProd; yProd=input_xProd; zProd=input_zProd;} + + /// setter to add further primary particles to the event + void setAddFurtherPrimaries(const int pdgCode, const int howMany){ + /// check if this species has been already added + const int map_counts = furtherPrim.count(pdgCode); + if(map_counts==1){ // species already present + const int howMany_already = furtherPrim[pdgCode]; + std::cout << "BEWARE: " << howMany_already << " particles of species " << pdgCode << " already required."; + std::cout << " Ignoring the command setAddFurtherPrimaries(" << pdgCode << "," << howMany << ")" << std::endl; + return; + } + /// add particles, if not yet present + furtherPrim[pdgCode] = howMany; + keys_furtherPrim.insert(pdgCode); + } + + /// set add a further primary pion + //void setAddFurtherPion(){addFurtherPion=true;} + + /// get mass from TParticlePDG + double getMass(int input_pdg){ + double mass = 0; + if(TDatabasePDG::Instance()){ + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg); + if(particle) mass = particle->Mass(); + else std::cout << "===> particle mass equal to 0" << std::endl; + } + return mass; + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genUniformMomentumEta(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // momentum + const double gen_p = ranGenerator->Uniform(minP,maxP); + // eta + const double gen_eta = ranGenerator->Uniform(minY,maxY); + // z-component momentum from eta + const double cosTheta = ( exp(2*gen_eta)-1 ) / ( exp(2*gen_eta)+1 ); // starting from eta = -ln(tan(theta/2)) = 1/2*ln( (1+cos(theta))/(1-cos(theta)) ) ---> NB: valid for cos(theta)!=1 + const double gen_pz = gen_p*cosTheta; + // y-component: random uniform + const double maxVal = sqrt( gen_p*gen_p-gen_pz*gen_pz ); + double sign_py = ranGenerator->Uniform(0,1); + sign_py = (sign_py>0.5)?1.:-1.; + const double gen_py = ranGenerator->Uniform(0.,maxVal)*sign_py; + // x-component momentum + double sign_px = ranGenerator->Uniform(0,1); + sign_px = (sign_px>0.5)?1.:-1.; + const double gen_px = sqrt( gen_p*gen_p-gen_pz*gen_pz-gen_py*gen_py )*sign_px; + + set4momentum(gen_px,gen_py,gen_pz); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEta(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectra->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEtaXi(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectraXi->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEtaOm(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectraOm->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + +protected: + + //__________________________________________________________________ + Pythia8::Particle createParticle(){ + //std::cout << "createParticle() mass " << m << " pdgCode " << pdg << std::endl; + Pythia8::Particle myparticle; + myparticle.id(pdg); + myparticle.status(11); + myparticle.px(px); + myparticle.py(py); + myparticle.pz(pz); + myparticle.e(E); + myparticle.m(m); + myparticle.xProd(xProd); + myparticle.yProd(yProd); + myparticle.zProd(zProd); + + return myparticle; + } + + //__________________________________________________________________ + int randomizeSign(){ + + std::unique_ptr gen_random {new TRandom3(0)}; + const float n = gen_random->Uniform(-1,1); + + return n/abs(n); + } + + //__________________________________________________________________ + Bool_t generateEvent() override { + + double original_m = m; + int original_pdg = pdg; + + /// reset event + mPythia.event.reset(); + + if(original_pdg!=211){ + for(Int_t ii=0; ii<15; ii++){ + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEta(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + } + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Bool_t lPythiaOK = kFALSE; + while (!lPythiaOK){ + lPythiaOK = pythiaObject.next(); + //Select rough central events, please, disregard + //if( pythiaObject.info.hiInfo->b() > 6) lPythiaOK = kFALSE; //regenerate, please + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // use event + Long_t nParticles = pythiaObject.event.size(); + Long_t nChargedParticlesAtMidRap = 0; + Long_t nPionsAtMidRap = 0; + lAddedParticles = 0; + for ( Long_t j=0; j < nParticles; j++ ) { + Int_t pypid = pythiaObject.event[j].id(); + Float_t pypx = pythiaObject.event[j].px(); + Float_t pypy = pythiaObject.event[j].py(); + Float_t pypz = pythiaObject.event[j].pz(); + Float_t pypt = pythiaObject.event[j].pT(); + Float_t pyrap = pythiaObject.event[j].y(); + Float_t pyeta = pythiaObject.event[j].eta(); + Int_t pystate = pythiaObject.event[j].status(); + //if(TMath::Abs(state > 89)) {continue;} + Float_t pyenergy = pythiaObject.event[j].e(); + Int_t pycharge = pythiaObject.event[j].charge(); + + //Per-species loop: skip outside of mid-rapidity, please + if ( TMath::Abs(pyeta) > 4.0 ) continue; //only within ALICE 3 acceptance + + //final only + if (!pythiaObject.event[j].isFinal()) continue; + + if ( TMath::Abs(pyeta) < 0.5 ){ + if ( TMath::Abs(pythiaObject.event[j].charge())>1e-5 ) nChargedParticlesAtMidRap++; + if ( TMath::Abs(pypid)==211 ) nPionsAtMidRap++; + } + + pdg = pypid; + px = pypx; + py = pypy; + pz = pypz; + E = pyenergy; + m = pythiaObject.event[j].m(); + xProd = pythiaObject.event[j].xProd(); + yProd = pythiaObject.event[j].yProd(); + zProd = pythiaObject.event[j].zProd(); + + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // XI ABUNDANCE FIX +// FCN=0.35879 FROM MINOS STATUS=SUCCESSFUL 126 CALLS 634 TOTAL +// EDM=3.7456e-09 STRATEGY= 1 ERROR MATRIX ACCURATE +// EXT PARAMETER STEP FIRST +// NO. NAME VALUE ERROR SIZE DERIVATIVE +// 1 p0 4.74929e-03 3.29248e-04 -3.35914e-06 5.38225e+00 +// 2 p1 -4.08255e-03 8.62587e-04 -2.02577e-05 2.45132e+00 +// 3 p2 4.76660e+00 1.93593e+00 1.93593e+00 2.70369e-04 +// Info in : created default TCanvas with name c1 + //Adjust relative abundance of multi-strange particles by injecting some + Double_t lExpectedXiToPion = TMath::Max(4.74929e-03 - 4.08255e-03*TMath::Exp(-nChargedParticlesAtMidRap/4.76660e+00) - 0.00211334,0.); + Double_t lExpectedXi = nPionsAtMidRap*lExpectedXiToPion; + Int_t lXiYield = gRandom->Poisson(3*lExpectedXi); //factor 3: fix the rapidity acceptance + m = 1.32171; + pdg = 3312; + cout<<"Adding extra xi: "<Uniform()>0.5?+1:-1; + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEtaXi(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // OMEGA ABUNDANCE FIX + //Adjust relative abundance of multi-strange particles by injecting some + Double_t lExpectedOmegaToPion = TMath::Max(8.55057e-04 - 7.38732e-04*TMath::Exp(-nChargedParticlesAtMidRap/2.40545e+01) - 6.56785e-05,0.); + Double_t lExpectedOmega = nPionsAtMidRap*lExpectedOmegaToPion; + Int_t lOmegaYield = gRandom->Poisson(3*lExpectedOmega); //factor 3: fix the rapidity acceptance + m = 1.67245; + pdg = 3334; + cout<<"Adding extra omegas: "<Uniform()>0.5?+1:-1; + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEtaOm(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //Revert back or else there'll be trouble next time! + m = original_m; + pdg = original_pdg; + + /// go to next Pythia event + mPythia.next(); + + return true; + } + +private: + + double genMinPt; /// minimum 3-momentum for generated particles + double genMaxPt; /// maximum 3-momentum for generated particles + double genminY; /// minimum pseudorapidity for generated particles + double genmaxY; /// maximum pseudorapidity for generated particles + double genminEta; + double genmaxEta; + int UEOverSampling; //number of times to repeat underlying event + int genEventCountUse; + + Pythia8::Vec4 fourMomentum; /// four-momentum (px,py,pz,E) + double E; /// energy: sqrt( m*m+px*px+py*py+pz*pz ) [GeV/c] + double m; /// particle mass [GeV/c^2] + int pdg; /// particle pdg code + double px; /// x-component momentum [GeV/c] + double py; /// y-component momentum [GeV/c] + double pz; /// z-component momentum [GeV/c] + double p; /// momentum + double y; /// rapidity + double eta; /// pseudorapidity + double xProd; /// x-coordinate position production vertex [cm] + double yProd; /// y-coordinate position production vertex [cm] + double zProd; /// z-coordinate position production vertex [cm] + + //Max number: max number of particles to be added + long lAddedParticles; + float ue_E[5000]; + float ue_m[5000]; + float ue_px[5000]; + float ue_py[5000]; + float ue_pz[5000]; + float ue_xProd[5000]; + float ue_yProd[5000]; + float ue_zProd[5000]; + int ue_pdg[5000]; + + bool randomizePDGsign; /// bool to randomize the PDG code of the core particle + + TF1 *fSpectra; /// TF1 to store more realistic shape of spectrum + TF1 *fSpectraXi; /// TF1 to store more realistic shape of spectrum + TF1 *fSpectraOm; /// TF1 to store more realistic shape of spectrum + + //BW integrand + TF1 *fIntegrand = NULL; + TF1 *fIntegrandXi = NULL; + TF1 *fIntegrandOm = NULL; + + TLorentzVector *fLVHelper; + + Pythia8::Pythia pythiaObject; ///Generate a full event if requested to do so + + //bool addFurtherPion; /// bool to attach an additional primary pion + std::map furtherPrim; /// key: PDG code; value: how many further primaries of this species to be added + std::unordered_set keys_furtherPrim; /// keys of the above map (NB: only unique elements allowed!) +}; + +FairGenerator* generateNativeOmegaCCC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4444)); +} + +FairGenerator* generateNativeOmegaCC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4432)); +} + +FairGenerator* generateNativeOmegaC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4332)); +} + +FairGenerator* generateNativeOmega(){ + return reinterpret_cast(new GeneratorPythia8Gun(3334)); +} + +FairGenerator* generatePYTHIA(){ + return reinterpret_cast(new GeneratorPythia8Gun(211)); +} From 0f6d137889094e3f02de2459d8cd9603855ad06f Mon Sep 17 00:00:00 2001 From: tubagundem Date: Wed, 11 Feb 2026 20:34:52 +0100 Subject: [PATCH 240/362] Remap TPC time gain objects for MC anchored to 2023, where --tpc-mc-time-gain option does not exist --- MC/bin/o2dpg_sim_workflow.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 657e613c8..e793f17f6 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -174,6 +174,7 @@ O2_ROOT=environ.get('O2_ROOT') QUALITYCONTROL_ROOT=environ.get('QUALITYCONTROL_ROOT') O2PHYSICS_ROOT=environ.get('O2PHYSICS_ROOT') +ccdbRemap = environ.get('ALIEN_JDL_REMAPPINGS') if O2DPG_ROOT == None: print('Error: This needs O2DPG loaded') @@ -237,15 +238,25 @@ def load_external_config(configfile): # We still may need adjust configurations manually for consistency: # -# * Force simpler TPC digitization of if TPC reco does not have the mc-time-gain option: +# * Force simpler TPC digitization of if TPC reco does not have the mc-time-gain option or remap to a different CCDB object if we are anchored to 2023: async_envfile = 'env_async.env' if environ.get('ALIEN_JDL_O2DPG_ASYNC_RECO_TAG') is not None else None tpcreco_mctimegain = option_if_available('o2-tpc-reco-workflow', '--tpc-mc-time-gain', envfile=async_envfile) if tpcreco_mctimegain == '': - # this was communicated by Jens Wiechula@TPC; avoids dEdX issue https://its.cern.ch/jira/browse/O2-5486 for the 2tag mechanism - print ("TPC reco does not support --tpc-mc-time-gain. Adjusting some config for TPC digitization") - overwrite_config(anchorConfig['ConfigParams'],'TPCGasParam','OxygenCont',5e-6) - overwrite_config(anchorConfig['ConfigParams'],'TPCGEMParam','TotalGainStack',2000) - overwrite_config(anchorConfig['ConfigParams'],'GPU_global','dEdxDisableResidualGain',1) + # TODO: Upload all MC time gain objects to TestReco and remove year dependence + year = environ.get('ALIEN_JDL_LPMANCHORYEAR') if environ.get('ALIEN_JDL_LPMANCHORYEAR') is not None else environ.get('ANCHORYEAR') + if year == '2023': + print("TPC reco does not support --tpc-mc-time-gain. Remapping time gain objects for 2023 MC") + # Year dependent workaround for MC anchored to 2023, solving the issue with 2tag mechanism + extra = 'https://alice-ccdb.cern.ch/TestReco/=TPC/Calib/TimeGain' + environ['ALIEN_JDL_REMAPPINGS'] = (ccdbRemap + ';' + extra) if ccdbRemap else extra + # Keep the cached variable in sync, since getDPL_global_options uses it + ccdbRemap = environ.get('ALIEN_JDL_REMAPPINGS') + else: + # this was communicated by Jens Wiechula@TPC; avoids dEdX issue https://its.cern.ch/jira/browse/O2-5486 for the 2tag mechanism + print ("TPC reco does not support --tpc-mc-time-gain. Adjusting some config for TPC digitization") + overwrite_config(anchorConfig['ConfigParams'],'TPCGasParam','OxygenCont',5e-6) + overwrite_config(anchorConfig['ConfigParams'],'TPCGEMParam','TotalGainStack',2000) + overwrite_config(anchorConfig['ConfigParams'],'GPU_global','dEdxDisableResidualGain',1) # TODO: put into it's own function for better modularity # with the config, we'll create a task_finalizer functor @@ -511,7 +522,6 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): includeAnalysis = args.include_analysis includeTPCResiduals=True if environ.get('ALIEN_JDL_DOTPCRESIDUALEXTRACTION') == '1' else False includeTPCSyncMode=True if environ.get('ALIEN_JDL_DOTPCSYNCMODE') == '1' else False -ccdbRemap = environ.get('ALIEN_JDL_REMAPPINGS') qcdir = "QC" if (includeLocalQC or includeFullQC) and not isdir(qcdir): From c6a2269d0d945b8e553454bc6afe017f76615b57 Mon Sep 17 00:00:00 2001 From: Chiara De Martin <39315597+ChiaraDeMartin95@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:16:50 +0100 Subject: [PATCH 241/362] Add new generator to trigger on events with at least two lambdas (#2271) * add new generator to trigger on events with at least two lambdas * add macro in tests --------- Co-authored-by: Chiara De Martin --- .../ini/GeneratorDoubleLambdaTriggered.ini | 9 + .../tests/GeneratorDoubleLambdaTriggered.C | 25 +++ .../pythia8/generator_pythia8_doubleLambdas.C | 162 ++++++++++++++++++ MC/run/PWGLF/run_DoubleLambdaTriggered.sh | 39 +++++ 4 files changed, 235 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorDoubleLambdaTriggered.C create mode 100644 MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C create mode 100755 MC/run/PWGLF/run_DoubleLambdaTriggered.sh diff --git a/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini new file mode 100644 index 000000000..f1f484e81 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini @@ -0,0 +1,9 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C +funcName=generateDoubleLambda(4, 0.2, 10, 0.8) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_136tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorDoubleLambdaTriggered.C b/MC/config/PWGLF/ini/tests/GeneratorDoubleLambdaTriggered.C new file mode 100644 index 000000000..96fcd8bbd --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorDoubleLambdaTriggered.C @@ -0,0 +1,25 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nLambda = tree->Scan("MCTrack.GetPdgCode()", "TMath::Abs(MCTrack.GetPdgCode()) == 3122"); + + if (nLambda == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C b/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C new file mode 100644 index 000000000..b03a57ef0 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C @@ -0,0 +1,162 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include "TSystem.h" +#include "TVector2.h" +#include "fairlogger/Logger.h" +#include +#include +#include +#include +using namespace Pythia8; +#endif + +/// Event generator using Pythia ropes +/// One event of interest is triggered after n minimum-bias events. +/// Event of interest : an event that contains at least two generated (anti-)Lambdas + +class GeneratorPythia8DoubleLambda : public o2::eventgen::GeneratorPythia8 +{ +public: + /// Constructor + GeneratorPythia8DoubleLambda(int gapSize = 4, double minPt = 0.2, double maxPt = 10, double maxEta = 0.8) + : o2::eventgen::GeneratorPythia8(), + mGapSize(gapSize), + mMinPt(minPt), + mMaxPt(maxPt), + mMaxEta(maxEta) + { + fmt::printf( + ">> Pythia8 generator: two (anti-)Lambdas, gap = %d, minPtLambda = %f, maxPtLambda = %f, |etaLambda| < %f\n", gapSize, minPt, maxPt, maxEta); + } + /// Destructor + ~GeneratorPythia8DoubleLambda() = default; + + bool Init() override + { + addSubGenerator(0, "Pythia8 events with two (anti-)Lambdas"); + return o2::eventgen::GeneratorPythia8::Init(); + } + +protected: + /// Check if particle is physical primary or from HF decay + bool isLambdaPhysicalPrimaryOrFromHF(const Pythia8::Particle &p, const Pythia8::Event &event) + { + // Select only final-state particles + if (!p.isFinal()) + { + return false; + } + + // Walk up ancestry + int motherId = p.mother1(); + + while (motherId > 0) + { + + // Get mother + const auto &mother = event[motherId]; + const int absMotherPdg = std::abs(mother.id()); + + // Check if particle is from HF decay + if ((absMotherPdg / 100 == 4) || (absMotherPdg / 100 == 5) || (absMotherPdg / 1000 == 4) || (absMotherPdg / 1000 == 5)) + { + return true; + } + + // Reject non-physical primary hadrons + if (mother.isHadron() && mother.tau0() > 1.0) + { + return false; + } + motherId = mother.mother1(); + } + return true; + } + + bool generateEvent() override + { + fmt::printf(">> Generating event %d\n", mGeneratedEvents); + + bool genOk = false; + int localCounter{0}; + constexpr int kMaxTries{100000}; + + // Accept mGapSize events unconditionally, then one triggered event + if (mGeneratedEvents % (mGapSize + 1) < mGapSize) + { + genOk = GeneratorPythia8::generateEvent(); + fmt::printf(">> Gap-event (no strangeness check)\n"); + } + else + { + while (!genOk && localCounter < kMaxTries) + { + if (GeneratorPythia8::generateEvent()) + { + genOk = selectEvent(mPythia.event); + } + localCounter++; + } + if (!genOk) + { + fmt::printf("Failed to generate triggered event after %d tries\n", kMaxTries); + return false; + } + fmt::printf(">> Triggered event: event accepted after %d iterations (double (anti-)Lambdas)\n", localCounter); + } + + notifySubGenerator(0); + mGeneratedEvents++; + return true; + } + + bool selectEvent(Pythia8::Event &event) + { + + std::vector particleID; + int nLambda{0}; + + for (int i = 0; i < event.size(); i++) + { + const auto &p = event[i]; + if (std::abs(p.eta()) > mMaxEta || p.pT() < mMinPt || p.pT() > mMaxPt) + continue; + if (!isLambdaPhysicalPrimaryOrFromHF(p, event)) + continue; + + if (std::abs(p.id()) == 3122) + nLambda++; + + particleID.emplace_back(i); + } + if (nLambda < 2) + return false; + + return true; + } + +private: + int mGapSize{4}; + double mMinPt{0.2}; + double mMaxPt{10.0}; + double mMaxEta{0.8}; + uint64_t mGeneratedEvents{0}; +}; + +///___________________________________________________________ +FairGenerator *generateDoubleLambda(int gap = 4, double minPt = 0.2, double maxPt = 10, double maxEta = 0.8) +{ + + auto myGenerator = new GeneratorPythia8DoubleLambda(gap, minPt, maxPt, maxEta); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGenerator->readString("Random:setSeed on"); + myGenerator->readString("Random:seed " + std::to_string(seed)); + return myGenerator; +} diff --git a/MC/run/PWGLF/run_DoubleLambdaTriggered.sh b/MC/run/PWGLF/run_DoubleLambdaTriggered.sh new file mode 100755 index 000000000..061ae86e5 --- /dev/null +++ b/MC/run/PWGLF/run_DoubleLambdaTriggered.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# 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 + +# ----------- CONFIGURE -------------------------- +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +#export ALICEO2_CCDB_LOCALCACHE=.ccdb + + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +SIMENGINE=${SIMENGINE:-TGeant4} +NSIGEVENTS=${NSIGEVENTS:-100} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-50000} +SYSTEM=${SYSTEM:-pp} +ENERGY=${ENERGY:-13600} +CFGINIFILE=${CFGINIFILE:-"${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini"} +SEED="-seed 1995" +#[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" + +echo "NWORKERS = $NWORKERS" + +# create workflow +O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +$O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external \ + -j ${NWORKERS} \ + -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} \ + -confKey "Diamond.width[2]=6." \ + ${SEED} \ + -e ${SIMENGINE} \ + -ini $CFGINIFILE + +# run workflow +O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS From 35ed5510d953921ab1e2f2c27911bd2d96a685f3 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Mon, 16 Feb 2026 14:13:11 +0100 Subject: [PATCH 242/362] Fix Pythia8 testing case (#2272) --- test/run_generator_tests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index a05f32fc5..e02f1080d 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -21,7 +21,7 @@ export ROOT_INCLUDE_PATH LD_LIBRARY_PATH # Entrypoint for O2DPG related tests # ###################################### -CHECK_GENERATORS="pythia8 External Hybrid" +CHECK_GENERATORS="Pythia8 External Hybrid" # The test parent dir to be cretaed in current directory TEST_PARENT_DIR="o2dpg_tests/generators" @@ -174,6 +174,10 @@ check_generators() # check if this generator is mentioned in the INI file and only then test it if [[ "$(grep ${g} ${ini_path})" != "" ]] ; then local look_for=$(grep " ${g}.*\(\)" ${test_script}) + # For Pythia8 the function in the test script is lowercase for compatibility purposes + if [[ "${g}" == "Pythia8" ]]; then + look_for=$(grep " pythia8.*\(\)" ${test_script}) + fi local has_trigger="$(grep Trigger${g} ${ini_path})" [[ -z "${look_for}" ]] && continue tested_any=1 From 0d6ff3c521ca9cf6a9f4f08d365ca3cfb86e0cf3 Mon Sep 17 00:00:00 2001 From: Rashi gupta <167059733+rashigupt@users.noreply.github.com> Date: Tue, 17 Feb 2026 13:38:55 +0530 Subject: [PATCH 243/362] =?UTF-8?q?Add=20Non-HFE=E2=80=93enhanced=20datase?= =?UTF-8?q?t=20configuration=20(#2189)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create the Non-HFE–enhanced dataset. We will produce a Non-HFE–enhanced dataset by generating Monte Carlo samples with increased π⁰ and η production, to improve the statistical precision of the non-HFE efficiency measurement. --- .../PWGHF/hybrid/GeneratorHF_Non_Hfe.json | 27 ++++++++ MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini | 4 ++ .../PWGHF/ini/tests/GeneratorHF_Non_Hfe.C | 61 +++++++++++++++++++ .../pythia8/generator/pythia8_NonHfe.cfg | 41 +++++++++++++ MC/config/PWGHF/trigger/selectNonHfe.C | 41 +++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json create mode 100644 MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg create mode 100644 MC/config/PWGHF/trigger/selectNonHfe.C diff --git a/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json b/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json new file mode 100644 index 000000000..a80e0da31 --- /dev/null +++ b/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json @@ -0,0 +1,27 @@ +{ + "generators": [ + { + "name": "pythia8", + "config": { + "config": "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg", + "hooksFileName": "", + "hooksFuncName": "", + "includePartonEvent": true, + "particleFilter": "", + "verbose": 0 + }, + "triggers": { + "mode": "or", + "specs": [ + { + "macro": "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/trigger/selectNonHfe.C", + "function": "selectPionEtaWithinAcc(\"111;221\",-1.5,1.5,1)" + } + ] + } + } + ], + "fractions": [ + 1 + ] +} diff --git a/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini b/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini new file mode 100644 index 000000000..7ed9bb10b --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini @@ -0,0 +1,4 @@ +#### This configuration uses the Hybrid external generator to trigger π⁰/η production within the specified rapidity window + +[GeneratorHybrid] +configFile = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C b/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C new file mode 100644 index 000000000..ba9dcb737 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C @@ -0,0 +1,61 @@ +int Hybrid() { + std::string path{"o2sim_Kine.root"}; + + const int pdgPi0 = 111; + const int pdgEta = 221; + const double yMin = -1.5; + const double yMax = 1.5; + const int minNb = 1; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim\n"; + return 1; + } + + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nEvents = tree->GetEntries(); + int nAccepted = 0; + int totalPi0 = 0, totalEta = 0; + + for (int i = 0; i < nEvents; ++i) { + tree->GetEntry(i); + + int count = 0; + for (auto& track : *tracks) { + int pdg = std::abs(track.GetPdgCode()); + double y = track.GetRapidity(); + + if ((pdg == pdgPi0 || pdg == pdgEta) && y >= yMin && y <= yMax) { + count++; + if (pdg == pdgPi0) totalPi0++; + if (pdg == pdgEta) totalEta++; + } + } + + if (count < minNb) { + std::cerr << " Trigger violation in event " << i + << " (found " << count << " π0/η in rapidity window)\n"; + return 1; + } + + nAccepted++; + } + + std::cout << "--------------------------------------\n"; + std::cout << "Trigger test: π0/η within rapidity window\n"; + std::cout << "Events tested: " << nEvents << "\n"; + std::cout << "Events accepted: " << nAccepted << "\n"; + std::cout << "# π0: " << totalPi0 << ", # η: " << totalEta << "\n"; + std::cout << "Trigger test PASSED\n"; + + return 0; +} diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg new file mode 100644 index 000000000..e4fe0e6f2 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg @@ -0,0 +1,41 @@ +### authors: Rashi Gupta (rashi.gupta@cern.ch) +### authors: Ravindra Singh (ravindra.singh@cern.ch) +### electrons from pi0 and eta enhancement + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + + +### switch off all decay channels +111:onMode = off +221:onMode = off + +111:onIfAny = 11 # pi0 -> e+ e- gamma +221:onIfAny = 11 # eta -> e+ e- gamma diff --git a/MC/config/PWGHF/trigger/selectNonHfe.C b/MC/config/PWGHF/trigger/selectNonHfe.C new file mode 100644 index 000000000..2acfc23fe --- /dev/null +++ b/MC/config/PWGHF/trigger/selectNonHfe.C @@ -0,0 +1,41 @@ +#include +#include "Generators/Trigger.h" +#include +#include + +///============================================================================ + +/// Select π⁰ and η within a given rapidity window for enhancement +/// pdgPartForAccCut: PDG of the particle to select (111=π⁰, 221=η) +/// minNb: minimum number of such particles per event for enhancement + +//// authors: Rashi Gupta (rashi.gupta@cern.ch) +/// authors: Ravindra Singh (ravindra.singh@cern.ch) +/// ============================================================================ +o2::eventgen::Trigger selectPionEtaWithinAcc(TString pdgPartForAccCut = "111;221", double rapidityMin = -1.5, double rapidityMax = 1.5, int minNb = 1) +{ + return [pdgPartForAccCut, rapidityMin, rapidityMax, minNb](const std::vector& particles) -> bool { + TObjArray* obj = pdgPartForAccCut.Tokenize(";"); + int count = 0; + for (const auto& particle : particles) { + int pdg = TMath::Abs(particle.GetPdgCode()); + double y = particle.Y(); + + if (y < rapidityMin || y > rapidityMax) continue; + + for (int i = 0; i < obj->GetEntriesFast(); ++i) { + int pdgCode = std::stoi(obj->At(i)->GetName()); + + if (pdg == pdgCode) { + count++; + break; + } + } + } + // Only accept events with at least minNb π⁰/η + if (count >= minNb) + return kTRUE; + else + return kFALSE; + }; +} From 7c27e5b3d2e2f22646c94972687e2a70dc440fb4 Mon Sep 17 00:00:00 2001 From: shahor02 Date: Wed, 18 Feb 2026 15:13:02 +0100 Subject: [PATCH 244/362] Adjust ITS CA tracklet pT cut for low-field PbPb (#2274) * Adjust ITS CA tracklet pT cut for low-field PbPb * Fix comparison operators for BABSI in setenv_extra.sh --- DATA/production/configurations/asyncReco/setenv_extra.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 0f78ed907..6e5cf41f6 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -29,11 +29,15 @@ if [[ -z $RUN_IR ]] || [[ -z $RUN_DURATION ]] || [[ -z $RUN_BFIELD ]]; then export RUN_BFIELD=`cat BField.txt` export RUN_DETECTOR_LIST=`cat DetList.txt` fi + +BABSI=$(printf "%.0f" "${RUN_BFIELD#-}") +[[ "$BABSI" -lt 12500 && "$BABSI" -gt 11500 ]] && LOWFIELD=1 || LOWFIELD=0 + echo -e "\n" echo "Printing run features" echo "DETECTOR LIST for current run ($RUNNUMBER) = $RUN_DETECTOR_LIST" echo "DURATION for current run ($RUNNUMBER) = $RUN_DURATION" -echo "B FIELD for current run ($RUNNUMBER) = $RUN_BFIELD" +echo "B FIELD for current run ($RUNNUMBER) = $RUN_BFIELD (LOWFIELD = ${LOWFIELD})" echo "IR for current run ($RUNNUMBER) = $RUN_IR" if (( $(echo "$RUN_IR <= 0" | bc -l) )); then echo "Changing run IR to 1 Hz, because $RUN_IR makes no sense" @@ -551,6 +555,9 @@ if [[ $BEAMTYPE == "PbPb" ]]; then if [[ -z "$ALIEN_JDL_DISABLE_UPC" || $ALIEN_JDL_DISABLE_UPC != 1 ]]; then EXTRA_ITSRECO_CONFIG+=";ITSVertexerParam.nIterations=2;ITSCATrackerParam.doUPCIteration=true;" fi + if [[ $LOWFIELD == "1" ]]; then + EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPt=2.5;" + fi elif [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then EXTRA_ITSRECO_CONFIG="ITSVertexerParam.phiCut=0.5;ITSVertexerParam.clusterContributorsCut=3;ITSVertexerParam.tanLambdaCut=0.2;" EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.startLayerMask[0]=127;ITSCATrackerParam.startLayerMask[1]=127;ITSCATrackerParam.startLayerMask[2]=127;" From 6cd7584e0c61fad96d07392643fbd7c0d17d6900 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Thu, 19 Feb 2026 17:27:39 +0530 Subject: [PATCH 245/362] use of GeneratorPYTHIA8 to generate background events instead of duplicate PYTHIA8 for injection mode (#2273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * use of GeneratorPYTHIA8 for background events in injection scheme * add new decay logic for lambda1520 --------- Co-authored-by: Nicolò Jacazio --- .../GeneratorLF_ExoticResonances_pp1360.ini | 8 +-- .../PWGLF/ini/GeneratorLF_Resonances_PbPb.ini | 8 +-- ...eratorLF_Resonances_PbPb5360_injection.ini | 8 +-- .../GeneratorLF_Resonances_PbPb_exotic.ini | 8 +-- .../PWGLF/ini/GeneratorLF_Resonances_pp.ini | 8 +-- .../ini/GeneratorLF_Resonances_pp1360.ini | 8 +-- ...eneratorLF_Resonances_pp1360_injection.ini | 8 +-- .../ini/GeneratorLF_Resonances_pp900.ini | 8 +-- ...GeneratorLF_Resonances_pp900_injection.ini | 8 +-- .../ini/GeneratorLF_Resonances_pp_exotic.ini | 8 +-- .../GeneratorLF_Resonances_pp_exoticAll.ini | 8 +-- .../PWGLF/pythia8/generator/lambda1520.cfg | 10 ++++ .../pythia8/generator/lambda1520gun_inj.json | 24 ++++++++ .../pythia8/generator_pythia8_LF_rapidity.C | 55 ++++++++++--------- 14 files changed, 106 insertions(+), 71 deletions(-) create mode 100644 MC/config/PWGLF/pythia8/generator/lambda1520.cfg create mode 100644 MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json diff --git a/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini b/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini index 3535d7cbe..abf18374a 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini index 4586b3bb3..0c568d47c 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json", true, 4, true, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg") -# [GeneratorPythia8] -# config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini index 5050d1760..7bce5d0b5 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json", true, 1, false, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "") -# [GeneratorPythia8] -# config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini index f5456c207..8c3471b4f 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4, true, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4, false, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "") -# [GeneratorPythia8] -# config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini index 345433715..543c0d7b2 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini index 345433715..543c0d7b2 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini index cf103d147..c8ad07a90 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini index 86503c6ab..e1895740b 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini index 2e5c4a6d4..d172f034f 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini index f83430519..ced172b4d 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini index b02959589..5469e9975 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini @@ -1,10 +1,10 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/pythia8/generator/lambda1520.cfg b/MC/config/PWGLF/pythia8/generator/lambda1520.cfg new file mode 100644 index 000000000..df201689b --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/lambda1520.cfg @@ -0,0 +1,10 @@ +### Define resonance +ProcessLevel:all = off # will not look for the 'process' + +# id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +102134:all = Lambda1520 Lambda1520bar 4 0 0 1.51950 0.01560 1.47 1.60 0 + +### add Resonance decays absent in PYTHIA8 decay table and set BRs from PDG for other +102134:oneChannel = 1 1.000 0 2212 -321 +102134:onMode = off +102134:onIfMatch = 2212 -321 diff --git a/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json b/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json new file mode 100644 index 000000000..f7e095729 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json @@ -0,0 +1,24 @@ +{ + "Lambda(1520)0" : { + "pdg": 102134, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "anti-Lambda(1520)0" : { + "pdg": -102134, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + } +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C index 26c088b0e..b88a9a7a6 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C @@ -1,5 +1,6 @@ /// /// \file generator_pythia8_LF_rapidity.C +/// \author Hirak Kumar Koley hirak.koley@cern.ch /// \author Bong-Hwi Lim bong-hwi.lim@cern.ch /// \author Based on generator_pythia8_LF.C by Nicolò Jacazio /// \since 2025/08/18 @@ -17,13 +18,15 @@ /// #if !defined(__CLING__) || defined(__ROOTCLING__) -#include "Pythia8/Pythia.h" #include "FairGenerator.h" -#include "Generators/GeneratorPythia8.h" -#include "TRandom3.h" -#include "TParticlePDG.h" + #include "TDatabasePDG.h" #include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" + +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" #if __has_include("SimulationDataFormat/MCGenStatus.h") #include "SimulationDataFormat/MCGenStatus.h" #else @@ -32,11 +35,13 @@ #if __has_include("SimulationDataFormat/MCUtils.h") #include "SimulationDataFormat/MCUtils.h" #endif -#include "fairlogger/Logger.h" #include "TSystem.h" -#include + #include "Generators/GeneratorPythia8Param.h" +#include "fairlogger/Logger.h" + #include +#include #endif // DecayerPythia8Param needs to be included after the #endif to work with Cling #include "Generators/DecayerPythia8Param.h" @@ -53,6 +58,7 @@ #endif // #include "Generators/GeneratorPythia8.h" #include "generator_pythia8_longlived.C" + #include using namespace Pythia8; @@ -66,12 +72,12 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 int gapBetweenInjection = 0, bool useTrigger = false, bool useRapidity = false, - std::string pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_minbias.cfg", - std::string pythiaCfgSignal = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_signal.cfg") : GeneratorPythia8{}, - mOneInjectionPerEvent{injOnePerEvent}, - mGapBetweenInjection{gapBetweenInjection}, - mUseTriggering{useTrigger}, - mUseRapidity{useRapidity} + std::string pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", + std::string pythiaCfgSignal = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") : GeneratorPythia8{}, + mOneInjectionPerEvent{injOnePerEvent}, + mGapBetweenInjection{gapBetweenInjection}, + mUseTriggering{useTrigger}, + mUseRapidity{useRapidity} { LOG(info) << "GeneratorPythia8LFRapidity constructor"; LOG(info) << "++ mOneInjectionPerEvent: " << mOneInjectionPerEvent; @@ -127,7 +133,7 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } // FIX: Fallback if still empty to default minbias if (pythiaCfgMb == "") { - pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/pythia8_inel_minbias.cfg"; + pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg"; } pythiaCfgMb = gSystem->ExpandPathName(pythiaCfgMb.c_str()); if (!pythiaObjectMinimumBias.readFile(pythiaCfgMb)) { @@ -142,12 +148,6 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 /** switch off process level **/ mPythiaGun.readString("ProcessLevel:all off"); - /** config **/ - auto& paramGen = o2::eventgen::GeneratorPythia8Param::Instance(); - if (!paramGen.config.empty()) { - LOG(fatal) << "Configuration file provided for \'GeneratorPythia8\' should be empty for this injection scheme"; - return; - } auto& param = o2::eventgen::DecayerPythia8Param::Instance(); LOG(info) << "Init \'GeneratorPythia8LFRapidity\' with following parameters"; LOG(info) << param; @@ -191,11 +191,12 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 if (!mUseTriggering) { // Injected mode: Embedding into MB // 1. Generate Background (MB) // LOG(info) << "Generating background event " << mEventCounter; + bool lGenerationOK = false; while (!lGenerationOK) { lGenerationOK = pythiaObjectMinimumBias.next(); } - mPythia.event = pythiaObjectMinimumBias.event; // Copy MB event to main event + mPythia.event = pythiaObjectMinimumBias.event; // 2. Determine if we inject specific particles (Gap logic) bool doInjection = true; @@ -232,7 +233,7 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } LOG(info) << "Using config container "; cfg.print(); - if (mUseTriggering) { // Do the triggering + if (mUseTriggering) { // Do the triggering bool doSignal{mEventCounter % (mGapBetweenInjection + 1) == 0}; // Do signal or gap if (doSignal) { @@ -475,13 +476,13 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } } }; - ConfigContainer(TString line) : ConfigContainer(line.Tokenize(" ")){}; + ConfigContainer(TString line) : ConfigContainer(line.Tokenize(" ")) {}; ConfigContainer(const nlohmann::json& jsonParams, bool useRapidity = false) : ConfigContainer(jsonParams["pdg"], - jsonParams["n"], - jsonParams["ptMin"], - jsonParams["ptMax"], - (useRapidity && jsonParams.contains("rapidityMin")) ? jsonParams["rapidityMin"] : (jsonParams.contains("min") ? jsonParams["min"] : jsonParams["etaMin"]), - (useRapidity && jsonParams.contains("rapidityMax")) ? jsonParams["rapidityMax"] : (jsonParams.contains("max") ? jsonParams["max"] : jsonParams["etaMax"])){}; + jsonParams["n"], + jsonParams["ptMin"], + jsonParams["ptMax"], + (useRapidity && jsonParams.contains("rapidityMin")) ? jsonParams["rapidityMin"] : (jsonParams.contains("min") ? jsonParams["min"] : jsonParams["etaMin"]), + (useRapidity && jsonParams.contains("rapidityMax")) ? jsonParams["rapidityMax"] : (jsonParams.contains("max") ? jsonParams["max"] : jsonParams["etaMax"])) {}; // Data Members const int mPdg = 0; From 2ea99ec68d59a499c5866b749b5f3b98e9187efd Mon Sep 17 00:00:00 2001 From: rbailhac Date: Fri, 20 Feb 2026 08:54:28 +0100 Subject: [PATCH 246/362] No generator with forced beauty and charm hadron semileptonic decays (#2277) --- MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh index 7547dcb0c..a3726aab3 100644 --- a/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh +++ b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh @@ -37,13 +37,10 @@ export NWORKERS=2 RNDSIG=$(($RANDOM % 100)) -if [[ $RNDSIG -ge 0 && $RNDSIG -lt 30 ]]; +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 20 ]]; then CONFIGNAME="GeneratorHFGapTriggered_Charm_Gap5.ini" -elif [[ $RNDSIG -ge 30 && $RNDSIG -lt 50 ]]; -then - CONFIGNAME="GeneratorHFGapTriggered_BeautyForcedDecay_Gap5.ini" -elif [[ $RNDSIG -ge 50 && $RNDSIG -lt 100 ]]; +elif [[ $RNDSIG -ge 20 && $RNDSIG -lt 100 ]]; then CONFIGNAME="GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5.ini" fi From a67861e46e7028c7f4b9aa2e39ba2e8060c3c601 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 18 Feb 2026 10:02:04 +0100 Subject: [PATCH 247/362] ITS: Enable delta-rof tracking in pp Enable deltaROF ITS tracking for 2026 pp. --- DATA/production/configurations/asyncReco/setenv_extra.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 6e5cf41f6..843bda18b 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -562,6 +562,7 @@ elif [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then EXTRA_ITSRECO_CONFIG="ITSVertexerParam.phiCut=0.5;ITSVertexerParam.clusterContributorsCut=3;ITSVertexerParam.tanLambdaCut=0.2;" EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.startLayerMask[0]=127;ITSCATrackerParam.startLayerMask[1]=127;ITSCATrackerParam.startLayerMask[2]=127;" EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPtIterLgt[0]=0.05;ITSCATrackerParam.minPtIterLgt[1]=0.05;ITSCATrackerParam.minPtIterLgt[2]=0.05;ITSCATrackerParam.minPtIterLgt[3]=0.05;ITSCATrackerParam.minPtIterLgt[4]=0.05;ITSCATrackerParam.minPtIterLgt[5]=0.05;ITSCATrackerParam.minPtIterLgt[6]=0.05;ITSCATrackerParam.minPtIterLgt[7]=0.05;ITSCATrackerParam.minPtIterLgt[8]=0.05;ITSCATrackerParam.minPtIterLgt[9]=0.09;ITSCATrackerParam.minPtIterLgt[10]=0.167;ITSCATrackerParam.minPtIterLgt[11]=0.125;" + EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.deltaRof=1;ITSVertexerParam.deltaRof=1;" # enable delta-rof tracking # this is to impose old pp pT cuts (overriding hardcoded pbpb24 apass1 settings) # EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPtIterLgt[0]=0.05;ITSCATrackerParam.minPtIterLgt[1]=0.05;ITSCATrackerParam.minPtIterLgt[2]=0.05;ITSCATrackerParam.minPtIterLgt[3]=0.05;ITSCATrackerParam.minPtIterLgt[4]=0.05;ITSCATrackerParam.minPtIterLgt[5]=0.05;ITSCATrackerParam.minPtIterLgt[6]=0.05;ITSCATrackerParam.minPtIterLgt[7]=0.05;ITSCATrackerParam.minPtIterLgt[8]=0.05;ITSCATrackerParam.minPtIterLgt[9]=0.05;ITSCATrackerParam.minPtIterLgt[10]=0.05;ITSCATrackerParam.minPtIterLgt[11]=0.05;" fi From 8afcabae5c0a7bc548accb31491685e70c8b3eca Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:34:32 +0100 Subject: [PATCH 248/362] [PWGLF] reduce gap size (#2278) --- MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini index f1f484e81..99c6ca698 100644 --- a/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini +++ b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C -funcName=generateDoubleLambda(4, 0.2, 10, 0.8) +funcName=generateDoubleLambda(1, 0.2, 10, 0.8) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_136tev.cfg From f102e9e72b13c4c23cb838e14062fa0faf502f32 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 24 Feb 2026 13:21:41 +0100 Subject: [PATCH 249/362] tmp use special ALIENPY_JCENTRAL --- GRID/utils/grid_submit.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/GRID/utils/grid_submit.sh b/GRID/utils/grid_submit.sh index 430026963..911252658 100755 --- a/GRID/utils/grid_submit.sh +++ b/GRID/utils/grid_submit.sh @@ -599,6 +599,7 @@ cat /proc/meminfo > alien_meminfo.log # ----------- PREPARE SOME ALIEN ENV -- useful for the job ----------- if [ "${ONGRID}" = "1" ]; then + export ALIENPY_JCENTRAL=alice-jcentral.cern.ch notify_mattermost "STARTING GRID ${ALIEN_PROC_ID} CHECK $(which alien.py)" alien.py ps --jdl ${ALIEN_PROC_ID} > this_jdl.jdl ALIEN_JOB_OUTPUTDIR=$(grep "OutputDir" this_jdl.jdl | awk '//{print $3}' | sed 's/"//g' | sed 's/;//') From f6d2de511e3007be2e1ec5f7051e7dfef47f7207 Mon Sep 17 00:00:00 2001 From: Marian Ivanov Date: Tue, 24 Feb 2026 15:53:32 +0100 Subject: [PATCH 250/362] O2-6235 - change pt range and bug fix (#2270) * O2-6235 - change pt range and bug fix kMaxInvPt to 2 (pt>0.5) make the inv_pt independent of the pt scale --------- Co-authored-by: miranov25 --- MC/config/common/external/generator/performanceGenerator.C | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/MC/config/common/external/generator/performanceGenerator.C b/MC/config/common/external/generator/performanceGenerator.C index ce59cdfaa..d592d6f25 100644 --- a/MC/config/common/external/generator/performanceGenerator.C +++ b/MC/config/common/external/generator/performanceGenerator.C @@ -208,8 +208,8 @@ namespace o2 }; // pT bounds: Max pT ~5 TeV (ALICE Pb-Pb energy) - const float kMaxInvPt = 1.0f; // Min pT = 1 GeV - const float kBaseMinInvPt = 2e-4f; // Max pT = 5000 GeV (unscaled) + const float kMaxInvPt = 2.f; // Min pT = 0.5 GeV + const float kMinInvPt = 2e-4f; // Max pT = 5000 GeV (unscaled) // Check if particle is a parton (quark/gluon, status=11) bool isParton(int& pdgCode) @@ -261,8 +261,7 @@ namespace o2 // 3. Status: 11 for partons (jets), 1 for final-state int status = isParton(pdgCode) ? 11 : 1; // 4. Kinematics (flat 1/pT, max ~5000 GeV / pTScale) - float min_inv_pt = kBaseMinInvPt / pTScale; // E.g., max pT=40,000 GeV for b quarks - float inv_pt = (gRandom->Rndm() / pTScale) * (kMaxInvPt - min_inv_pt) + min_inv_pt; + float inv_pt = gRandom->Rndm() * (kMaxInvPt - kMinInvPt) + kMinInvPt; float pt = 1.0f / inv_pt; float phi = gRandom->Rndm() * 2.0f * TMath::Pi(); float eta = gRandom->Rndm() * 3.0f - 1.5f; // ALICE TPC: -1.5 to 1.5 From 1499939647cebe38afb22d0486cab0e4be801d79 Mon Sep 17 00:00:00 2001 From: Marvin Hemmer <53471402+mhemmer-cern@users.noreply.github.com> Date: Wed, 25 Feb 2026 13:48:30 +0100 Subject: [PATCH 251/362] [PWGEM] forced dalitz decay: fix missing width (#2280) - Fix missing dimond width[2] setting --- MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini b/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini index 17caba124..1cc9c5b5b 100644 --- a/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini +++ b/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini @@ -1,3 +1,6 @@ +[Diamond] +width[2]=6.0 + [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg From 92074d3413e6798c6bf102df35d7acc928bbd069 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Thu, 26 Feb 2026 13:41:04 +0530 Subject: [PATCH 252/362] Added and updated ini for Lambda1520 (#2279) * Update generator function to use exoticAll.json * Add Lambda and anti-Lambda entries to resonance list * Added new generator for Lambda1520 * Added test code * Update PDG codes for Lambda(1520) --- .../PWGLF/ini/GeneratorLF_Lambda1520_pp.ini | 10 ++ .../GeneratorLF_Resonances_pp_exoticAll.ini | 2 +- .../ini/tests/GeneratorLF_Lambda1520_pp.C | 138 ++++++++++++++++++ ...c.json => resonancelistgun_exoticAll.json} | 24 ++- 4 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Lambda1520_pp.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Lambda1520_pp.C rename MC/config/PWGLF/pythia8/generator/{resonancelistgun_exotic.json => resonancelistgun_exoticAll.json} (87%) diff --git a/MC/config/PWGLF/ini/GeneratorLF_Lambda1520_pp.ini b/MC/config/PWGLF/ini/GeneratorLF_Lambda1520_pp.ini new file mode 100644 index 000000000..5f2eb7dca --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Lambda1520_pp.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/lambda1520.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini index 5469e9975..64d174b68 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") [GeneratorPythia8] # if triggered then this will be used as the background event config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Lambda1520_pp.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Lambda1520_pp.C new file mode 100644 index 000000000..6b02def64 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Lambda1520_pp.C @@ -0,0 +1,138 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json similarity index 87% rename from MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json rename to MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json index 2727376ca..70212867a 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json @@ -120,6 +120,28 @@ "rapidityMax": 1.2, "genDecayed": true }, + "Lambda(1520)0" : { + "pdg": 102134, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, + "anti-Lambda(1520)0" : { + "pdg": -102134, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, "Xi(1820)0": { "pdg": 123314, "n": 1, @@ -164,4 +186,4 @@ "rapidityMax": 1.2, "genDecayed": true } -} \ No newline at end of file +} From 8a4a641d91829af75c509d9ad5bd32f6b3c7ea67 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Thu, 26 Feb 2026 16:47:45 +0100 Subject: [PATCH 253/362] [PWGHF] Protect daughter index access in selectEvent to prevent segmentation faults (#2281) --- .../generator_pythia8_hfhadron_to_nuclei.C | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C b/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C index 49b98168d..a2aadef89 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C @@ -3,6 +3,7 @@ #include "Pythia8/Pythia.h" #include "TRandom.h" #include +#include #include #include @@ -119,18 +120,45 @@ class GeneratorPythia8HFHadToNuclei : public o2::eventgen::GeneratorPythia8 int id = std::abs(event[iPart].id()); float rap = event[iPart].y(); if (id == mHadronPdg && rap > mHadRapidityMin && rap < mHadRapidityMax) { + + int d1 = event[iPart].daughter1(); + int d2 = event[iPart].daughter2(); + + // Protection for invalid index of daughter 1 + if (d1 < 0 || d1 >= event.size()) { + LOG(info) << "Invalid daughter index 1! d1 = " << d1; + continue; + } + + // Protection for invalid index of daughter 2 + if (d2 < 0 || d2 >= event.size()) { + LOG(info) << "Invalid daughter index 2! d2 = " << d2; + continue; + } + + // Swap order + if (d1 > d2) { + std::swap(d1, d2); + } + + // No daughters + if (d1 == 0 && d2 == 0) { + LOG(info) << "No daughters (0,0). Skipping."; + continue; + } + LOG(debug) << "-----------------------------------------------------"; - LOG(debug) << "Found hadron " << event[iPart].id() << " with rapidity " << rap << " and daughters " << event[iPart].daughter1() << " " << event[iPart].daughter2(); + LOG(debug) << "Found hadron " << event[iPart].id() << " with rapidity " << rap << " and daughters " << d1 << " " << d2; // print pdg code of daughters LOG(debug) << "Daughters: "; - for (int iDau = event[iPart].daughter1(); iDau <= event[iPart].daughter2(); ++iDau) { + for (int iDau = d1; iDau <= d2; ++iDau) { LOG(debug) << "Daughter " << iDau << ": " << event[iDau].id(); } - bool isCoalDone = CoalescencePythia8(event, mNucleiPdgList, mTrivialCoal, mCoalMomentum, event[iPart].daughter1(), event[iPart].daughter2()); + bool isCoalDone = CoalescencePythia8(event, mNucleiPdgList, mTrivialCoal, mCoalMomentum, d1, d2); if (isCoalDone) { - LOG(debug) << "Coalescence process found for hadron " << event[iPart].id() << " with daughters " << event[iPart].daughter1() << " " << event[iPart].daughter2(); + LOG(debug) << "Coalescence process found for hadron " << event[iPart].id() << " with daughters " << d1 << " " << d2; LOG(debug) << "Check updated daughters: "; - for (int iDau = event[iPart].daughter1(); iDau <= event[iPart].daughter2(); ++iDau) { + for (int iDau = d1; iDau <= d2; ++iDau) { LOG(debug) << "Daughter " << iDau << ": " << event[iDau].id(); } return true; @@ -171,4 +199,4 @@ FairGenerator *generateHFHadToNuclei(int input_trigger_ratio = 5, std::vectorreadString("Random:setSeed on"); myGen->readString("Random:seed " + std::to_string(seed)); return myGen; -} \ No newline at end of file +} From 72be78822cc3a023bd405d1a453bbd073322c5c6 Mon Sep 17 00:00:00 2001 From: Chiara De Martin <39315597+ChiaraDeMartin95@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:05:19 +0100 Subject: [PATCH 254/362] Force Lambdas to decay into protons and pions (#2284) * force the Lambda to decay into proton and pion * generate lambdas with pt > 0.6 GeV/c * remove unneccessary configuration * fix nevents --------- Co-authored-by: Chiara De Martin --- .../ini/GeneratorDoubleLambdaTriggered.ini | 2 +- .../decayer/force_lambda_charged_decay.cfg | 5 ++ .../pythia8/decayer/g4_ext_decayer_lambda.in | 68 +++++++++++++++++++ MC/run/PWGLF/run_DoubleLambdaTriggered.sh | 4 +- 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg create mode 100644 MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in diff --git a/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini index 99c6ca698..5051b84a9 100644 --- a/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini +++ b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C -funcName=generateDoubleLambda(1, 0.2, 10, 0.8) +funcName=generateDoubleLambda(1, 0.6, 10, 0.8) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_136tev.cfg diff --git a/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg b/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg new file mode 100644 index 000000000..2446b28c7 --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg @@ -0,0 +1,5 @@ +3122:mayDecay = on +3122:oneChannel = 1 1.0 0 2212 -211 + +-3122:mayDecay = on +-3122:oneChannel = 1 1.0 0 -2212 211 \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in new file mode 100644 index 000000000..e843b1d9e --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection lambda anti_lambda \ No newline at end of file diff --git a/MC/run/PWGLF/run_DoubleLambdaTriggered.sh b/MC/run/PWGLF/run_DoubleLambdaTriggered.sh index 061ae86e5..c7e2ae418 100755 --- a/MC/run/PWGLF/run_DoubleLambdaTriggered.sh +++ b/MC/run/PWGLF/run_DoubleLambdaTriggered.sh @@ -26,10 +26,12 @@ echo "NWORKERS = $NWORKERS" # create workflow O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +CFGDECAY="${O2DPG_ROOT}/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg" +G4CFG="${O2DPG_ROOT}/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in" $O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external \ -j ${NWORKERS} \ -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} \ - -confKey "Diamond.width[2]=6." \ + -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6.;;DecayerPythia8.config[1]=${CFGDECAY};DecayerPythia8.showChanged=1;G4.configMacroFile=${G4CFG}" \ ${SEED} \ -e ${SIMENGINE} \ -ini $CFGINIFILE From fdcd28fca3e393b522634426f9f175c9657b8e77 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 2 Mar 2026 13:26:57 +0100 Subject: [PATCH 255/362] Do not use 4gpu for non-EPN sites --- .../configurations/asyncReco/async_pass.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index 56201e190..fdb542750 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -445,9 +445,17 @@ if [[ $ASYNC_PASS_NO_OPTIMIZED_DEFAULTS != 1 ]]; then fi else if [[ $BEAMTYPE == "pp" ]]; then - export OPTIMIZED_PARALLEL_ASYNC=pp_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA, 4 gpu per job, pp) + if [[ $ALIEN_JDL_SITEARCH =~ ^EPN ]]; then + export OPTIMIZED_PARALLEL_ASYNC=pp_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA, 4 gpu per job, pp) + else + export OPTIMIZED_PARALLEL_ASYNC=pp_gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 gpu per job, pp) + fi else # PbPb - export OPTIMIZED_PARALLEL_ASYNC=PbPb_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA 4 gpu per job, PbPb) + if [[ $ALIEN_JDL_SITEARCH =~ ^EPN ]]; then + export OPTIMIZED_PARALLEL_ASYNC=PbPb_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA 4 gpu per job, PbPb) + else + export OPTIMIZED_PARALLEL_ASYNC=PbPb_gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 gpu per job, PbPb) + fi fi fi else From d8e022647ec324ae1d61f2dbceeae41e2341b046 Mon Sep 17 00:00:00 2001 From: abmodak <67369858+abmodak@users.noreply.github.com> Date: Mon, 2 Mar 2026 20:49:26 +0100 Subject: [PATCH 256/362] Add new files for synthetic flow study in OO (#2285) * Add macro for synthetic flow study in OO * Add script file for synthetic flow study in OO * Add .ini file for synthetic flow study in OO * Update GeneratorLF_SyntheFlowOO.ini * Update generator_pythia8_syntheFlowOO.C * Update GeneratorLF_SyntheFlowOO.ini * Create GeneratorLF_SyntheFlowOO.C * Update generator_pythia8_syntheFlowOO.C --- .../PWGLF/ini/GeneratorLF_SyntheFlowOO.ini | 6 + .../ini/tests/GeneratorLF_SyntheFlowOO.C | 28 +++++ .../pythia8/generator_pythia8_syntheFlowOO.C | 107 ++++++++++++++++++ MC/run/PWGLF/run_SyntheticFlow_OO.sh | 42 +++++++ 4 files changed, 183 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_SyntheFlowOO.C create mode 100644 MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C create mode 100644 MC/run/PWGLF/run_SyntheticFlow_OO.sh diff --git a/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini b/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini new file mode 100644 index 000000000..ee52a0a61 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C +funcName=generator_syntheFlowOO() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_SyntheFlowOO.C b/MC/config/PWGLF/ini/tests/GeneratorLF_SyntheFlowOO.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_SyntheFlowOO.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C b/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C new file mode 100644 index 000000000..09fac8287 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C @@ -0,0 +1,107 @@ + +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" +#include "CCDB/BasicCCDBManager.h" +#include "TH1F.h" +#include "TH1D.h" + +#include +#include + +class GeneratorPythia8SyntheFlowOO : public o2::eventgen::GeneratorPythia8 +{ +public: + /// Constructor + GeneratorPythia8SyntheFlowOO() { + lutGen = new o2::eventgen::FlowMapper(); + + // -------- CONFIGURE SYNTHETIC FLOW ------------ + // establish connection to ccdb + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("https://alice-ccdb.cern.ch"); + + // config was placed at midpoint of run 544122, retrieve that + std::map metadataRCT, headers; + headers = ccdb_api.retrieveHeaders("RCT/Info/RunInformation/544122", metadataRCT, -1); + int64_t tsSOR = atol(headers["SOR"].c_str()); + int64_t tsEOR = atol(headers["EOR"].c_str()); + int64_t midRun = 0.5*tsSOR+0.5*tsEOR; + + map metadata; // can be empty + auto list = ccdb_api.retrieveFromTFileAny("Users/d/ddobrigk/syntheflow", metadata, midRun); + + TH1D *hv2vspT = (TH1D*) list->FindObject("hFlowVsPt_ins1116150_v1_Table_1"); + TH1D *heccvsb = (TH1D*) list->FindObject("hEccentricityVsB"); + + cout<<"Generating LUT for flow test"<CreateLUT(hv2vspT, heccvsb); + cout<<"Finished creating LUT!"<phi(); + float impactParameter = mPythia.info.hiInfo->b(); + + for ( Long_t j=0; j < mPythia.event.size(); j++ ) { + float pyphi = mPythia.event[j].phi(); + float pypT = mPythia.event[j].pT(); + + // calculate delta with EP + float deltaPhiEP = pyphi - eventPlaneAngle; + float shift = 0.0; + while(deltaPhiEP<0.0){ + deltaPhiEP += 2*TMath::Pi(); + shift += 2*TMath::Pi(); + } + while(deltaPhiEP>2*TMath::Pi()){ + deltaPhiEP -= 2*TMath::Pi(); + shift -= 2*TMath::Pi(); + } + float newDeltaPhiEP = lutGen->MapPhi(deltaPhiEP, impactParameter, pypT); + float pyphiNew = newDeltaPhiEP - shift + eventPlaneAngle; + + if(pyphiNew>TMath::Pi()) + pyphiNew -= 2.0*TMath::Pi(); + if(pyphiNew<-TMath::Pi()) + pyphiNew += 2.0*TMath::Pi(); + mPythia.event[j].rot(0.0, pyphiNew-pyphi); + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + return true; + } + +private: + o2::eventgen::FlowMapper *lutGen; // for mapping phi angles +}; + + FairGenerator *generator_syntheFlowOO() + { + auto generator = new GeneratorPythia8SyntheFlowOO(); + gRandom->SetSeed(0); + generator->readString("Random:setSeed = on"); + generator->readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + return generator; + } diff --git a/MC/run/PWGLF/run_SyntheticFlow_OO.sh b/MC/run/PWGLF/run_SyntheticFlow_OO.sh new file mode 100644 index 000000000..4b6c2fef2 --- /dev/null +++ b/MC/run/PWGLF/run_SyntheticFlow_OO.sh @@ -0,0 +1,42 @@ +#!/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 + +# ----------- CONFIGURE -------------------------- +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +#export ALICEO2_CCDB_LOCALCACHE=.ccdb + + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +SIMENGINE=${SIMENGINE:-TGeant4} +NSIGEVENTS=${NSIGEVENTS:-1} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-50000} +SYSTEM=${SYSTEM:-OO} +ENERGY=${ENERGY:-5360} +CFGINIFILE=${CFGINIFILE:-"${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini"} +[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" + +echo "NWORKERS = $NWORKERS" + +# create workflow +O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +$O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external \ + -j ${NWORKERS} \ + -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} \ + -confKey "Diamond.width[2]=6." \ + ${SEED} \ + -e ${SIMENGINE} \ + -ini $CFGINIFILE + +# run workflow +O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS From 1144e4f28778aae9eab38a4e153000beb5cad3d5 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Wed, 18 Feb 2026 11:13:26 +0100 Subject: [PATCH 257/362] MID: add subSpec to QC inputs --- DATA/production/qc-async/mchmid-tracks.json | 2 +- DATA/production/qc-async/mftmchmid-tracks.json | 8 ++++---- DATA/production/qc-async/mid.json | 8 ++++---- DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json | 2 +- DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json | 2 +- DATA/production/qc-sync/mid-digits.json | 2 +- DATA/production/qc-sync/mid.json | 6 +++--- DATA/testing/detectors/MID/mid-qcmn-epn-digits.json | 2 +- MC/config/QC/json/mchmid-tracks-task.json | 2 +- MC/config/QC/json/mftmchmid-tracks-task.json | 4 ++-- MC/config/QC/json/mid-task.json | 6 +++--- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/DATA/production/qc-async/mchmid-tracks.json b/DATA/production/qc-async/mchmid-tracks.json index ebd6843d1..f87a75ce4 100644 --- a/DATA/production/qc-async/mchmid-tracks.json +++ b/DATA/production/qc-async/mchmid-tracks.json @@ -11,7 +11,7 @@ "maxNumberCycles": "-1", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "movingWindows": [ "WithCuts/TracksPerTF", diff --git a/DATA/production/qc-async/mftmchmid-tracks.json b/DATA/production/qc-async/mftmchmid-tracks.json index a678fd721..2b892e070 100644 --- a/DATA/production/qc-async/mftmchmid-tracks.json +++ b/DATA/production/qc-async/mftmchmid-tracks.json @@ -13,7 +13,7 @@ "type": "direct", "_type": "dataSamplingPolicy", "name": "muon-tracks", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "movingWindows": [ "WithCuts/TracksPerTF", @@ -64,7 +64,7 @@ "_type": "direct", "type": "dataSamplingPolicy", "name": "glo-mu-tracks", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "movingWindows": [ "MCH-MID/WithCuts/TracksPerTF", @@ -111,7 +111,7 @@ "id": "muon-tracks", "active": "true", "machines": [], - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID", "samplingConditions": [ { "condition": "random", @@ -125,7 +125,7 @@ "id": "glo-mu-tracks", "active": "true", "machines": [], - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID", "samplingConditions": [ { "condition": "random", diff --git a/DATA/production/qc-async/mid.json b/DATA/production/qc-async/mid.json index 4d8c8df15..2007b84bd 100644 --- a/DATA/production/qc-async/mid.json +++ b/DATA/production/qc-async/mid.json @@ -30,7 +30,7 @@ ], "dataSource": { "type": "direct", - "query": "digits:MID/DATA;digits_rof:MID/DATAROF" + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0" } }, "MIDFilteredDigits": { @@ -42,7 +42,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "digits:MID/FDATA;digits_rof:MID/FDATAROF" + "query": "digits:MID/FDATA/0;digits_rof:MID/FDATAROF/0" } }, "MIDClusters": { @@ -54,7 +54,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "clusters:MID/TRACKCLUSTERS;clusterrofs:MID/TRCLUSROFS" + "query": "clusters:MID/TRACKCLUSTERS/0;clusterrofs:MID/TRCLUSROFS/0" } }, "MIDTracks": { @@ -66,7 +66,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "tracks:MID/TRACKS;trackrofs:MID/TRACKROFS" + "query": "tracks:MID/TRACKS/0;trackrofs:MID/TRACKROFS/0" } } }, diff --git a/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json b/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json index 74d113268..d34062b50 100644 --- a/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json +++ b/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json @@ -33,7 +33,7 @@ "disableLastCycle": "true", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "taskParameters": { "maxTracksPerTF": "600", diff --git a/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json b/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json index f7e73bf55..3806ed288 100644 --- a/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json +++ b/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json @@ -33,7 +33,7 @@ "disableLastCycle": "true", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "taskParameters": { "maxTracksPerTF": "600", diff --git a/DATA/production/qc-sync/mid-digits.json b/DATA/production/qc-sync/mid-digits.json index 7bf1bda58..1539c4e1f 100644 --- a/DATA/production/qc-sync/mid-digits.json +++ b/DATA/production/qc-sync/mid-digits.json @@ -55,7 +55,7 @@ "id": "middigits", "active": "true", "machines": [], - "query": "digits:MID/DATA;digits_rof:MID/DATAROF", + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0", "samplingConditions": [ { "condition": "random", diff --git a/DATA/production/qc-sync/mid.json b/DATA/production/qc-sync/mid.json index fea6f247e..5775dc714 100644 --- a/DATA/production/qc-sync/mid.json +++ b/DATA/production/qc-sync/mid.json @@ -148,7 +148,7 @@ "epn", "localhost" ], - "query": "tracks:MID/TRACKS;trackrofs:MID/TRACKROFS", + "query": "tracks:MID/TRACKS/0;trackrofs:MID/TRACKROFS/0", "samplingConditions": [ { "condition": "random", @@ -165,7 +165,7 @@ "epn", "localhost" ], - "query": "clusters:MID/TRACKCLUSTERS;clusterrofs:MID/TRCLUSROFS", + "query": "clusters:MID/TRACKCLUSTERS/0;clusterrofs:MID/TRCLUSROFS/0", "samplingConditions": [ { "condition": "random", @@ -182,7 +182,7 @@ "epn", "localhost" ], - "query": "digits:MID/DATA;digits_rof:MID/DATAROF", + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0", "samplingConditions": [ { "condition": "random", diff --git a/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json b/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json index f63e66e8c..cf20c554c 100644 --- a/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json +++ b/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json @@ -55,7 +55,7 @@ "id": "mid-digits", "active": "true", "machines": [], - "query": "digits:MID/DATA;digits_rof:MID/DATAROF", + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0", "samplingConditions": [ { "condition": "random", diff --git a/MC/config/QC/json/mchmid-tracks-task.json b/MC/config/QC/json/mchmid-tracks-task.json index b1129bb33..67c6e22f9 100644 --- a/MC/config/QC/json/mchmid-tracks-task.json +++ b/MC/config/QC/json/mchmid-tracks-task.json @@ -36,7 +36,7 @@ "maxNumberCycles": "-1", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "taskParameters": { "maxTracksPerTF": "600", diff --git a/MC/config/QC/json/mftmchmid-tracks-task.json b/MC/config/QC/json/mftmchmid-tracks-task.json index 8f7c927b9..6f82b5038 100644 --- a/MC/config/QC/json/mftmchmid-tracks-task.json +++ b/MC/config/QC/json/mftmchmid-tracks-task.json @@ -36,7 +36,7 @@ "maxNumberCycles": "-1", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "taskParameters": { "maxTracksPerTF": "600", @@ -73,7 +73,7 @@ "maxNumberCycles": "-1", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "taskParameters": { "maxTracksPerTF": "600", diff --git a/MC/config/QC/json/mid-task.json b/MC/config/QC/json/mid-task.json index 1f76d7ef2..6d5671bce 100644 --- a/MC/config/QC/json/mid-task.json +++ b/MC/config/QC/json/mid-task.json @@ -35,7 +35,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "digits:MID/DATA;digits_rof:MID/DATAROF" + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0" } }, "MIDClusters": { @@ -47,7 +47,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "clusters:MID/TRACKCLUSTERS;clusterrofs:MID/TRCLUSROFS" + "query": "clusters:MID/TRACKCLUSTERS/0;clusterrofs:MID/TRCLUSROFS/0" } }, "MIDTracks": { @@ -59,7 +59,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "tracks:MID/TRACKS;trackrofs:MID/TRACKROFS" + "query": "tracks:MID/TRACKS/0;trackrofs:MID/TRACKROFS/0" } } }, From da3640b7326dcd87d4c87fec02f4b0febace431c Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Tue, 3 Mar 2026 11:17:45 +0100 Subject: [PATCH 258/362] Add collision system overwriting option (#2283) --- MC/bin/o2dpg_sim_workflow_anchored.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow_anchored.py b/MC/bin/o2dpg_sim_workflow_anchored.py index 14ce8d146..e777b9acf 100755 --- a/MC/bin/o2dpg_sim_workflow_anchored.py +++ b/MC/bin/o2dpg_sim_workflow_anchored.py @@ -650,8 +650,10 @@ def main(): # needs to be handled as further below: energyarg = (" -eCM " + str(eCM)) if A1 == A2 else (" -eA " + str(eA) + " -eB " + str(eB)) forwardargs += " -tf " + str(args.tf) + " --sor " + str(effective_run_start) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " --run-anchored --first-orbit " \ - + str(GLOparams["FirstOrbit"]) + " --orbitsPerTF " + str(GLOparams["OrbitsPerTF"]) + " -col " + str(ColSystem) + str(energyarg) - # the following options can be overwritten/influence from the outside + + str(GLOparams["FirstOrbit"]) + " --orbitsPerTF " + str(GLOparams["OrbitsPerTF"]) + str(energyarg) + # the following options can be overwritten/influenced from the outside + if not '-col' in forwardargs: + forwardargs += ' -col ' + ColSystem if not '--readoutDets' in forwardargs: forwardargs += ' --readoutDets ' + GLOparams['detList'] if not '-field' in forwardargs: From 94582f3c76ad8757a7e779e317765e990f48ea97 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Thu, 26 Feb 2026 12:52:59 +0100 Subject: [PATCH 259/362] setenv.sh: use CTP derivative scaling for TPC corrections by default in pp, PbPb, light nuclei --- DATA/common/setenv.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DATA/common/setenv.sh b/DATA/common/setenv.sh index 637476a0c..5dc2c3513 100755 --- a/DATA/common/setenv.sh +++ b/DATA/common/setenv.sh @@ -164,8 +164,8 @@ DISABLE_ROOT_INPUT="--disable-root-input" # Special detector related settings if [[ -z "${TPC_CORR_SCALING:-}" ]]; then # TPC corr.map lumi scaling options, any combination of --lumi-type <0,1,2> --corrmap-lumi-mode <0,1> and TPCCorrMap... configurable param TPC_CORR_SCALING= - if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1"; fi - if [[ $BEAMTYPE == "PbPb" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1 TPCCorrMap.lumiInstFactor=2.414"; fi + if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1 --corrmap-lumi-mode 1"; fi + if [[ $BEAMTYPE == "PbPb" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1 --corrmap-lumi-mode 1 TPCCorrMap.lumiInstFactor=2.414"; fi if [[ $BEAMTYPE == "cosmic" ]]; then TPC_CORR_SCALING=" TPCCorrMap.lumiMean=-1;"; fi # for COSMICS we disable all corrections export TPC_CORR_SCALING=$TPC_CORR_SCALING fi From a03ffdb277212cff9b08e2d06a19554b7d3666e7 Mon Sep 17 00:00:00 2001 From: Andreas Molander Date: Wed, 4 Mar 2026 15:34:07 +0200 Subject: [PATCH 260/362] FIT: update online QC config names (#2252) --- DATA/production/qc-workflow.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DATA/production/qc-workflow.sh b/DATA/production/qc-workflow.sh index 62a35622e..6d152921f 100755 --- a/DATA/production/qc-workflow.sh +++ b/DATA/production/qc-workflow.sh @@ -77,9 +77,9 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then QC_JSON_TOF=apricot://o2/components/qc/ANY/any/tof-full-epn-qcmn-on-epn fi fi - [[ -z "${QC_JSON_FDD:-}" ]] && QC_JSON_FDD=apricot://o2/components/qc/ANY/any/fdd-digits-qc-epn - [[ -z "${QC_JSON_FT0:-}" ]] && QC_JSON_FT0=apricot://o2/components/qc/ANY/any/ft0-digits-qc-epn - [[ -z "${QC_JSON_FV0:-}" ]] && QC_JSON_FV0=apricot://o2/components/qc/ANY/any/fv0-digits-qc-epn + [[ -z "${QC_JSON_FDD:-}" ]] && QC_JSON_FDD=apricot://o2/components/qc/ANY/any/fdd-digits-qcmn-epn + [[ -z "${QC_JSON_FT0:-}" ]] && QC_JSON_FT0=apricot://o2/components/qc/ANY/any/ft0-digits-qcmn-epn + [[ -z "${QC_JSON_FV0:-}" ]] && QC_JSON_FV0=apricot://o2/components/qc/ANY/any/fv0-digits-qcmn-epn if [[ -z "${QC_JSON_EMC:-}" ]]; then if [[ "$BEAMTYPE" == "PbPb" ]]; then if has_detector CTP; then From 3b511ae9b6ea78231b798237ab4add6fdcd36f7f Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Thu, 5 Mar 2026 11:44:26 +0100 Subject: [PATCH 261/362] Add impact parameter as centrality variable (#2287) --- MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns | 1 + MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns | 1 + MC/config/examples/epos4/generator/examplepbpb.optns | 1 + 3 files changed, 3 insertions(+) diff --git a/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns index 9c7df71a3..5c84f533d 100644 --- a/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns +++ b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns @@ -29,4 +29,5 @@ set nfreeze 1 !number of freeze out events per hydro event set modsho 1 !printout every modsho events set centrality 0 !0=min bias set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable set nfull 10 diff --git a/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns index 254a1e4a4..eeaab8cd9 100644 --- a/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns +++ b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns @@ -29,4 +29,5 @@ set nfreeze 1 !number of freeze out events per hydro event set modsho 1 !printout every modsho events set centrality 0 !0=min bias set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable set nfull 10 diff --git a/MC/config/examples/epos4/generator/examplepbpb.optns b/MC/config/examples/epos4/generator/examplepbpb.optns index 217b2db77..49a41c350 100644 --- a/MC/config/examples/epos4/generator/examplepbpb.optns +++ b/MC/config/examples/epos4/generator/examplepbpb.optns @@ -29,4 +29,5 @@ set nfreeze 1 !number of freeze out events per hydro event set modsho 1 !printout every modsho events set centrality 0 !0=min bias set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable set nfull 10 \ No newline at end of file From 888231795dc2ae8349a329bcc45907ef40088456 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 5 Mar 2026 17:49:14 +0100 Subject: [PATCH 262/362] some optimization of time margins for 2026 asynce reco --- .../configurations/asyncReco/setenv_extra.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 843bda18b..2d8a8dffd 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -336,6 +336,8 @@ if [[ "0$OLDVERSION" == "01" ]] && [[ $BEAMTYPE == "PbPb" || $PERIOD == "MAY" || fi fi +EXTRA_PRIMVTX_TimeMargin="" + # some settings in common between workflows and affecting ITS-TPC matching : ${CUT_MATCH_CHI2:=250} if [[ $ALIGNLEVEL == 0 ]]; then @@ -347,7 +349,12 @@ if [[ $ALIGNLEVEL == 0 ]]; then elif [[ $ALIGNLEVEL == 1 ]]; then ERRIB="100e-8" ERROB="100e-8" - [[ -z $TPCITSTIMEERR ]] && TPCITSTIMEERR="0.2" + if [[ $ALIEN_JDL_LPMANCHORYEAR == "2026" ]] ; then + [[ -z $TPCITSTIMEERR ]] && TPCITSTIMEERR="0.05" + EXTRA_PRIMVTX_TimeMargin="pvertexer.timeMarginVertexTime=0.3" + else + [[ -z $TPCITSTIMEERR ]] && TPCITSTIMEERR="0.2" + fi if [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" && $BEAMTYPE == "PbPb" && $ANCHORED_PASS_NUMBER -lt 5 ]] || [[ $PERIOD == "LHC24al" ]] ; then [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" ]] && [[ $BEAMTYPE == "PbPb" ]] && CUT_MATCH_CHI2=80 || CUT_MATCH_CHI2=100 export ITSTPCMATCH="tpcitsMatch.safeMarginTimeCorrErr=2.;tpcitsMatch.XMatchingRef=60.;tpcitsMatch.cutMatchingChi2=$CUT_MATCH_CHI2;;tpcitsMatch.crudeAbsDiffCut[0]=6;tpcitsMatch.crudeAbsDiffCut[1]=6;tpcitsMatch.crudeAbsDiffCut[2]=0.3;tpcitsMatch.crudeAbsDiffCut[3]=0.3;tpcitsMatch.crudeAbsDiffCut[4]=2.5;tpcitsMatch.crudeNSigma2Cut[0]=64;tpcitsMatch.crudeNSigma2Cut[1]=64;tpcitsMatch.crudeNSigma2Cut[2]=64;tpcitsMatch.crudeNSigma2Cut[3]=64;tpcitsMatch.crudeNSigma2Cut[4]=64;" @@ -591,7 +598,6 @@ export ARGS_EXTRA_PROCESS_o2_tof_reco_workflow+=" --use-ccdb" # following comment https://alice.its.cern.ch/jira/browse/O2-2691?focusedCommentId=278262&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-278262 #export PVERTEXER="pvertexer.acceptableScale2=9;pvertexer.minScale2=2.;pvertexer.nSigmaTimeTrack=4.;pvertexer.timeMarginTrackTime=0.5;pvertexer.timeMarginVertexTime=7.;pvertexer.nSigmaTimeCut=10;pvertexer.dbscanMaxDist2=36;pvertexer.dcaTolerance=3.;pvertexer.pullIniCut=100;pvertexer.addZSigma2=0.1;pvertexer.tukey=20.;pvertexer.addZSigma2Debris=0.01;pvertexer.addTimeSigma2Debris=1.;pvertexer.maxChi2Mean=30;pvertexer.timeMarginReattach=3.;pvertexer.addTimeSigma2Debris=1.;pvertexer.dbscanDeltaT=24;pvertexer.maxChi2TZDebris=100;pvertexer.maxMultRatDebris=1.;pvertexer.dbscanAdaptCoef=20.;pvertexer.timeMarginVertexTime=1.3" # updated on 7 Sept 2022 -EXTRA_PRIMVTX_TimeMargin="" if [[ $BEAMTYPE == "PbPb" || $PERIOD == "MAY" || $PERIOD == "JUN" || $PERIOD == LHC22* || $PERIOD == LHC23* ]]; then EXTRA_PRIMVTX_TimeMargin="pvertexer.timeMarginVertexTime=1.3" fi From 22f8bf4203e7436c7e88eb2728ca8c0bf3f20183 Mon Sep 17 00:00:00 2001 From: Sebastian Scheid Date: Fri, 6 Mar 2026 10:53:11 +0100 Subject: [PATCH 263/362] PWGEM: Add HF2ee script for OO (#2290) --- MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh diff --git a/MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh b/MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh new file mode 100644 index 000000000..8026630ff --- /dev/null +++ b/MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC25ae +# + +# example anchoring + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=564356 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC26a2 +export ALIEN_JDL_LPMANCHORRUN=564356 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC25ae +export ALIEN_JDL_LPMANCHORYEAR=2025 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 30/70 sampling for different generators +# No forced beauty decays as we have observed biases + +# generate random number +RNDSIG=$(($RANDOM % 100)) + + +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 30 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini" +elif [[ $RNDSIG -ge 30 && $RNDSIG -lt 100 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini" +fi + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh From 7f272515e9697480ee599176d4b3e91035f50879 Mon Sep 17 00:00:00 2001 From: Raymond Ehlers Date: Fri, 6 Mar 2026 05:40:28 -0800 Subject: [PATCH 264/362] Add JJ config for gap 3 test production (#2289) * Fix typo in comment * Add JJ config for gap 3 test production --- .../GeneratorJE_gapgen3_hook_pp5360GeV.ini | 9 +++ .../GeneratorJE_gapgen2_hook_pp13600GeV.C | 2 +- .../GeneratorJE_gapgen3_hook_pp5360GeV.C | 71 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 MC/config/PWGGAJE/ini/GeneratorJE_gapgen3_hook_pp5360GeV.ini create mode 100644 MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen3_hook_pp5360GeV.C diff --git a/MC/config/PWGGAJE/ini/GeneratorJE_gapgen3_hook_pp5360GeV.ini b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen3_hook_pp5360GeV.ini new file mode 100644 index 000000000..c708379a8 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen3_hook_pp5360GeV.ini @@ -0,0 +1,9 @@ +### jet-jet production with MB Gap 3 for pp anchored to Pb-Pb periods +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C +funcName = getGeneratorPythia8GapGenJE(3,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias_pp5360GeV.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet_pp5360GeV.cfg") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet_pp5360GeV.cfg +includePartonEvent=true diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C index 6f32003fe..3364b9f6d 100644 --- a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C +++ b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - float ratioTrigger = 1./2; // one event triggered out of 5 + float ratioTrigger = 1./2; // one event triggered out of 2 TFile file(path.c_str(), "READ"); diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen3_hook_pp5360GeV.C b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen3_hook_pp5360GeV.C new file mode 100644 index 000000000..db42706cb --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen3_hook_pp5360GeV.C @@ -0,0 +1,71 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + float ratioTrigger = 1./3; // one event triggered out of 3 + + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsJetJet{}; + float sumWeightsMB{}, sumWeightsJetJet{}; + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information and event weights + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (eventHeader->hasInfo(o2::dataformats::MCInfoKeys::weight)) { + float weight = eventHeader->getInfo(o2::dataformats::MCInfoKeys::weight,isValid); + if (subGeneratorId == 0) { + nEventsMB++; + sumWeightsMB += weight; + } + else if (subGeneratorId == 1) { + nEventsJetJet++; + sumWeightsJetJet += weight; + } + } + } + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << " sum of weights for MB events: " << sumWeightsMB << "\n"; + std::cout << "# Jet-jet events " << nEventsJetJet << "\n"; + std::cout << " sum of weights jet-jet events: " << sumWeightsJetJet << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsJetJet < nEvents * ratioTrigger * 0.95 || nEventsJetJet > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of jet-jet generated events different than expected\n"; + return 1; + } + if(nEventsMB < sumWeightsMB * 0.95 || nEventsMB > sumWeightsMB * 1.05) { + std::cerr << "Weights of MB events do not = 1 as expected\n"; + return 1; + } + if(sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} From 12e659bb41f6bf2a7bc851772f442dae753a1a28 Mon Sep 17 00:00:00 2001 From: chengtt0406 <39661669+chengtt0406@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:11:15 +0700 Subject: [PATCH 265/362] Force Xic0 and Omegac0 decay via external decayer (#2293) * Force Xic0 and Omegac0 decay via external decayer * Add back previous file --- .../decayer/force_hadronic_Xic0_Omegac.cfg | 44 ++++++++++++ .../geant4_externaldecayer_omegac_xic.in | 68 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 MC/config/PWGHF/pythia8/decayer/force_hadronic_Xic0_Omegac.cfg create mode 100644 MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_omegac_xic.in diff --git a/MC/config/PWGHF/pythia8/decayer/force_hadronic_Xic0_Omegac.cfg b/MC/config/PWGHF/pythia8/decayer/force_hadronic_Xic0_Omegac.cfg new file mode 100644 index 000000000..457b52847 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/force_hadronic_Xic0_Omegac.cfg @@ -0,0 +1,44 @@ +################################################### +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: March 2025 +################################################### + +Init:showChangedParticleData = on + +4332:tau0 = 0.0803 # Omega_c0 +4132:tau0 = 0.0455 # Xi_c0 + +4332:onMode = off +4132:onMode = off + +# Omega_c0 (4332) +4332:oneChannel = 1 0.4 0 3334 211 # Omega- pi+ +4332:addChannel = 1 0.4 0 3312 211 # Xi- pi+ +4332:addChannel = 1 0.2 0 3312 321 # Xi- K+ + +# Xi_c0 (4132) +4132:oneChannel = 1 0.4 0 3312 211 # Xi- pi+ +4132:addChannel = 1 0.4 0 3334 321 # Omega- K+ +4132:addChannel = 1 0.2 0 3312 321 # Xi- K+ + +# Xi- -> Lambda pi- +3312:onMode = off +3312:onIfAll = 3122 -211 + +# Omega- -> Lambda K- +3334:onMode = off +3334:onIfAll = 3122 -321 + +# Lambda -> p pi- +3122:onMode = off +3122:onIfAll = 2212 -211 + +# Omega_c0 +4332:onIfMatch = 3334 211 +4332:onIfMatch = 3312 211 +4332:onIfMatch = 3334 321 +4332:onIfMatch = 3312 321 + +# Xi_c0 +4132:onIfMatch = 3312 211 +4132:onIfMatch = 3334 321 diff --git a/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_omegac_xic.in b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_omegac_xic.in new file mode 100644 index 000000000..40fea08d1 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_omegac_xic.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection omega_c0 anti_omega_c0 xi_c0 anti_xi_c0 From 690deb19afc6cea3fd98bbcc54069fe6d1797523 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Mon, 9 Mar 2026 14:43:02 +0530 Subject: [PATCH 266/362] [PWGLF] Added configuration for baryonic resonances (#2291) * Add files via upload * Added configuration for baryonic resonances * updated PDG for Xi1820 * Update Xi(1820) resonance IDs in GeneratorLF * Update PDG codes for baryonic resonance list * Update Xi1820 resonance configuration IDs --- ...LF_ResonancesBaryonic_pp1360_injection.ini | 10 ++ ...orLF_ResonancesBaryonic_pp1360_injection.C | 150 ++++++++++++++++++ .../resonancelistgun_baryonic_inj.json | 90 +++++++++++ .../pythia8/generator/resonances_baryonic.cfg | 28 ++++ 4 files changed, 278 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C create mode 100644 MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json create mode 100644 MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini new file mode 100644 index 000000000..5fb6619ea --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C new file mode 100644 index 000000000..7ee3c81c2 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C @@ -0,0 +1,150 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324, // Xi(1530)0bar + 123314, // Xi(1820)- + -123314, // Xi(1820)+ + 123324, // Xi(1820)0 + -123324 // Xi(1820)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211}, // Xi(1530)0bar + {3122, -321}, // Xi(1820)- + {-3122, 321}, // Xi(1820)+ + {3122, 310}, // Xi(1820)0 + {-3122, -310} // Xi(1820)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json new file mode 100644 index 000000000..60864a9cd --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json @@ -0,0 +1,90 @@ +{ + "Lambda(1520)0" : { + "pdg": 102134, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "anti-Lambda(1520)0" : { + "pdg": -102134, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "Xi(1530)0" : { + "pdg": 3324, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "anti-Xi(1530)0" : { + "pdg": -3324, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "Xi(1820)0" : { + "pdg": 123324, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "Anti-Xi(1820)0" : { + "pdg": -123324, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "Xi(1820)-" : { + "pdg": 123314, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "Xi(1820)+" : { + "pdg": -123314, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + } +} diff --git a/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg b/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg new file mode 100644 index 000000000..e05459994 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg @@ -0,0 +1,28 @@ +### Define resonance +ProcessLevel:all = off # will not look for the 'process' + +### Lambda1520 +# id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +102134:all = Lambda1520 Lambda1520bar 4 0 0 1.51950 0.01560 1.47 1.60 0 +102134:oneChannel = 1 1.000 0 2212 -321 +102134:onMode = off +102134:onIfMatch = 2212 -321 + +### Xi1530 +# id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +3324:all = Xi1530 Xi1530bar 4 0 0 1.53180 0.0091 1.50 1.59 0 +3324:oneChannel = 1 1.000 0 3312 211 +3324:onMode = off +3324:onIfMatch = 3312 211 + +### Xi1820 +123324:all = Xi1820 Xi1820bar 4 0 0 1.823 0.024 1.75 1.95 0 +123324:oneChannel = 1 1.000 0 3122 310 +123324:onMode = off +123324:onIfMatch = 3122 310 + +123314:all = Xi1820Minus Xi1820Plus 4 -3 0 1.823 0.024 1.75 1.95 0 +123314:oneChannel = 1 1.000 0 3122 -321 +123314:onMode = off +123314:onIfMatch = 3122 -321 + From eb2b8919cc5bb0b74de534ed9b2530bd311d7ecd Mon Sep 17 00:00:00 2001 From: laguiard <141957089+laguiard741@users.noreply.github.com> Date: Mon, 9 Mar 2026 11:33:29 -0300 Subject: [PATCH 267/362] Add Pythia8 trigger gap generator config for pO 9.6 TeV (#2292) --- ...siPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini | 7 ++ ...JpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C | 84 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C diff --git a/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini new file mode 100644 index 000000000..c660aae24 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C +funcName=GeneratorInclusiveJpsiPsi2S_EvtGenMidY(5,-1.5,1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From a82a0657222e1ffd74afb43b4750c0d4af3b13d9 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Wed, 11 Mar 2026 08:01:20 +0530 Subject: [PATCH 268/362] Update cfg and decay chain for exoticAll resonances (#2295) * Update resonance parameters in exoticAll.json * Modify Lambda1520 resonance decay channels Updated resonance configuration for Lambda1520 by modifying decay channels and branching ratios. * Update PDG codes and particle names in JSON * Uncomment Lambda1520 resonance configuration * Update resonances.cfg * Remove f_0(980) and K1(1270) from resonance list Removed entries for f_0(980) and K1(1270) from the resonance list. --- .../generator/resonancelistgun_exoticAll.json | 201 ++++++++---------- .../PWGLF/pythia8/generator/resonances.cfg | 24 +-- 2 files changed, 86 insertions(+), 139 deletions(-) diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json index 70212867a..3961322b6 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json @@ -1,189 +1,156 @@ { - "f_0(980)": { - "pdg": 9010221, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, - "genDecayed": true - }, "f_2(1270)": { "pdg": 225, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_0(1370)": { "pdg": 10221, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_0(1500)": { "pdg": 9030221, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_0(1710)": { "pdg": 10331, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_1(1285)": { "pdg": 20223, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_1(1420)": { "pdg": 20333, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_2(1525)": { "pdg": 335, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "a_2(1320)": { "pdg": 115, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, - "genDecayed": true - }, - "K1(1270)+": { - "pdg": 10323, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, - "genDecayed": true - }, - "K1(1270)-": { - "pdg": -10323, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "Lambda(1520)0" : { "pdg": 102134, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "anti-Lambda(1520)0" : { "pdg": -102134, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "Xi(1820)0": { "pdg": 123314, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "Anti-Xi(1820)0": { "pdg": -123314, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "Xi(1820)-": { "pdg": 123324, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "Xi(1820)+": { "pdg": -123324, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonances.cfg b/MC/config/PWGLF/pythia8/generator/resonances.cfg index b9d2750eb..d35eaba2e 100644 --- a/MC/config/PWGLF/pythia8/generator/resonances.cfg +++ b/MC/config/PWGLF/pythia8/generator/resonances.cfg @@ -6,32 +6,12 @@ ProcessLevel:all = off # will not look for the 'process' 102132:addChannel = 1 0.33333 5 3222 -211 102132:addChannel = 1 0.33333 5 3212 111 - # id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +### Lambda1520 102134:all = Lambda1520 Lambda1520bar 4 0 0 1.51950 0.01560 1.47 1.60 0 - -### add Resonance decays absent in PYTHIA8 decay table and set BRs from PDG for other -102134:oneChannel = 1 0.229944 5 2212 -321 -102134:addChannel = 1 0.229944 5 2112 -311 -102134:addChannel = 1 0.143076 5 3222 -211 -102134:addChannel = 1 0.143076 5 3212 111 -102134:addChannel = 1 0.143076 5 3112 211 -102134:addChannel = 1 0.034066 4 3224 -211 -102134:addChannel = 1 0.034066 4 3214 111 -102134:addChannel = 1 0.034066 4 3114 211 -102134:addChannel = 1 0.008687 3 3122 22 - +102134:oneChannel = 1 1.000 0 2212 -321 102134:onMode = off - 102134:onIfMatch = 2212 -321 -102134:onIfMatch = 2112 -311 -102134:onIfMatch = 3222 -211 -102134:onIfMatch = 3212 111 -102134:onIfMatch = 3112 211 -102134:onIfMatch = 3224 -211 -102134:onIfMatch = 3214 111 -102134:onIfMatch = 3114 211 -102134:onIfMatch = 3122 22 ### Xi1820 123324:all = Xi1820 Xi1820bar 0 0 0 1.8234 0.0 0.0 0.0 0 From 5e972df25b70db4d8bcf352362fc5972f972f688 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:59:59 +0100 Subject: [PATCH 269/362] Add generator for Sigma-Proton correlations (#2296) Co-authored-by: Francesco Mazzaschi --- .../ini/GeneratorSigmaProtonTriggered.ini | 5 + .../ini/tests/GeneratorSigmaProtonTriggered.C | 49 +++++ .../pythia8/generator_pythia8_sigma_hadron.C | 197 ++++++++++++++++++ MC/run/PWGLF/run_SigmaProtonTriggered.sh | 36 ++++ 4 files changed, 287 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorSigmaProtonTriggered.C create mode 100644 MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C create mode 100644 MC/run/PWGLF/run_SigmaProtonTriggered.sh diff --git a/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini b/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini new file mode 100644 index 000000000..d14e19cbe --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini @@ -0,0 +1,5 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C +funcName=generateSigmaHadron(2212, 3, 0.5, 10, 0.8) +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorSigmaProtonTriggered.C b/MC/config/PWGLF/ini/tests/GeneratorSigmaProtonTriggered.C new file mode 100644 index 000000000..91d47a9a6 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorSigmaProtonTriggered.C @@ -0,0 +1,49 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector* tracks = nullptr; + tree->SetBranchAddress("MCTrack", &tracks); + + const auto nEvents = tree->GetEntries(); + + for (Long64_t iEv = 0; iEv < nEvents; ++iEv) { + tree->GetEntry(iEv); + + bool hasSigma = false; + bool hasProton = false; + + for (const auto& track : *tracks) { + const int pdg = track.GetPdgCode(); + const int absPdg = std::abs(pdg); + + if (absPdg == 3112 || absPdg == 3222) { + hasSigma = true; + } + + if (pdg == 2212) { + hasProton = true; + } + + if (hasSigma && hasProton) { + std::cout << "Found event of interest at entry " << iEv << "\n"; + return 0; + } + } + } + + std::cerr << "No Sigma-proton event of interest\n"; + return 1; +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C b/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C new file mode 100644 index 000000000..296dd78fc --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C @@ -0,0 +1,197 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include "TSystem.h" +#include "TVector2.h" +#include "fairlogger/Logger.h" +#include +#include +#include +#include +using namespace Pythia8; +#endif + +/// Event of interest: +/// an event that contains at least one Sigma- or Sigma+ +/// paired with at least one hadron of a specific PDG code, +/// and the pair has k* < kStarMax + +class GeneratorPythia8SigmaHadron : public o2::eventgen::GeneratorPythia8 +{ +public: + /// Constructor + GeneratorPythia8SigmaHadron(int hadronPdg, int gapSize = 4, double minPt = 0.2, + double maxPt = 10, double maxEta = 0.8, double kStarMax = 1.0) + : o2::eventgen::GeneratorPythia8(), + mHadronPdg(hadronPdg), + mGapSize(gapSize), + mMinPt(minPt), + mMaxPt(maxPt), + mMaxEta(maxEta), + mKStarMax(kStarMax) + { + fmt::printf( + ">> Pythia8 generator: Sigma± + hadron(PDG=%d), gap = %d, minPt = %f, maxPt = %f, |eta| < %f, k* < %f\n", + hadronPdg, gapSize, minPt, maxPt, maxEta, kStarMax); + } + + ~GeneratorPythia8SigmaHadron() = default; + + bool Init() override + { + addSubGenerator(0, "Pythia8 events with Sigma± and a specific hadron"); + return o2::eventgen::GeneratorPythia8::Init(); + } + +protected: + /// Check whether particle descends from a Sigma+ or Sigma- + bool isFromSigmaDecay(const Pythia8::Particle& p, const Pythia8::Event& event) + { + int motherId = p.mother1(); + + while (motherId > 0) { + const auto& mother = event[motherId]; + const int absMotherPdg = std::abs(mother.id()); + + if (absMotherPdg == 3112 || absMotherPdg == 3222) { + return true; + } + + motherId = mother.mother1(); + } + + return false; + } + + /// k* of a pair from invariant masses and 4-momenta + /// k* = momentum of either particle in the pair rest frame + double computeKStar(const Pythia8::Particle& p1, const Pythia8::Particle& p2) const + { + const double e = p1.e() + p2.e(); + const double px = p1.px() + p2.px(); + const double py = p1.py() + p2.py(); + const double pz = p1.pz() + p2.pz(); + const double s = e * e - px * px - py * py - pz * pz; + if (s <= 0.) { + return 1.e9; + } + const double m1 = p1.m(); + const double m2 = p2.m(); + const double term1 = s - std::pow(m1 + m2, 2); + const double term2 = s - std::pow(m1 - m2, 2); + const double lambda = term1 * term2; + + if (lambda <= 0.) { + return 0.; + } + return 0.5 * std::sqrt(lambda / s); + } + + bool generateEvent() override + { + fmt::printf(">> Generating event %llu\n", mGeneratedEvents); + + bool genOk = false; + int localCounter{0}; + constexpr int kMaxTries{100000}; + + // Accept mGapSize events unconditionally, then one triggered event + if (mGeneratedEvents % (mGapSize + 1) < mGapSize) { + genOk = GeneratorPythia8::generateEvent(); + fmt::printf(">> Gap-event (no trigger check)\n"); + } else { + while (!genOk && localCounter < kMaxTries) { + if (GeneratorPythia8::generateEvent()) { + genOk = selectEvent(mPythia.event); + } + localCounter++; + } + + if (!genOk) { + fmt::printf("Failed to generate triggered event after %d tries\n", kMaxTries); + return false; + } + + fmt::printf(">> Triggered event: accepted after %d iterations (Sigma± + hadron PDG=%d, k* < %f)\n", + localCounter, mHadronPdg, mKStarMax); + } + + notifySubGenerator(0); + mGeneratedEvents++; + return true; + } + + bool selectEvent(Pythia8::Event& event) + { + std::vector sigmaIndices; + std::vector hadronIndices; + + for (int i = 0; i < event.size(); i++) { + const auto& p = event[i]; + + if (std::abs(p.eta()) > mMaxEta || p.pT() < mMinPt || p.pT() > mMaxPt) { + continue; + } + + const int pdg = p.id(); + const int absPdg = std::abs(pdg); + + // Sigma- or Sigma+ + if (absPdg == 3112 || absPdg == 3222) { + sigmaIndices.push_back(i); + } + + if (std::abs(pdg) == mHadronPdg && !isFromSigmaDecay(p, event)) { + hadronIndices.push_back(i); + } + } + if (sigmaIndices.empty() || hadronIndices.empty()) { + return false; + } + + for (const auto iSigma : sigmaIndices) { + for (const auto iHadron : hadronIndices) { + + if (iSigma == iHadron) { + continue; + } + + const auto& sigma = event[iSigma]; + const auto& hadron = event[iHadron]; + + const double kStar = computeKStar(sigma, hadron); + if (kStar < mKStarMax) { + return true; + } + } + } + + return false; + } + +private: + int mHadronPdg{211}; + int mGapSize{4}; + double mMinPt{0.2}; + double mMaxPt{10.0}; + double mMaxEta{0.8}; + double mKStarMax{1.0}; + uint64_t mGeneratedEvents{0}; +}; + +///___________________________________________________________ +FairGenerator* generateSigmaHadron(int hadronPdg, int gap = 4, double minPt = 0.2, + double maxPt = 10, double maxEta = 0.8, double kStarMax = 1.0) +{ + auto myGenerator = new GeneratorPythia8SigmaHadron(hadronPdg, gap, minPt, maxPt, maxEta, kStarMax); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGenerator->readString("Random:setSeed on"); + myGenerator->readString("Random:seed " + std::to_string(seed)); + return myGenerator; +} \ No newline at end of file diff --git a/MC/run/PWGLF/run_SigmaProtonTriggered.sh b/MC/run/PWGLF/run_SigmaProtonTriggered.sh new file mode 100644 index 000000000..6d3d01f50 --- /dev/null +++ b/MC/run/PWGLF/run_SigmaProtonTriggered.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# 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 + +# ----------- CONFIGURE -------------------------- +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +#export ALICEO2_CCDB_LOCALCACHE=.ccdb + + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +SIMENGINE=${SIMENGINE:-TGeant4} +NSIGEVENTS=${NSIGEVENTS:-100} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-500000} +SYSTEM=${SYSTEM:-pp} +ENERGY=${ENERGY:-13600} +CFGINIFILE=${CFGINIFILE:-"${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini"} +SEED="-seed 1995" + +# create workflow +O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +$O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external \ + -j ${NWORKERS} \ + -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} \ + -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6.;" \ + ${SEED} \ + -e ${SIMENGINE} \ + -ini $CFGINIFILE + +# run workflow +O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS From 47f914f769cd81e3e40e2fd59abb3d8d1383cd78 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 12 Mar 2026 16:03:05 +0100 Subject: [PATCH 270/362] Event-pools: Consistency fix for vertexing For event pools, the vertex applied to events should (0,0,0). We tried to do this by setting 'kNoVertex' to the collision context... which unfortunately was not doing what we wanted. Instead of putting (0,0,0) this simply does not put a vertex into the collision context. This lead to the consequence that the vertex was fixed during event generation later. Problem fixed by imposing `kNoVertex` also on the event generation step **in case of event pool generation**. --- MC/bin/o2dpg_sim_workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index e793f17f6..9126bd4e9 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -615,7 +615,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): # No vertexing for event pool generation; otherwise the vertex comes from CCDB and later from CollContext # (Note that the CCDB case covers the kDiamond case, since this is picked up in GRP_TASK) vtxmode_precoll = 'kNoVertex' if args.make_evtpool else 'kCCDB' -vtxmode_sgngen = 'kCollContext' +vtxmode_sgngen = 'kNoVertex' if args.make_evtpool else 'kCollContext' # preproduce the collision context / timeframe structure for all timeframes at once precollneeds=[GRP_TASK['name']] From 248b92e3ba54f089f6c67e95dc72f30f4d671689 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 13 Mar 2026 09:39:54 +0100 Subject: [PATCH 271/362] MC: Add reco-pass meta-data to AOD The reco-pass field was not filled in MC AOD. Using the `LPMPASSNAME` variable to set it, in analogy to how it is done in the async scripts. Related to https://its.cern.ch/jira/browse/O2-6724 --- MC/bin/o2dpg_sim_workflow.py | 1 + 1 file changed, 1 insertion(+) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 9126bd4e9..97f3195b8 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1809,6 +1809,7 @@ def getDigiTaskName(det): f"--lpmp-prod-tag {args.productionTag}", "--anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}", "--anchor-prod ${ALIEN_JDL_LPMANCHORPRODUCTION:-unknown}", + "--reco-pass ${ALIEN_JDL_LPMPASSNAME:-unknown}", created_by_option, "--combine-source-devices" if not args.no_combine_dpl_devices else "", "--disable-mc" if args.no_mc_labels else "", From c0c32a8c52312520a3462faa970577b551f4682a Mon Sep 17 00:00:00 2001 From: rmunzer <97919772+rmunzer@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:47:59 +0100 Subject: [PATCH 272/362] Update cutAbsEta value to 1.5 in tpc.json --- DATA/production/qc-async/tpc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/production/qc-async/tpc.json b/DATA/production/qc-async/tpc.json index b95eff981..f172cffe4 100644 --- a/DATA/production/qc-async/tpc.json +++ b/DATA/production/qc-async/tpc.json @@ -83,7 +83,7 @@ "query": "inputTracks:TPC/TRACKS/0;inputClusters:TPC/CLUSTERNATIVE;inputClusRefs:TPC/CLUSREFS/0" }, "taskParameters": { - "cutAbsEta": "1.", + "cutAbsEta": "1.5", "cutMinNCluster": "60", "cutMindEdxTot": "20.", "seed": "0", From 1aef95852bd47085e68831fcec04f6b120fa8dac Mon Sep 17 00:00:00 2001 From: rmunzer <97919772+rmunzer@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:51:17 +0100 Subject: [PATCH 273/362] Update cutAbsEta value from '1.' to '1.5' --- DATA/production/qc-sync/tpc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/production/qc-sync/tpc.json b/DATA/production/qc-sync/tpc.json index daabaa239..d4fa3a484 100644 --- a/DATA/production/qc-sync/tpc.json +++ b/DATA/production/qc-sync/tpc.json @@ -106,7 +106,7 @@ "name": "tpc-tracks" }, "taskParameters": { - "cutAbsEta": "1.", + "cutAbsEta": "1.5", "cutMinNCluster": "60", "cutMindEdxTot": "20." }, From 3fc4a8e44eb60ce0f2358944d1a53d8722caa284 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Sat, 14 Mar 2026 22:56:07 +0530 Subject: [PATCH 274/362] Remove Xi(1820) resonances from JSON configuration (#2299) --- .../generator/resonancelistgun_exoticAll.json | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json index 3961322b6..800756307 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json @@ -108,49 +108,5 @@ "rapidityMin": -1.0, "rapidityMax": 1.0, "genDecayed": true - }, - "Xi(1820)0": { - "pdg": 123314, - "n": 3, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true - }, - "Anti-Xi(1820)0": { - "pdg": -123314, - "n": 3, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true - }, - "Xi(1820)-": { - "pdg": 123324, - "n": 3, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true - }, - "Xi(1820)+": { - "pdg": -123324, - "n": 3, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true } } From c32c968cf402b1a9fe832931cbff1d6136014380 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Sat, 14 Mar 2026 23:49:10 +0530 Subject: [PATCH 275/362] Added configuration for exotic + Lambda1520 resonances with gap 2 (#2300) * Add GeneratorLF_Resonances_pp_exoticAll_gap2.ini * Add test for resonance injection * Update injectedPDGs and decayDaughters vectors --- ...neratorLF_Resonances_pp_exoticAll_gap2.ini | 10 ++ ...GeneratorLF_Resonances_pp_exoticAll_gap2.C | 154 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll_gap2.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini new file mode 100644 index 000000000..add3bb81e --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 2, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] # this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll_gap2.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll_gap2.C new file mode 100644 index 000000000..74076d41c --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll_gap2.C @@ -0,0 +1,154 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 225, // f_2(1270) + 10221, // f_0(1370) + 9030221, // f_0(1500) + 10331, // f_0(1710) + 20223, // f_1(1285) + 20333, // f_1(1420) + 335, // f_2(1525) + 115, // a_2(1320) + 102134, // Lambda(1520)0 + -102134 // Lambda(1520)0bar + }; + std::vector> decayDaughters = { + {310, 310}, // f_2(1270) + {310, 310}, // f_0(1370) + {310, 310}, // f_0(1500) + {310, 310}, // f_0(1710) + {310, -321, 211}, // f_1(1285) + {310, -321, 211}, // f_1(1420) + {310, 310}, // f_2(1525) + {310, 310}, // a_2(1320) + {2212, -321}, // Lambda(1520)0 + {-2212, 321} // Lambda(1520)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } From 1c02908b70fddfb2cfcab266e16acdaca513553d Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Sun, 15 Mar 2026 15:47:00 +0530 Subject: [PATCH 276/362] Updated gap parameter to 4 and removed Xi1820 (#2301) * Update funcName parameter in generator configuration * Update baryonic resonance parameters and remove entries * Refactor injectedPDGs and decayDaughters vectors --- ...LF_ResonancesBaryonic_pp1360_injection.ini | 4 +- ...orLF_ResonancesBaryonic_pp1360_injection.C | 12 +---- .../resonancelistgun_baryonic_inj.json | 52 ++----------------- 3 files changed, 8 insertions(+), 60 deletions(-) diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini index 5fb6619ea..7d9613efa 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini @@ -1,8 +1,8 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -[GeneratorPythia8] # if triggered then this will be used as the background event +[GeneratorPythia8] # this will be used as the background event config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C index 7ee3c81c2..27069c08f 100644 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C @@ -9,21 +9,13 @@ int External() 102134, // Lambda(1520)0 -102134, // Lambda(1520)0bar 3324, // Xi(1530)0 - -3324, // Xi(1530)0bar - 123314, // Xi(1820)- - -123314, // Xi(1820)+ - 123324, // Xi(1820)0 - -123324 // Xi(1820)0bar + -3324 // Xi(1530)0bar }; std::vector> decayDaughters = { {2212, -321}, // Lambda(1520)0 {-2212, 321}, // Lambda(1520)0bar {3312, 211}, // Xi(1530)0 - {-3312, -211}, // Xi(1530)0bar - {3122, -321}, // Xi(1820)- - {-3122, 321}, // Xi(1820)+ - {3122, 310}, // Xi(1820)0 - {-3122, -310} // Xi(1820)0bar + {-3312, -211} // Xi(1530)0bar }; auto nInjection = injectedPDGs.size(); diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json index 60864a9cd..11a339251 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json @@ -1,7 +1,7 @@ { "Lambda(1520)0" : { "pdg": 102134, - "n": 5, + "n": 3, "ptMin": 0.0, "ptMax": 15, "etaMin": -1.0, @@ -12,7 +12,7 @@ }, "anti-Lambda(1520)0" : { "pdg": -102134, - "n": 5, + "n": 3, "ptMin": 0.0, "ptMax": 15, "etaMin": -1.0, @@ -23,7 +23,7 @@ }, "Xi(1530)0" : { "pdg": 3324, - "n": 5, + "n": 3, "ptMin": 0.0, "ptMax": 15, "etaMin": -1.0, @@ -34,51 +34,7 @@ }, "anti-Xi(1530)0" : { "pdg": -3324, - "n": 5, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true - }, - "Xi(1820)0" : { - "pdg": 123324, - "n": 5, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true - }, - "Anti-Xi(1820)0" : { - "pdg": -123324, - "n": 5, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true - }, - "Xi(1820)-" : { - "pdg": 123314, - "n": 5, - "ptMin": 0.0, - "ptMax": 15, - "etaMin": -1.0, - "etaMax": 1.0, - "rapidityMin": -1.0, - "rapidityMax": 1.0, - "genDecayed": true - }, - "Xi(1820)+" : { - "pdg": -123314, - "n": 5, + "n": 3, "ptMin": 0.0, "ptMax": 15, "etaMin": -1.0, From ddbdc5484d9760757fc89fbc125cf86925179381 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Mon, 16 Mar 2026 17:30:39 +0100 Subject: [PATCH 277/362] update params (#2302) Co-authored-by: Francesco Mazzaschi --- MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini b/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini index d14e19cbe..923a5947d 100644 --- a/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini +++ b/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini @@ -1,5 +1,5 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C -funcName=generateSigmaHadron(2212, 3, 0.5, 10, 0.8) +funcName=generateSigmaHadron(2212, 2, 1, 10, 0.8) [GeneratorPythia8] config=${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg \ No newline at end of file From b5e99d7709f224e5dbd9cb6152ae47a240280e58 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Wed, 18 Mar 2026 16:44:27 +0100 Subject: [PATCH 278/362] Forward error code to async_pass.sh script --- .../configurations/asyncReco/async_pass.sh | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index fdb542750..508198546 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -492,6 +492,12 @@ WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT=${ALIEN_JDL_WORKFLOWDETECTORSEXCLUDEQC:-} # print workflow if [[ $ALIEN_JDL_SSPLITWF != "1" ]]; then env $SETTING_ROOT_OUTPUT IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS_EXCLUDE_QC=$WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list > workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow is $exitcode" > validation_error.message + echo "exit code from printing workflow is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -532,6 +538,12 @@ else export WORKFLOW_PARAMETERS=$(echo $WORKFLOW_PARAMETERS | sed -e "s/,$i,/,/g" -e "s/^$i,//" -e "s/,$i"'$'"//" -e "s/^$i"'$'"//") done env DISABLE_ROOT_OUTPUT=0 IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=TPC,CTP WORKFLOW_DETECTORS_MATCHING= ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 1) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 1) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -570,6 +582,12 @@ else export WORKFLOW_PARAMETERS=$(echo $WORKFLOW_PARAMETERS | sed -e "s/,$i,/,/g" -e "s/^$i,//" -e "s/,$i"'$'"//" -e "s/^$i"'$'"//") done env DISABLE_ROOT_OUTPUT=0 IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=ALL WORKFLOW_DETECTORS_EXCLUDE=TPC,$DETECTORS_EXCLUDE WORKFLOW_DETECTORS_MATCHING= ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 2) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 2) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -655,6 +673,12 @@ else STEP_3_ROOT_OUTPUT=$SETTING_ROOT_OUTPUT fi env $STEP_3_ROOT_OUTPUT IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=ALL WORKFLOW_DETECTORS_EXCLUDE=$DETECTORS_EXCLUDE WORKFLOW_DETECTORS_USE_GLOBAL_READER_TRACKS=$READ_TRACKS WORKFLOW_DETECTORS_USE_GLOBAL_READER_CLUSTERS=$READ_CLUSTERS WORKFLOW_DETECTORS_EXCLUDE_GLOBAL_READER_TRACKS=HMP WORKFLOW_DETECTORS_EXCLUDE_QC=$WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT,$DETECTORS_EXCLUDE ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 3) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 3) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -693,6 +717,12 @@ else WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT+=",CPV" echo "QC_JSON_FROM_OUTSIDE = $QC_JSON_FROM_OUTSIDE" env $SETTING_ROOT_OUTPUT IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=ALL WORKFLOW_DETECTORS_EXCLUDE=$DETECTORS_EXCLUDE WORKFLOW_DETECTORS_USE_GLOBAL_READER_TRACKS=$READ_TRACKS WORKFLOW_DETECTORS_USE_GLOBAL_READER_CLUSTERS=$READ_CLUSTERS WORKFLOW_DETECTORS_EXCLUDE_GLOBAL_READER_TRACKS= WORKFLOW_DETECTORS_EXCLUDE_QC=$WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT,$DETECTORS_EXCLUDE ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 4) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 4) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` From 418fe243c9f00ce63f260c1085a7e2ce4bf85cca Mon Sep 17 00:00:00 2001 From: rbailhac Date: Fri, 20 Mar 2026 16:15:41 +0100 Subject: [PATCH 279/362] Generator for HF enhanced PbPb MC for dielectron analysis (#2304) * HF pp embedded in Pb--Pb simulated events * HF pp events embedded in Pb--Pb events for dielectron analysis * Fix the test of the generators --- .../generator/Generator_pythia8_HFLepton_pp.C | 202 +++++++++ .../Generator_pythia8_embed_HFLepton.C | 396 ++++++++++++++++++ ...orHF_BeautyNoForcedDecay_PbPb_electron.ini | 9 + .../ini/GeneratorHF_Charm_PbPb_electron.ini | 9 + ...atorHF_BeautyNoForcedDecay_PbPb_electron.C | 111 +++++ .../tests/GeneratorHF_Charm_PbPb_electron.C | 116 +++++ MC/run/PWGEM/runHFToDielectrons_PbPb.sh | 51 +++ 7 files changed, 894 insertions(+) create mode 100644 MC/config/PWGEM/external/generator/Generator_pythia8_HFLepton_pp.C create mode 100644 MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C create mode 100644 MC/config/PWGEM/ini/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHF_Charm_PbPb_electron.ini create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHF_Charm_PbPb_electron.C create mode 100644 MC/run/PWGEM/runHFToDielectrons_PbPb.sh diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_HFLepton_pp.C b/MC/config/PWGEM/external/generator/Generator_pythia8_HFLepton_pp.C new file mode 100644 index 000000000..854d6ff42 --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_HFLepton_pp.C @@ -0,0 +1,202 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include + +using namespace Pythia8; + +class GeneratorPythia8HFLeptonpp : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8HFLeptonpp() = default; + + /// constructor + GeneratorPythia8HFLeptonpp(TString configsignal, int quarkPdg = 4, int lInputExternalID = 0) + { + + lGeneratedEvents = 0; + lExternalID = lInputExternalID; + mQuarkPdg = quarkPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(1)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.readString("Beams:eCM = 5360.0"); + pythiaObjectSignal.init(); + cout << "Initalization of signal event is complete" << endl; + + // flag the generators using type + // addCocktailConstituent(type, "interesting"); + // addCocktailConstitent(0, "minbias"); + // Add Sub generators + addSubGenerator(1, "charm lepton"); + addSubGenerator(2, "beauty forced decay"); + addSubGenerator(3, "beauty no foced decay"); + } + + /// Destructor + ~GeneratorPythia8HFLeptonpp() = default; + + void addTriggerOnDaughter(int nb, int pdg) + { + mNbDaughter = nb; + mPdgDaughter = pdg; + }; + void setQuarkRapidity(float yMin, float yMax) + { + mQuarkRapidityMin = yMin; + mQuarkRapidityMax = yMax; + }; + void setDaughterRapidity(float yMin, float yMax) + { + mDaughterRapidityMin = yMin; + mDaughterRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + bool isGoodAtPartonLevel = false, isGoodAtDaughterLevel = (mPdgDaughter != 0) ? false : true; + int nbDaughter = 0; + for (auto iPart{0}; iPart < event.size(); ++iPart) { + // search for Q-Qbar mother with at least one Q in rapidity window + if (!isGoodAtPartonLevel) { + auto daughterList = event[iPart].daughterList(); + bool hasQ = false, hasQbar = false, atSelectedY = false; + for (auto iDau : daughterList) { + if (event[iDau].id() == mQuarkPdg) { + hasQ = true; + } + if (event[iDau].id() == -mQuarkPdg) { + hasQbar = true; + } + if ((std::abs(event[iDau].id()) == mQuarkPdg) && (event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + atSelectedY = true; + } + if (hasQ && hasQbar && atSelectedY) { + isGoodAtPartonLevel = true; + } + } + // search for mNbDaughter daughters of type mPdgDaughter in rapidity window + if (!isGoodAtDaughterLevel) { + int id = std::abs(event[iPart].id()); + float rap = event[iPart].y(); + if (id == mPdgDaughter) { + int motherindexa = event[iPart].mother1(); + if (motherindexa > 0) { + int idmother = std::abs(event[motherindexa].id()); + if (int(std::abs(idmother) / 100.) == 4 || int(std::abs(idmother) / 1000.) == 4 || int(std::abs(idmother) / 100.) == 5 || int(std::abs(idmother) / 1000.) == 5) { + if (rap > mDaughterRapidityMin && rap < mDaughterRapidityMax) { + nbDaughter++; + if (nbDaughter >= mNbDaughter) isGoodAtDaughterLevel = true; + } + } + } + } + } + // we send the trigger + if (isGoodAtPartonLevel && isGoodAtDaughterLevel) { + return true; + } + } + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mQuarkPdg; + float mQuarkRapidityMin; + float mQuarkRapidityMax; + int mPdgDaughter; + int mNbDaughter; + float mDaughterRapidityMin; + float mDaughterRapidityMax; + + Long64_t lGeneratedEvents; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +// Charm-enriched forced decay +FairGenerator* GeneratorPythia8CharmLepton(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8HFLeptonpp("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_cr2_forceddecayscharm.cfg", 4, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + +// Beauty-enriched forced decay +FairGenerator* GeneratorPythia8BeautyForcedDecays(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8HFLeptonpp("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_forceddecayscharmbeauty.cfg", 5, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + +// Beauty-enriched no forced decay +FairGenerator* GeneratorPythia8BeautyNoForcedDecays(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8HFLeptonpp("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar.cfg", 5, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C b/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C new file mode 100644 index 000000000..fe55587aa --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C @@ -0,0 +1,396 @@ +/////////////////////////////////////////////////////////////////////////////// +/// /// +/// HF MC generator for Pb-Pb /// +/// Option 1: generate N PYTHIA events triggered on ccbar and/or bbbar /// +/// to be embedded with a underlying Pb-Pb event /// +/// /// +/////////////////////////////////////////////////////////////////////////////// + +#include "Generator_pythia8_HFLepton_pp.C" + +using namespace Pythia8; + +#include +namespace hf_generators +{ + enum GenType : int { + Charm = 0, // --> GeneratorPythia8CharmLepton: charm enriched + Beauty, // --> GeneratorPythia8BeautyForcedDecays: beauty enriched with forced decays + BeautyNoForcedDecays, // --> GeneratorPythia8BeautyNoForcedDecays: beauty enriched no forced decays + NGenType + }; +} + +class GeneratorPythia8EmbedHFLepton : public o2::eventgen::GeneratorPythia8 +{ +public: + + /// default constructor + GeneratorPythia8EmbedHFLepton() = default; + + /// Destructor + ~GeneratorPythia8EmbedHFLepton() { + // Clean up the internally created HF generator if any + if (mGeneratorEvHFLepton) { + delete mGeneratorEvHFLepton; + mGeneratorEvHFLepton = nullptr; + } + } + + /// Init + bool Init() override + { + return o2::eventgen::GeneratorPythia8::Init(); + } + + /// @brief setup the event generator for HF signals + /// \param gentype generator type (only ccbar, only bbbar, both) + /// \param usePtHardBins flag to enable/disable pt-hard bins + /// \param yQuarkMin minimum quark rapidity + /// \param yQuarkMax maximum quark rapidity + /// \param yHadronMin minimum hadron rapidity + /// \param yHadronMax maximum hadron rapidity + /// \param hadronPdgList list of PDG codes for hadrons to be used in trigger + /// \param quarkPdgList list of PDG codes for quarks to be enriched in the trigger + void setupGeneratorEvHFLepton(int genType, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) { + mGeneratorEvHFLepton = nullptr; + switch (genType) + { + case hf_generators::Charm: + LOG(info) << "********** [GeneratorPythia8EmbedHFLepton] configuring GeneratorPythia8CharmLepton **********"; + LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; + mGeneratorEvHFLepton = dynamic_cast(GeneratorPythia8CharmLepton(inputExternalID, pdgLepton, yMinQ, yMaxQ, yMinL, yMaxL)); + break; + case hf_generators::Beauty: + LOG(info) << "********** [GeneratorPythia8EmbedHFLepton] configuring GeneratorPythia8BeautyForcedDecays **********"; + LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; + mGeneratorEvHFLepton = dynamic_cast(GeneratorPythia8BeautyForcedDecays(inputExternalID, pdgLepton, yMinQ, yMaxQ, yMinL, yMaxL)); + break; + case hf_generators::BeautyNoForcedDecays: + LOG(info) << "********** [GeneratorPythia8EmbedHFLepton] configuring GeneratorPythia8BeautyNoForcedDecays **********"; + LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; + mGeneratorEvHFLepton = dynamic_cast(GeneratorPythia8BeautyNoForcedDecays(inputExternalID, pdgLepton, yMinQ, yMaxQ, yMinL, yMaxL)); + break; + default: + LOG(fatal) << "********** [GeneratorPythia8EmbedHFLepton] bad configuration, fix it! **********"; + break; + } + mGeneratorEvHFLepton->Init(); + } + + // This function is called by the primary generator + // for each event in case we are in embedding mode. + // We use it to setup the number of signal events + // to be generated and to be embedded on the background. + void notifyEmbedding(const o2::dataformats::MCEventHeader* bkgHeader) override + { + LOG(info) << "[notifyEmbedding] ----- Function called"; + + /// Impact parameter between the two nuclei + const float x = bkgHeader->GetB(); + LOG(info) << "[notifyEmbedding] ----- Collision impact parameter: " << x; + + /// number of events to be embedded in a background event + // gen->setFormula("max(1.,120.*(x<5.)+80.*(1.-x/20.)*(x>5.)*(x<11.)+240.*(1.-x/13.)*(x>11.))"); + //mNumSigEvs = static_cast(std::lround(5.0 + 0.886202881 * std::pow(std::max(0.0f, 17.5f - x), 1.7))); + mNumSigEvs = static_cast(std::max(1.,120.*(x<5.)+80.*(1.-x/20.)*(x>5.)*(x<11.)+240.*(1.-x/13.)*(x>11.))); + //mNumSigEvs = 1; + LOG(info) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std::endl; + }; + +protected: + +/// @brief Main function for event generation +bool generateEvent() override +{ + /// Overriding that from GeneratorPythia8, to avoid the simulation of an untriggered event as first + return true; +} + +/// @brief Main function to find out whether the particle comes charm or beauty quark +/// @param partId is the index of the particle under study +/// @param particles are the particles of the full event +bool isFromCharmOrBeauty(const int partId, std::vector const& particles) { + + // Let's check wheter this is already a c or b quark? + const TParticle& part = particles.at(partId); + const int pdgAbs = std::abs(part.GetPdgCode()); + if(pdgAbs == 4 || pdgAbs == 5) { + return true; + } + + // Let's check the mother particles of the hadron at all stages + // and look for the charm or beauty quark + std::vector> arrayIds{}; + std::vector initVec{partId}; + arrayIds.push_back(initVec); // the first vector contains the index of the original particle + int stage = 0; + while(arrayIds[-stage].size() > 0) { + + //LOG(info) << "### stage " << stage << ", arrayIds[-stage].size() = " << arrayIds[-stage].size(); + + std::vector arrayIdsStage{}; + + for (auto& iPart : arrayIds[-stage]) { // check all the particles that were the mothers at the previous stage + const TParticle& partStage = particles.at(iPart); + + // check the first mother + const int firstMotherId = partStage.GetFirstMother(); + if( firstMotherId >= 0) { + const TParticle& firstMother = particles.at(firstMotherId); + const int pdgAbsFirstMother = std::abs(firstMother.GetPdgCode()); + if(pdgAbsFirstMother == 4 || pdgAbsFirstMother == 5) { + return true; + } + // the first mother is not a charm or beauty quark + arrayIdsStage.push_back(firstMotherId); + } + + // let's check all other mothers, if any + const int lastMotherId = partStage.GetSecondMother(); + if(lastMotherId >=0 && lastMotherId != firstMotherId) { + for(int motherId = firstMotherId+1 /*first mother already considered*/; motherId <= lastMotherId; motherId++) { + const TParticle& mother = particles.at(motherId); + const int pdgAbsMother = std::abs(mother.GetPdgCode()); + if(pdgAbsMother == 4 || pdgAbsMother == 5) { + return true; + } + // this mother is not a charm or beauty quark + arrayIdsStage.push_back(motherId); + } + } + + } + + /* + All light-flavour mothers are not considered with this approach + eg: D+ coming from c and uBar --> uBar lost + --> TODO: check if the current particle has a charm or beauty hadron as daughter. If yes, keep it + >>> we can ignore it! This might be useful only for jet analyses, however this approach of embedding N pp events into a Pb-Pb one might be not ideal for them + */ + + // none of the particle mothers is a charm or beauty quark, let's consider their indices for the next stage + arrayIds.push_back(arrayIdsStage); + stage--; // ready to go to next stage + + } /// end while(arrayIds[-stage].size() > 0) + + return false; +} + + +void printParticleVector(std::vector v) { + for(int id=0; id idFirstMother=" << idFirstMother << ", idLastMother=" << idLastMother << ", idFirstDaughter=" << idFirstDaughter << ", idLastDaughter=" << idLastDaughter; + } +} + + +int findKey(const std::map& m, int value) { + for(std::pair p : m) { + if(p.second /*index*/ == value) { + return p.first; // key --> it becomes the new index + } + } + return -1; +} + + +/// @brief Main function to copy the generated particles in mPythia.event into the stack (this.mParticles) +Bool_t importParticles() override +{ + /// Import particles from generated event + /// This should not do anything now, since we override generateEvent + GeneratorPythia8::importParticles(); + + LOG(info) << ""; + LOG(info) << "*************************************************************"; + LOG(info) << "************** New signal event considered **************"; + LOG(info) << "*************************************************************"; + LOG(info) << ""; + + /// Generate mNumSigEvs HF events to be merged in one + int nEvsHF = 0; + while(nEvsHF < mNumSigEvs) { + + /// generate the HF event + bool genOk = false; + while(!genOk) { + genOk = (mGeneratorEvHFLepton->generateEvent() && mGeneratorEvHFLepton->importParticles() /*copy particles from mGeneratorEvHF.mPythia.event to mGeneratorEvHF.mParticles*/ ); + } + + int originalSize = mParticles.size(); // stack of this event generator + + // for debug + // LOG(info) << ""; + // LOG(info) << "============ Before HF event " << nEvsHF; + // LOG(info) << "Full stack (size " << originalSize << "):"; + // printParticleVector(mParticles); + + /// copy the particles from the HF event in the particle stack + auto particlesHfEvent = mGeneratorEvHFLepton->getParticles(); + std::map mapHfParticles = {}; + int counterHfParticles = 0; + + // for debug + // LOG(info) << "-----------------------------------------------"; + // LOG(info) << ">>> HF event " << nEvsHF; + // LOG(info) << " HF event stack:"; + // printParticleVector(particlesHfEvent); + + for(int iPart=0; iPart>>"; + // LOG(info) << " >>> printing mapHfParticles:"; + // for(auto& p : mapHfParticles) { + // const int pdgCodeFromMap = particlesHfEvent.at(p.second).GetPdgCode(); + // LOG(info) << " >>> entry " << p.first << ", original id = " << p.second << ", pdgCode=" << pdgCodeFromMap << " --> firstMotherId=" << particlesHfEvent.at(p.second).GetFirstMother() << ", lastMotherId=" << particlesHfEvent.at(p.second).GetSecondMother() << ", firstDaughterId=" << particlesHfEvent.at(p.second).GetFirstDaughter() << ", lastDaughterId=" << particlesHfEvent.at(p.second).GetLastDaughter(); + // } + + + // In the map we have only the particles from charm or beauty + // Let's readapt the mother/daughter indices accordingly + int offset = originalSize; + for(int iHfPart=0; iHfPart= 0) { + idFirstMother = findKey(mapHfParticles, idFirstMother); + /// If idFirstMother>=0, the 1st mother is from charm or beauty, i.e. is not a light-flavoured parton + /// Instead, if idFirstMother==-1 from findKey this means that the first mother was a light-flavoured parton --> not stored in the map + if(idFirstMother >=0) { + /// the 1st mother is from charm or beauty, i.e. is not a light-flavoured parton + if(idLastMother != idFirstMotherOrig) { + if(idLastMother != -1) { + /// idLastMother is >= 0 + } + } else { + /// idLastMother is equal to idFirstMother + idLastMother = idFirstMother; + } + isFirstMotherOk = true; + } + } + if(!isFirstMotherOk) { + /// - If we are here, it means that the 1st mother was not from charm or beauty + /// - No need to check whether idLastMother>=0, + /// because this would mean that none of the mother is from charm or beauty and this was checked already in isFromCharmOrBeauty + /// - Need to loop between 1st and last mother, to treat cases like these + /// [11:52:13][INFO] id = 565, pdgCode = -2 --> idFirstMother=519, idLastMother=519 + /// [11:52:13][INFO] id = 566, pdgCode = -4 --> idFirstMother=520, idLastMother=520 + /// [11:52:13][INFO] id = 567, pdgCode = -1 --> idFirstMother=518, idLastMother=518 + /// [11:52:13][INFO] id = 568, pdgCode = -311 --> idFirstMother=565, idLastMother=567 + /// [11:52:13][INFO] id = 569, pdgCode = -4212 --> idFirstMother=565, idLastMother=567 + /// --> w/o loop between 1st and last mother, the mother Ids assigned to this Sc+ (4212) by findKey are -1, both first and last + bool foundAnyMother = false; + for(int idMotherOrig=(idFirstMotherOrig+1); idMotherOrig<=idLastMother; idMotherOrig++) { + const int idMother = findKey(mapHfParticles, idMotherOrig); + if(idMother >= 0) { + /// this should mean that the mother is from HF, i.e. that we found the correct one + idFirstMother = idMother; + idLastMother = idFirstMother; + foundAnyMother = true; + break; + } + } + // set last mother to -1 if no mother has been found so far + if (!foundAnyMother) { + idLastMother = -1; + } + } + + /// fix daughter indices + idFirstDaughter = findKey(mapHfParticles, idFirstDaughter); + idLastDaughter = findKey(mapHfParticles, idLastDaughter); + + /// adjust the particle mother and daughter indices + particle.SetFirstMother((idFirstMother >= 0) ? idFirstMother + offset : idFirstMother); + particle.SetLastMother((idLastMother >= 0) ? idLastMother + offset : idLastMother); + particle.SetFirstDaughter((idFirstDaughter >= 0) ? idFirstDaughter + offset : idFirstDaughter); + particle.SetLastDaughter((idLastDaughter >= 0) ? idLastDaughter + offset : idLastDaughter); + + /// copy inside this.mParticles from mGeneratorEvHF.mParticles, i.e. the particles generated in mGeneratorEvHF + mParticles.push_back(particle); + + } + + // for debug + // LOG(info) << "-----------------------------------------------"; + // LOG(info) << "============ After HF event " << nEvsHF; + // LOG(info) << "Full stack:"; + // printParticleVector(mParticles); + + /// one more event generated, let's update the counter and clear it, to allow the next generation + nEvsHF++; + //mGeneratedEvents++; + mGeneratorEvHFLepton->clearParticles(); + } + + return true; +} + +private: + + Generator* mGeneratorEvHFLepton; // to generate HF signal events + + int mNumSigEvs{1}; // number of HF signal events to be merged in one Pythia event + //unsigned long long mGeneratedEvents; + +}; + +// Charm enriched +FairGenerator * GeneratorPythia8EmbedHFLeptonCharm(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8EmbedHFLepton(); + + /// setup the internal generator for HF events + myGen->setupGeneratorEvHFLepton(hf_generators::Charm, inputExternalID, pdgLepton, yMinQ = -1.5, yMaxQ = 1.5, yMinL = -1, yMaxL = 1); + + return myGen; +} + +// Beauty enriched +FairGenerator * GeneratorPythia8EmbedHFLeptonBeauty(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8EmbedHFLepton(); + + /// setup the internal generator for HF events + myGen->setupGeneratorEvHFLepton(hf_generators::Beauty, inputExternalID, pdgLepton, yMinQ = -1.5, yMaxQ = 1.5, yMinL = -1, yMaxL = 1); + + return myGen; +} + +// Charm and beauty enriched (with same ratio) +FairGenerator * GeneratorPythia8EmbedHFLeptonBeautyNoForcedDecays(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8EmbedHFLepton(); + + /// setup the internal generator for HF events + myGen->setupGeneratorEvHFLepton(hf_generators::BeautyNoForcedDecays, inputExternalID, pdgLepton, yMinQ = -1.5, yMaxQ = 1.5, yMinL = -1, yMaxL = 1); + + return myGen; +} diff --git a/MC/config/PWGEM/ini/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini b/MC/config/PWGEM/ini/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini new file mode 100644 index 000000000..f24c66d3e --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C +funcName=GeneratorPythia8EmbedHFLeptonBeautyNoForcedDecays(3, 11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent=true diff --git a/MC/config/PWGEM/ini/GeneratorHF_Charm_PbPb_electron.ini b/MC/config/PWGEM/ini/GeneratorHF_Charm_PbPb_electron.ini new file mode 100644 index 000000000..b72cfb523 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHF_Charm_PbPb_electron.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C +funcName=GeneratorPythia8EmbedHFLeptonCharm(1, 11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent=true diff --git a/MC/config/PWGEM/ini/tests/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.C new file mode 100644 index 000000000..375e79b75 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.C @@ -0,0 +1,111 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance != nEvents) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHF_Charm_PbPb_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHF_Charm_PbPb_electron.C new file mode 100644 index 000000000..d55c16c11 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHF_Charm_PbPb_electron.C @@ -0,0 +1,116 @@ +int External() +{ + + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance != nEvents) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/run/PWGEM/runHFToDielectrons_PbPb.sh b/MC/run/PWGEM/runHFToDielectrons_PbPb.sh new file mode 100644 index 000000000..4193f6751 --- /dev/null +++ b/MC/run/PWGEM/runHFToDielectrons_PbPb.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +RNDSEED=${RNDSEED:-0} +NWORKERS=${NWORKERS:-8} + + +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_CPULIMIT=20 +export ALIEN_JDL_LPMANCHORPASSNAME=apass4 +export ALIEN_JDL_MCANCHOR=apass4 +export ALIEN_JDL_COLLISIONSYSTEM=PbPb +export ALIEN_JDL_LPMPASSNAME=apass4 +export ALIEN_JDL_LPMRUNNUMBER=544474 +export ALIEN_JDL_LPMANCHORRUN=544474 + +export ALIEN_JDL_LPMINTERACTIONTYPE=PbPb +export ALIEN_JDL_LPMPRODUCTIONTAG="TestProd17032026" +export ALIEN_JDL_LPMANCHORPRODUCTION="LHC26ac" +export ALIEN_JDL_LPMANCHORYEAR=2023 + +export ALIEN_JDL_O2DPGWORKFLOWTARGET="aod" + +export PRODSPLIT=${ALIEN_O2DPG_GRIDSUBMIT_PRODSPLIT:-10} +export SPLITID=${ALIEN_O2DPG_GRIDSUBMIT_SUBJOBID:-10} +export CYCLE=0 +export NTIMEFRAMES=8 +export NSIGEVENTS=20 +export NBKGEVENTS=10 + +# define the generator via ini file +# use 20/80 sampling for different generators +# generate random number +RNDSIG=$(($RANDOM % 100)) + + +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 20 ]]; +then + CONFIGNAME="GeneratorHF_Charm_PbPb_electron.ini" +elif [[ $RNDSIG -ge 20 && $RNDSIG -lt 100 ]]; +then + CONFIGNAME="GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini" +fi + + +# generator and other sim configuration; parallel world for ITS +SIM_OPTIONS="-eCM 5360 -gen external -j ${NWORKERS} -tf ${NTIMEFRAMES} -e TGeant4 -seed 0 -ini ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/ini/$CONFIGNAME -genBkg pythia8 -procBkg \"heavy_ion\" -colBkg PbPb --embedding -nb $NBKGEVENTS" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="${SIM_OPTIONS}" + +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh + From 4eee7fb6bfe8a9fced3e71a3f73b7c18fbf7b9de Mon Sep 17 00:00:00 2001 From: Sebastian Scheid Date: Sun, 22 Mar 2026 17:57:31 +0100 Subject: [PATCH 280/362] PWGEM: Use default Pythia settings for OO HFee generator (#2305) --- ...nerator_pythia8_GapTriggered_HFLepton_OO.C | 15 +-- .../generator/pythia8_OO_536_bbbar.cfg | 22 ++++ .../generator/pythia8_OO_536_ccbar.cfg | 45 ++++++++ ...8_bbbar_OO_536_forceddecayscharmbeauty.cfg | 101 ++++++++++++++++++ 4 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C index 55a23a437..439d7e3ce 100644 --- a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C @@ -46,14 +46,6 @@ public: pythiaObjectSignal.readFile(pathconfigSignal.Data()); pythiaObjectSignal.readString("Random:setSeed on"); pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); - pythiaObjectSignal.readString("Beams:idA = 1000080160"); - pythiaObjectSignal.readString("Beams:idB = 1000080160"); - pythiaObjectSignal.readString("Beams:eCM = 5360.0"); - pythiaObjectSignal.readString("Beams:frameType = 1"); - pythiaObjectSignal.readString("ParticleDecays:limitTau0 = on"); - pythiaObjectSignal.readString("ParticleDecays:tau0Max = 10."); - pythiaObjectSignal.readString("HeavyIon:SigFitNGen = 0"); - pythiaObjectSignal.readString("HeavyIon:SigFitDefPar = 2.15,18.42,0.33"); pythiaObjectSignal.init(); cout << "Initalization of signal event is complete" << endl; @@ -197,7 +189,7 @@ private: // Charm-enriched forced decay FairGenerator* GeneratorPythia8GapTriggeredCharmLepton(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) { - auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_cr2_forceddecayscharm.cfg", 4, inputTriggerRatio, inputExternalID); + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg", 4, inputTriggerRatio, inputExternalID); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->readString("Random:setSeed on"); myGen->readString("Random:seed " + std::to_string(seed)); @@ -207,10 +199,11 @@ FairGenerator* GeneratorPythia8GapTriggeredCharmLepton(int inputTriggerRatio, in return myGen; } + // Beauty-enriched forced decay FairGenerator* GeneratorPythia8GapTriggeredBeautyForcedDecays(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) { - auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_forceddecayscharmbeauty.cfg", 5, inputTriggerRatio, inputExternalID); + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg", 5, inputTriggerRatio, inputExternalID); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->readString("Random:setSeed on"); myGen->readString("Random:seed " + std::to_string(seed)); @@ -223,7 +216,7 @@ FairGenerator* GeneratorPythia8GapTriggeredBeautyForcedDecays(int inputTriggerRa // Beauty-enriched no forced decay FairGenerator* GeneratorPythia8GapTriggeredBeautyNoForcedDecays(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) { - auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar.cfg", 5, inputTriggerRatio, inputExternalID); + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg", 5, inputTriggerRatio, inputExternalID); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->readString("Random:setSeed on"); myGen->readString("Random:seed " + std::to_string(seed)); diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg new file mode 100644 index 000000000..47d52bfbd --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg @@ -0,0 +1,22 @@ +### beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 +Beams:frameType = 1 + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 +### processes +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg new file mode 100644 index 000000000..07d252517 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg @@ -0,0 +1,45 @@ +### beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 +Beams:frameType = 1 + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +### processes +# HardQCD:hardccbar on # ccbar production +SoftQCD:inelastic = on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + + +### only semileptonic decays +### D+ +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +### Ds +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg new file mode 100644 index 000000000..4305eb7dc --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg @@ -0,0 +1,101 @@ +### beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 +Beams:frameType = 1 + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 +### processes +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 + +### only semileptonic decays for charm +### D+ +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +421:addChannel = 1 0.014 0 -311 -211 -11 12 +### Ds +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +### only semileptonic decays for beauty +### B0 +511:oneChannel = 1 0.0207000 0 12 -11 -411 +511:addChannel = 1 0.0570000 0 12 -11 -413 +511:addChannel = 1 0.0023000 0 12 -11 -415 +511:addChannel = 1 0.0001330 0 12 -11 -211 +511:addChannel = 1 0.0002690 0 12 -11 -213 +511:addChannel = 1 0.0045000 0 12 -11 -10411 +511:addChannel = 1 0.0052000 0 12 -11 -10413 +511:addChannel = 1 0.0083000 0 12 -11 -20413 + +### B+ +521:oneChannel = 1 0.0000720 0 12 -11 111 +521:addChannel = 1 0.0001450 0 12 -11 113 +521:addChannel = 1 0.0000840 0 12 -11 221 +521:addChannel = 1 0.0001450 0 12 -11 223 +521:addChannel = 1 0.0000840 0 12 -11 331 +521:addChannel = 1 0.0224000 0 12 -11 -421 +521:addChannel = 1 0.0617000 0 12 -11 -423 +521:addChannel = 1 0.0030000 0 12 -11 -425 +521:addChannel = 1 0.0049000 0 12 -11 -10421 +521:addChannel = 1 0.0056000 0 12 -11 -10423 +521:addChannel = 1 0.0090000 0 12 -11 -20423 + +### Bs +531:oneChannel = 1 0.0002000 0 12 -11 -321 +531:addChannel = 1 0.0003000 0 12 -11 -323 +531:addChannel = 1 0.0210000 0 12 -11 -431 +531:addChannel = 1 0.0490000 0 12 -11 -433 +531:addChannel = 1 0.0070000 0 12 -11 -435 +531:addChannel = 1 0.0003000 0 12 -11 -10323 +531:addChannel = 1 0.0040000 0 12 -11 -10431 +531:addChannel = 1 0.0070000 0 12 -11 -10433 +531:addChannel = 1 0.0002000 0 12 -11 -20323 +531:addChannel = 1 0.0040000 0 12 -11 -20433 + +### Lambdab +5122:oneChannel = 1 0.0546000 0 -12 11 4122 +5122:addChannel = 1 0.0096000 0 -12 11 4124 +5122:addChannel = 1 0.0128000 0 -12 11 14122 + +### Chi_{b}^{-} +5132:oneChannel = 1 0.1080010 0 -12 11 4 3101 +5132:addChannel = 1 0.0020000 0 -12 11 2 3101 +### Chi_{b}^{0} +5232:oneChannel = 1 0.1080010 0 -12 11 4 3201 +5232:addChannel = 1 0.0020000 0 -12 11 2 3201 +### Omega_{b}^{-} +5332:oneChannel = 1 0.1080010 1 -12 11 4 3303 +5332:oneChannel = 1 0.0020000 1 -12 11 2 3303 + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 From 22cd82f25c42087966716dbe1f5d8fe3d1abeb56 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 24 Mar 2026 09:25:39 +0100 Subject: [PATCH 281/362] qc-workflow.sh: add CTP raw data QC in EPNSYNCMODE --- DATA/production/qc-workflow.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/DATA/production/qc-workflow.sh b/DATA/production/qc-workflow.sh index 6d152921f..6ce392301 100755 --- a/DATA/production/qc-workflow.sh +++ b/DATA/production/qc-workflow.sh @@ -117,6 +117,7 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then [[ -z "${QC_JSON_CPV:-}" ]] && QC_JSON_CPV=apricot://o2/components/qc/ANY/any/cpv-physics-qcmn-epn [[ -z "${QC_JSON_TRD:-}" ]] && QC_JSON_TRD=apricot://o2/components/qc/ANY/any/trd-full-qcmn [[ -z "${QC_JSON_PHS:-}" ]] && QC_JSON_PHS=apricot://o2/components/qc/ANY/any/phos-raw-clusters-epn + [[ -z "${QC_JSON_CTP:-}" ]] && QC_JSON_CTP=apricot://o2/components/qc/ANY/any/ctp-raw-qc-epn [[ -z "${QC_JSON_GLO_PRIMVTX:-}" ]] && QC_JSON_GLO_PRIMVTX=apricot://o2/components/qc/ANY/any/glo-vtx-qcmn-epn [[ -z "${QC_JSON_GLO_ITSTPC:-}" ]] && QC_JSON_GLO_ITSTPC=apricot://o2/components/qc/ANY/any/glo-itstpc-mtch-qcmn-epn if [[ -z "${QC_JSON_TOF_MATCH:-}" ]]; then From 8d9bcc2133e4c3abecb72fd8c829338572cbd576 Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Tue, 24 Mar 2026 09:47:38 +0100 Subject: [PATCH 282/362] Honor detector inclusion list for FT0,FV0,EMC,CTP --- MC/bin/o2dpg_sim_workflow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 97f3195b8..ecd00867a 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -302,6 +302,9 @@ def load_external_config(configfile): activeDetectors = { det:1 for det in activeDetectors.split(',') if det not in args.skipModules and det not in args.skipReadout} for det in activeDetectors: activate_detector(det) +for det in args.skipModules: + print(f"Skipping detector {det} in simulation") + deactivate_detector(det) # function to finalize detector source lists based on activeDetectors # detector source lists are comma separated lists of DET1, DET2, DET1-DET2, ... @@ -1227,7 +1230,7 @@ def createRestDigiTask(name, det='ALLSMALLER'): getDPL_global_options(), f'-n {args.ns}', simsoption, - '--onlyDet FT0,FV0,EMC,CTP', + '--onlyDet ' + ','.join([det for det in ['FT0', 'FV0', 'EMC', 'CTP'] if isActive(det)]), f'--interactionRate {INTRATE}', f'--incontext {CONTEXTFILE}', f'--store-ctp-lumi {CTPSCALER}', From c89a05315c8d0ef495a3210979f3d40693888d71 Mon Sep 17 00:00:00 2001 From: sejeong8 Date: Fri, 27 Mar 2026 00:44:16 +0900 Subject: [PATCH 283/362] new ini, test for enhanced HFe MC for pp ref energy (#2310) --- ...F_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini | 9 ++ ...rHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C | 128 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini new file mode 100644 index 000000000..202b484b5 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.0, 1.0, {11}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C new file mode 100644 index 000000000..fb9df800e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C @@ -0,0 +1,128 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgDecayElectron = 11; + int checkPdgQuarkOne = 4; + int checkPdgQuarkTwo = 5; + float ratioTrigger = 1. / 5; // one event triggered out of 5 + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}; + int nElectrons{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } // if event header + + int nelectronsev = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayElectron) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4 || + int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nElectrons++; + nelectronsev++; + } // gmpdg + } // pdgdecay + } // loop track + // std::cout << "#electrons per event: " << nelectronsev << "\n"; + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) + << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) + << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne + << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo + << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne + << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo + << " different than expected\n"; + return 1; + } + if (nQuarksOne < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne + << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo + << " lower than expected\n"; + return 1; + } + std::cout << "#electrons: " << nElectrons << "\n"; + + return 0; +} // external From 2fc42f71f0400d4485e06ef1902ab4d8bc221c97 Mon Sep 17 00:00:00 2001 From: MRazza <118839113+MRazza879@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:19:55 +0200 Subject: [PATCH 284/362] Update probQQtoQ and BeamRemnants settings in config (#2312) --- .../PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg index 58acb17c4..dd7df4cd9 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg @@ -28,13 +28,15 @@ ColourReconnection:timeDilationPar 0.18 StringPT:sigma 0.335 StringZ:aLund 0.36 StringZ:bLund 0.56 -#StringFlav:probQQtoQ 0.078 -StringFlav:probQQtoQ 0.17 +StringFlav:probQQtoQ 0.078 StringFlav:ProbStoUD 0.2 StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 MultiPartonInteractions:pT0Ref 2.15 BeamRemnants:remnantMode 1 BeamRemnants:saturation 5 +BeamRemnants:allowBeamJunction = off +BeamRemnants:beamJunction = off +ColourReconnection:allowDiquarkJunctionCR = off # Correct decay lengths (wrong in PYTHIA8 decay table) # Lb From b7d1025283459c8108c684ab626c51f83c611cd8 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 1 Apr 2026 16:27:37 +0200 Subject: [PATCH 285/362] Use renamed TPC inputype for skimming --- .../configurations/CTFSkimming/ctf-skim-workflow.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh b/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh index fbf38cbda..8ede2eff4 100755 --- a/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh +++ b/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh @@ -89,7 +89,7 @@ done if [[ -z ${IRFRAMES:-} ]] || [[ -z ${CTFLIST:-} ]] ; then echo "Format: ${0##*/} -f -c " - exit 1 + exit 1 fi [[ "0${ALLOW_MISSING_DET:-}" == "00" ]] && ALLOW_MISSING_DET= || ALLOW_MISSING_DET="--allow-missing-detectors" @@ -107,12 +107,12 @@ add_W o2-ctf-reader-workflow "--ctf-data-subspec 1 --ir-frames-files $IRFRAMES $ if [[ -z ${NO_ITSMFT_MASKING:-} ]] ; then has_detector_ctf ITS && add_W o2-its-reco-workflow "--digits-from-upstream --disable-mc --disable-tracking --disable-root-output --pipeline $(get_N its-tracker ITS REST 1 ITSTRK)" "ITSClustererParam.maxBCDiffToMaskBias=10;" - has_detector_ctf MFT && add_W o2-mft-reco-workflow "--digits-from-upstream --disable-mc --disable-tracking --disable-root-output --pipeline $(get_N mft-tracker MFT REST 1 MFTTRK)" "MFTClustererParam.maxBCDiffToMaskBias=10;" + has_detector_ctf MFT && add_W o2-mft-reco-workflow "--digits-from-upstream --disable-mc --disable-tracking --disable-root-output --pipeline $(get_N mft-tracker MFT REST 1 MFTTRK)" "MFTClustererParam.maxBCDiffToMaskBias=10;" fi has_detector_ctf ITS && add_W o2-itsmft-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${ITS_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${ITS_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${ITS_ENC_MEMFACT:-1.5} --pipeline $(get_N its-entropy-encoder ITS CTF 1)" has_detector_ctf MFT && add_W o2-itsmft-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${MFT_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${MFT_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${MFT_ENC_MEMFACT:-1.5} --runmft true --pipeline $(get_N mft-entropy-encoder MFT CTF 1)" -has_detector_ctf TPC && add_W o2-tpc-reco-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TPC_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TPC_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TPC_ENC_MEMFACT:-1.} --input-type compressed-clusters-flat --output-type encoded-clusters,disable-writer --pipeline $(get_N tpc-entropy-encoder TPC CTF 1 TPCENT)" +has_detector_ctf TPC && add_W o2-tpc-reco-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TPC_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TPC_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TPC_ENC_MEMFACT:-1.} --input-type compressed-clusters-flat-for-encode --output-type encoded-clusters,disable-writer --pipeline $(get_N tpc-entropy-encoder TPC CTF 1 TPCENT)" has_detector_ctf TRD && add_W o2-trd-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TRD_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TRD_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TRD_ENC_MEMFACT:-1.5} --pipeline $(get_N trd-entropy-encoder TRD CTF 1 TRDENT)" has_detector_ctf TOF && add_W o2-tof-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TOF_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TOF_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TOF_ENC_MEMFACT:-1.5} --pipeline $(get_N tof-entropy-encoder TOF CTF 1)" has_detector_ctf FT0 && add_W o2-ft0-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${FT0_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${FT0_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${FT0_ENC_MEMFACT:-1.5} --pipeline $(get_N ft0-entropy-encoder FT0 CTF 1)" From a509bd7b27ab83fe46c31cc67a9b6480b56d7959 Mon Sep 17 00:00:00 2001 From: Nasir Mehdi Malik <89008506+nasirmehdimalik@users.noreply.github.com> Date: Sat, 4 Apr 2026 21:36:49 +0530 Subject: [PATCH 286/362] [PWGLF] Added configuration for baryonic resonances efficiency studies for Light ION (#2311) * retest * Remove NeNe file with external genertaor failed --- ...atorLF_ResonancesBaryonic_OO_injection.ini | 10 ++ ...atorLF_ResonancesBaryonic_pO_injection.ini | 10 ++ ...LF_ResonancesBaryonic_pp5360_injection.ini | 10 ++ ...eratorLF_ResonancesBaryonic_OO_injection.C | 142 ++++++++++++++++++ ...eratorLF_ResonancesBaryonic_pO_injection.C | 142 ++++++++++++++++++ ...orLF_ResonancesBaryonic_pp5360_injection.C | 142 ++++++++++++++++++ 6 files changed, 456 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_OO_injection.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pO_injection.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_OO_injection.C create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pO_injection.C create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp5360_injection.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_OO_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_OO_injection.ini new file mode 100644 index 000000000..ac4000cba --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_OO_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pO_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pO_injection.ini new file mode 100644 index 000000000..b85a88051 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pO_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini new file mode 100644 index 000000000..18acc657e --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_OO_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_OO_injection.C new file mode 100644 index 000000000..a47ce77ea --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_OO_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_ResonancesBaryonic_OO_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pO_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pO_injection.C new file mode 100644 index 000000000..38d05d522 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pO_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_ResonancesBaryonic_pO_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp5360_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp5360_injection.C new file mode 100644 index 000000000..f73f13c3d --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp5360_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_ResonancesBaryonic_pp5360_injection() { External(); } From e633fcf459ba933643426207a2fea7916acf5364 Mon Sep 17 00:00:00 2001 From: sawan <124118453+sawankumawat@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:03:38 +0530 Subject: [PATCH 287/362] Enabled injection scheme with uniform rapidity and pT (#2315) --- ...LF_ResonancesBaryonic_pp5360_injection.ini | 2 +- .../ini/GeneratorLF_Resonances_pp_exotic.ini | 2 +- ...neratorLF_Resonances_pp_exoticAll_gap2.ini | 2 +- .../tests/GeneratorLF_Resonances_pp_exotic.C | 35 ++-------- .../PWGLF/pythia8/generator/gluelistgun.json | 70 ++++++++++++------- 5 files changed, 56 insertions(+), 55 deletions(-) diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini index 18acc657e..779dfcf51 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg", "") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg", "") [GeneratorPythia8] # if triggered then this will be used as the background event config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini index ced172b4d..e520191e7 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") [GeneratorPythia8] # if triggered then this will be used as the background event config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini index add3bb81e..e55c3195c 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C -funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 2, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") [GeneratorPythia8] # this will be used as the background event config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C index 6fe8638d7..5155fbebc 100644 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C @@ -6,41 +6,20 @@ int External() int numberOfEventsProcessed{0}; int numberOfEventsProcessedWithoutInjection{0}; std::vector injectedPDGs = { - 9010221, // f_0(980) 225, // f_2(1270) 115, // a_2(1320) 10221, // f_0(1370) 9030221, // f_0(1500) 335, // f_2(1525) - 10331, // f_0(1710) - 20223, // f_1(1285) - 20333, // f_1(1420) - 335, // f_2(1525) - 10323, // K1(1270)+ - -10323, // K1(1270)-bar - 123314, // Xi(1820)- - -123314, // Xi(1820)+ - 123324, // Xi(1820)0 - -123324 // Xi(1820)0bar + 10331 // f_0(1710) }; std::vector> decayDaughters = { - {211, -211}, // f_0(980) - {310, 310}, // f_2(1270) - {310, 310}, // a_2(1320) - {310, 310}, // f_0(1370) - {310, 310}, // f_0(1500) - {310, 310}, // f_2(1525) - {310, 310}, // f_0(1710) - {310, -321, 211}, // f_1(1285) - {310, -321, 211}, // f_1(1420) - {310, 310}, // f_2(1525) - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {3122, -311}, // Xi(1820)- - {3122, 311}, // Xi(1820)+ - {3122, 310}, // Xi(1820)0 - {-3122, 310} // Xi(1820)0bar + {310, 310}, // f_2(1270) + {310, 310}, // a_2(1320) + {310, 310}, // f_0(1370) + {310, 310}, // f_0(1500) + {310, 310}, // f_2(1525) + {310, 310} // f_0(1710) }; auto nInjection = injectedPDGs.size(); diff --git a/MC/config/PWGLF/pythia8/generator/gluelistgun.json b/MC/config/PWGLF/pythia8/generator/gluelistgun.json index c261c5608..00683e335 100644 --- a/MC/config/PWGLF/pythia8/generator/gluelistgun.json +++ b/MC/config/PWGLF/pythia8/generator/gluelistgun.json @@ -1,46 +1,68 @@ { "f_2(1270)": { "pdg": 225, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1370)": { + "pdg": 10221, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1500)": { + "pdg": 9030221, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_0(1710)": { "pdg": 10331, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "f_2(1525)": { "pdg": 335, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true }, "a_2(1230)": { "pdg": 115, - "n": 1, + "n": 3, "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "rapidityMin": -1.2, - "rapidityMax": 1.2, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, "genDecayed": true } } \ No newline at end of file From 30358fa567075de8c46555243dde99bb22ff40de Mon Sep 17 00:00:00 2001 From: Chuntai <48704924+wuctlby@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:40:42 +0200 Subject: [PATCH 288/362] Config files for the charm baryon in ppref (#2316) --- .../decayer/force_hadronic_charmbaryon.cfg | 82 +++++++++++++++++++ .../geant4_externaldecayer_charmbaryon.in | 68 +++++++++++++++ .../pythia8/generator/pythia8_inel_536.cfg | 11 +++ 3 files changed, 161 insertions(+) create mode 100644 MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg create mode 100644 MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_charmbaryon.in create mode 100644 MC/config/common/pythia8/generator/pythia8_inel_536.cfg diff --git a/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg b/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg new file mode 100644 index 000000000..65af76403 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg @@ -0,0 +1,82 @@ +# Decay configuration taken from MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_pp_ref.cfg +Init:showChangedParticleData = on +4332:tau0 = 0.0803 # OmegaC +4132:tau0 = 0.0455 # Xic0 + +# switch off all decay channels +4232:onMode = off +4332:onMode = off +4132:onMode = off + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma+ π+ π- (10%) +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +## Xic0 decays +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 ### Xi_c()0 --> Xi- pi+ 0.01432524810113947 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 +# Matching Exclusive Decay Channels: +# ------------------------------------------------------- +# Xi_c()0 --> Xi- pi+ 0.01432524810113947 +# -> PDG Codes: 3312, 211 +# Xi_c()0 --> Xi- pi+ pi+ pi- 0.04775082700379833 +# -> PDG Codes: 3312, 211, 211, -211 + +## OmegaC decays +### add custom OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +# Matching Exclusive Decay Channels: +# ------------------------------------------------------- +# Omega_c()0 --> Omega- pi+ None +# -> PDG Codes: 3334, 211 +# Omega_c()0 --> Omega- pi+ pi0 1.79939678284182 +# -> PDG Codes: 3334, 211, 111 +# Omega_c()0 --> Omega- pi- 2 pi+ 0.30954954954955 +# -> PDG Codes: 3334, -211, [2], 211 + +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 +# Matching Exclusive Decay Channels: +# ------------------------------------------------------- +# Omega_c()0 --> Xi- Kbar0 pi+ 2.12 +# -> PDG Codes: 3312, -311, 211 +# Omega_c()0 --> Xi- K- 2 pi+ 0.625932203389831 +# -> PDG Codes: 3312, -321, [2], 211 + +## Allow the decay of resonances in the decay chain +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 diff --git a/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_charmbaryon.in b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_charmbaryon.in new file mode 100644 index 000000000..46b4def18 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_charmbaryon.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection omega_c0 anti_omega_c0 xi_c0 anti_xi_c0 xi_c+ xi_c- diff --git a/MC/config/common/pythia8/generator/pythia8_inel_536.cfg b/MC/config/common/pythia8/generator/pythia8_inel_536.cfg new file mode 100644 index 000000000..d1fb9b68a --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_inel_536.cfg @@ -0,0 +1,11 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360.0 # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. From afdcafc71e022b97f076fb23f219424a2efba24b Mon Sep 17 00:00:00 2001 From: Chuntai <48704924+wuctlby@users.noreply.github.com> Date: Tue, 14 Apr 2026 10:23:09 +0200 Subject: [PATCH 289/362] update missing decay channels of resonances (#2320) --- .../PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg b/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg index 65af76403..9e5e79e45 100644 --- a/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg +++ b/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg @@ -73,6 +73,12 @@ Init:showChangedParticleData = on # -> PDG Codes: 3312, -321, [2], 211 ## Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 ### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p ### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p 3312:onMode = off From 458ff61bd2c4c6f5730f752fac15f4e8781ba2ab Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:50:45 +0200 Subject: [PATCH 290/362] add generator for NeNe based on EPOS4 (#2322) --- .../examples/ini/GeneratorEPOS4NeNe536TeV.ini | 12 +++ .../ini/tests/GeneratorEPOS4NeNe536TeV.C | 78 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini create mode 100644 MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C diff --git a/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini new file mode 100644 index 000000000..3dc0901ad --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 10 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C new file mode 100644 index 000000000..994e64c42 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C @@ -0,0 +1,78 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + // Check if there is 1 event, as customarily set in the ini file + // Heavy-ion collisions with hydro and hadronic cascade are very slow to simulate + if (nEvents != 10) + { + std::cerr << "Expected 10 events, got " << nEvents << "\n"; + return 1; + } + + // ---- Neon-Neon parameters ---- + constexpr int kNeonPDG = 1000100200; // Ne-20 ion + constexpr double kEnucleon = 5360.; // GeV per nucleon + constexpr int kA = 20; // Neon mass number + constexpr double kNeonEnergy = kA * kEnucleon / 2.0; // beam energy in GeV + + // Check if each event has two neon ions at expected energy + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int count = 0; + + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + + // 50 MeV tolerance (floating point safety) + if (std::abs(energy - kNeonEnergy) < 5e-2 && + track.GetPdgCode() == kNeonPDG) + { + count++; + } + } + + if (count < 2) + { + std::cerr << "Event " << i + << " has less than 2 neon ions at " + << kNeonEnergy << " GeV\n"; + return 1; + } + } + + return 0; +} From 556f5602478c3ffa8286368e04006a43e3aedf81 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 16 Apr 2026 16:58:27 +0200 Subject: [PATCH 291/362] ITS: propagate settings to wfx (#2323) * ITS: propagate settings to wfx Signed-off-by: Felix Schlepper * ITS: remove duplicated setting already present in dpl-workflow.sh Signed-off-by: Felix Schlepper --------- Signed-off-by: Felix Schlepper --- .../configurations/asyncReco/setenv_extra.sh | 13 ++++++++----- MC/bin/o2dpg_sim_config.py | 16 +++++++++++++--- MC/bin/o2dpg_sim_workflow.py | 1 - 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 2d8a8dffd..329e9e9dc 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -558,18 +558,21 @@ export ITSEXTRAERR="ITSCATrackerParam.sysErrY2[0]=$ERRIB;ITSCATrackerParam.sysEr # ad-hoc options for ITS reco workflow EXTRA_ITSRECO_CONFIG= if [[ $BEAMTYPE == "PbPb" ]]; then - EXTRA_ITSRECO_CONFIG="ITSCATrackerParam.deltaRof=0;ITSVertexerParam.clusterContributorsCut=16;ITSVertexerParam.lowMultBeamDistCut=0;ITSCATrackerParam.nROFsPerIterations=12;ITSCATrackerParam.perPrimaryVertexProcessing=false;ITSCATrackerParam.fataliseUponFailure=false;ITSCATrackerParam.dropTFUponFailure=true;ITSCATrackerParam.maxMemory=21474836480;" + # tracker memory + EXTRA_ITSRECO_CONFIG=";ITSCATrackerParam.perPrimaryVertexProcessing=false;ITSCATrackerParam.fataliseUponFailure=false;ITSCATrackerParam.dropTFUponFailure=true;ITSCATrackerParam.maxMemory=21474836480;" if [[ -z "$ALIEN_JDL_DISABLE_UPC" || $ALIEN_JDL_DISABLE_UPC != 1 ]]; then EXTRA_ITSRECO_CONFIG+=";ITSVertexerParam.nIterations=2;ITSCATrackerParam.doUPCIteration=true;" fi if [[ $LOWFIELD == "1" ]]; then - EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPt=2.5;" + EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPt=2.5;" # disables B-field scaling fi elif [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then - EXTRA_ITSRECO_CONFIG="ITSVertexerParam.phiCut=0.5;ITSVertexerParam.clusterContributorsCut=3;ITSVertexerParam.tanLambdaCut=0.2;" - EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.startLayerMask[0]=127;ITSCATrackerParam.startLayerMask[1]=127;ITSCATrackerParam.startLayerMask[2]=127;" + # allowed start layers + EXTRA_ITSRECO_CONFIG=";ITSCATrackerParam.startLayerMask[0]=127;ITSCATrackerParam.startLayerMask[1]=127;ITSCATrackerParam.startLayerMask[2]=127;" + # low pt-cutoffs EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPtIterLgt[0]=0.05;ITSCATrackerParam.minPtIterLgt[1]=0.05;ITSCATrackerParam.minPtIterLgt[2]=0.05;ITSCATrackerParam.minPtIterLgt[3]=0.05;ITSCATrackerParam.minPtIterLgt[4]=0.05;ITSCATrackerParam.minPtIterLgt[5]=0.05;ITSCATrackerParam.minPtIterLgt[6]=0.05;ITSCATrackerParam.minPtIterLgt[7]=0.05;ITSCATrackerParam.minPtIterLgt[8]=0.05;ITSCATrackerParam.minPtIterLgt[9]=0.09;ITSCATrackerParam.minPtIterLgt[10]=0.167;ITSCATrackerParam.minPtIterLgt[11]=0.125;" - EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.deltaRof=1;ITSVertexerParam.deltaRof=1;" # enable delta-rof tracking + # enable delta-rof tracking + EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.addTimeError[0]=30;ITSCATrackerParam.addTimeError[1]=30;ITSCATrackerParam.addTimeError[2]=30;ITSCATrackerParam.addTimeError[3]=30;ITSCATrackerParam.addTimeError[4]=30;ITSCATrackerParam.addTimeError[5]=30;ITSCATrackerParam.addTimeError[6]=30;ITSVertexerParam.seedMemberRadiusTime=1;" # this is to impose old pp pT cuts (overriding hardcoded pbpb24 apass1 settings) # EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPtIterLgt[0]=0.05;ITSCATrackerParam.minPtIterLgt[1]=0.05;ITSCATrackerParam.minPtIterLgt[2]=0.05;ITSCATrackerParam.minPtIterLgt[3]=0.05;ITSCATrackerParam.minPtIterLgt[4]=0.05;ITSCATrackerParam.minPtIterLgt[5]=0.05;ITSCATrackerParam.minPtIterLgt[6]=0.05;ITSCATrackerParam.minPtIterLgt[7]=0.05;ITSCATrackerParam.minPtIterLgt[8]=0.05;ITSCATrackerParam.minPtIterLgt[9]=0.05;ITSCATrackerParam.minPtIterLgt[10]=0.05;ITSCATrackerParam.minPtIterLgt[11]=0.05;" fi diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index 1f5696e75..86f5ee2e1 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -28,9 +28,19 @@ def add(cfg, flatconfig): if 302000 <= int(args.run) and int(args.run) < 309999: add(config, {"ITSAlpideParam.roFrameLengthInBC" : 198}) # ITS reco settings - add(config, {"ITSVertexerParam.phiCut" : 0.5, - "ITSVertexerParam.clusterContributorsCut" : 3, - "ITSVertexerParam.tanLambdaCut" : 0.2}) + add(config, {"ITSVertexerParam.pairCut": 0.0317563, + "ITSVertexerParam.clusterCut": 0.6640964, + "ITSVertexerParam.coarseZWindow": 0.2049018, + "ITSVertexerParam.seedDedupZCut": 0.0711793, + "ITSVertexerParam.refitDedupZCut": 0.0680009, + "ITSVertexerParam.duplicateZCut": 0.1582193, + "ITSVertexerParam.finalSelectionZCut": 0.1081465, + "ITSVertexerParam.duplicateDistance2Cut": 0.0117033, + "ITSVertexerParam.clusterContributorsCut": 2, + "ITSVertexerParam.seedMemberRadiusZ": 0, + "ITSVertexerParam.vertNsigmaCut": 4.0, + "ITSVertexerParam.vertRadiusSigma": 0.0452309, + "ITSVertexerParam.trackletSigma": 0.0025941}) # primary vertexing settings if 301000 <= int(args.run) and int(args.run) <= 301999: add(config, {"pvertexer.acceptableScale2" : 9, diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index ecd00867a..f11f66863 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1390,7 +1390,6 @@ def getDigiTaskName(det): ITSRECOtask['cmd'] = task_finalizer([ "${O2_ROOT}/bin/o2-its-reco-workflow" if args.detectorList == 'ALICE2' else "${O2_ROOT}/bin/o2-its3-reco-workflow", getDPL_global_options(bigshm=havePbPb), - '--trackerCA' if args.detectorList == 'ALICE2' else '', '--tracking-mode async', putConfigValues(["ITSVertexerParam", "ITSAlpideParam", From d5418b9477af158b5e12200eb968d07d1850b938 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Thu, 16 Apr 2026 18:05:16 +0200 Subject: [PATCH 292/362] Set proper settings for ITS vertexer --- MC/bin/o2dpg_sim_config.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index 86f5ee2e1..2958063b7 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -28,7 +28,9 @@ def add(cfg, flatconfig): if 302000 <= int(args.run) and int(args.run) < 309999: add(config, {"ITSAlpideParam.roFrameLengthInBC" : 198}) # ITS reco settings - add(config, {"ITSVertexerParam.pairCut": 0.0317563, + add(config, {"ITSVertexerParam.phiCut": 0.4, + "ITSVertexerParam.tanLambdaCut": 0.17, + "ITSVertexerParam.pairCut": 0.0317563, "ITSVertexerParam.clusterCut": 0.6640964, "ITSVertexerParam.coarseZWindow": 0.2049018, "ITSVertexerParam.seedDedupZCut": 0.0711793, @@ -96,10 +98,6 @@ def add(cfg, flatconfig): if args.fwdmatching_cut_4_param == True: add(config, {"FwdMatching.cutFcn" : "cut3SigmaXYAngles"}) - # deal with larger combinatorics - if args.col == "PbPb" or (args.embedding and args.colBkg == "PbPb"): - add(config, {"ITSVertexerParam.lowMultBeamDistCut": "0."}) - # FIT digitizer settings # 2023 PbPb if 543437 <= int(args.run) and int(args.run) <= 545367: @@ -244,4 +242,4 @@ def overwrite_config(config, mainkey, subkey, value): if mainkey not in config: # Initialize the main key in the dictionary if it does not already exist config[mainkey] = {} - config[mainkey][subkey] = value \ No newline at end of file + config[mainkey][subkey] = value From a935d7d40c1fc8c2bd9bc7a62c251e1afdc7acbd Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Sat, 18 Apr 2026 16:17:58 +0530 Subject: [PATCH 293/362] [PWGLF] Added injected configuration to use flat rapidity and pt (#2327) * [PWGLF] Added Resonance injected configuration Use flat rapidity and pT * Added corresponding test --- ...ancesBaryonic_pp1360_rapidityinjection.ini | 10 ++ ...onancesBaryonic_pp1360_rapidityinjection.C | 142 ++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.ini new file mode 100644 index 000000000..3b27a5608 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] # this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.C new file mode 100644 index 000000000..27069c08f --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } From 95cc50b4dc1ab201d903250906a5f492ffb9a2ec Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Thu, 9 Apr 2026 15:30:21 +0200 Subject: [PATCH 294/362] Fix concatenation for McCollisions indexed Trees --- MC/utils/AODBcRewriter.C | 164 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C index 0aa48d8f6..f5d3f19ec 100644 --- a/MC/utils/AODBcRewriter.C +++ b/MC/utils/AODBcRewriter.C @@ -55,6 +55,18 @@ static const char *findIndexBranchName(TTree *t) { return nullptr; } +static const char *findMcCollisionIndexBranchName(TTree *t) { + if (!t) + return nullptr; + if (t->GetBranch("fIndexMcCollisions")) + return "fIndexMcCollisions"; + return nullptr; +} + +static inline bool isMcCollisionTree(const char *tname) { + return TString(tname).BeginsWith("O2mccollision"); +} + // Scalar type tag enum class ScalarTag { kInt, @@ -336,6 +348,10 @@ struct BCMaps { std::vector indexMap; std::vector uniqueBCs; std::unordered_map> newIndexOrigins; + + // McCollision scheme (populated when O2mccollision is sorted) during first stage + std::vector mcOldEntries; + std::vector mcNewEntries; }; static BCMaps buildBCMaps(TTree *treeBCs) { @@ -543,7 +559,7 @@ static bool isVLA(TBranch *br) { // This is the VLA-aware rewritePayloadSorted implementation (keeps previous // tested behavior) static void rewritePayloadSorted(TDirectory *dirIn, TDirectory *dirOut, - const BCMaps &maps) { + BCMaps &maps) { std::unordered_set skipNames; // for count branches TIter it(dirIn->GetListOfKeys()); while (TKey *k = (TKey *)it()) { @@ -562,6 +578,13 @@ static void rewritePayloadSorted(TDirectory *dirIn, TDirectory *dirOut, const char *idxName = findIndexBranchName(src); if (!idxName) { + // Tables indexed by McCollisions (not BCs) are forwarded to the second + // stage where the sorting scheme is available. + if (findMcCollisionIndexBranchName(src)) { + std::cout << " [forward] " << tname + << " (McCollision-indexed) -> second stage\n"; + continue; + } dirOut->cd(); std::cout << " [copy] " << tname << " (no index) -> cloning\n"; TTree *c = src->CloneTree(-1, "fast"); @@ -649,6 +672,18 @@ static void rewritePayloadSorted(TDirectory *dirIn, TDirectory *dirOut, return a.entry < b.entry; }); + // If this is the McCollision tree, record the sort permutation so that + // tables indexed by McCollisions (fIndexMcCollisions) can be reordered consistently + if (isMcCollisionTree(tname)) { + maps.mcOldEntries.resize(keys.size()); + maps.mcNewEntries.assign(nEnt, -1); + for (Long64_t j = 0; j < (Long64_t)keys.size(); ++j) { + maps.mcOldEntries[j] = keys[j].entry; + if (keys[j].entry >= 0) + maps.mcNewEntries[keys[j].entry] = j; + } + } + // prepare output tree dirOut->cd(); TTree *out = src->CloneTree(0, "fast"); @@ -889,6 +924,133 @@ static void rewritePayloadSorted(TDirectory *dirIn, TDirectory *dirOut, out->Write(); } // end while keys in dir + // ---- second stage: tables indexed by McCollisions using fIndexMcCollisions ---- + if (!maps.mcNewEntries.empty()) { + TIter it2(dirIn->GetListOfKeys()); + while (TKey *k2 = (TKey *)it2()) { + if (TString(k2->GetClassName()) != "TTree") + continue; + std::unique_ptr holder2(k2->ReadObj()); + TTree *src2 = dynamic_cast(holder2.get()); + if (!src2) + continue; + const char *tname2 = src2->GetName(); + if (isBCtree(tname2) || isFlagsTree(tname2)) + continue; + if (findIndexBranchName(src2)) + continue; // handled in first stage + const char *mcIdxName = findMcCollisionIndexBranchName(src2); + if (!mcIdxName) { + // No BC index and no McCollision index → already handled (copied) earlier + continue; + } + + std::cout << " [proc] reindex+SORT " << tname2 + << " (McCollision index=" << mcIdxName << ")\n"; + + TBranch *inMcIdxBr = src2->GetBranch(mcIdxName); + if (!inMcIdxBr) { + std::cerr << " ERR no McCollision index branch\n"; + continue; + } + Int_t oldMcI = 0, newMcI = 0; + inMcIdxBr->SetAddress(&oldMcI); + + // Build sort keys: sort by new McCollision position. + Long64_t nEnt2 = src2->GetEntries(); + std::vector keys2; + keys2.reserve(nEnt2); + for (Long64_t i = 0; i < nEnt2; ++i) { + inMcIdxBr->GetEntry(i); + Long64_t newMcPos = -1; + if (oldMcI >= 0 && + (size_t)oldMcI < maps.mcNewEntries.size()) + newMcPos = maps.mcNewEntries[(size_t)oldMcI]; + keys2.push_back({i, newMcPos}); + } + std::stable_sort(keys2.begin(), keys2.end(), + [](const SortKey &a, const SortKey &b) { + bool ai = (a.newBC < 0), bi = (b.newBC < 0); + if (ai != bi) + return !ai && bi; + if (a.newBC != b.newBC) + return a.newBC < b.newBC; + return a.entry < b.entry; + }); + + dirOut->cd(); + TTree *out2 = src2->CloneTree(0, "fast"); + + std::unordered_map inBrs2, outBrs2; + for (auto *b : *src2->GetListOfBranches()) + inBrs2[((TBranch *)b)->GetName()] = (TBranch *)b; + for (auto *b : *out2->GetListOfBranches()) + outBrs2[((TBranch *)b)->GetName()] = (TBranch *)b; + + TBranch *outMcIdxBr = out2->GetBranch(mcIdxName); + outMcIdxBr->SetAddress(&newMcI); + + std::unordered_set skipNames2; + skipNames2.insert(mcIdxName); + + std::vector> scalarBufs2; + for (auto &kv : inBrs2) { + if (skipNames2.count(kv.first)) + continue; + TBranch *inBr = kv.second; + TBranch *ouBr = outBrs2.count(kv.first) ? outBrs2[kv.first] : nullptr; + if (!ouBr) + continue; + TLeaf *leaf = (TLeaf *)inBr->GetListOfLeaves()->At(0); + if (!leaf || isVLA(inBr)) + continue; // no variable-length arrays seen in McCollision-indexed tables (could be changed in the future) + ScalarTag tag = leafType(leaf); + if (tag == ScalarTag::kUnknown) + continue; + auto sb = bindScalarBranch(inBr, ouBr, tag); + if (sb) + scalarBufs2.emplace_back(std::move(sb)); + } + + Long64_t changed2 = 0; + for (const auto &sk : keys2) { + src2->GetEntry(sk.entry); + Int_t prev = oldMcI; + newMcI = (sk.newBC >= 0 ? (Int_t)sk.newBC : -1); + if (newMcI != prev) + ++changed2; + out2->Fill(); + } + std::cout << " wrote " << out2->GetEntries() + << " rows; remapped " << changed2 + << " McCollision index values; sorted\n"; + out2->Write(); + } + } else { + // No mccollision permutation available: clone deferred trees as-is + TIter it2(dirIn->GetListOfKeys()); + while (TKey *k2 = (TKey *)it2()) { + if (TString(k2->GetClassName()) != "TTree") + continue; + std::unique_ptr holder2(k2->ReadObj()); + TTree *src2 = dynamic_cast(holder2.get()); + if (!src2) + continue; + if (isBCtree(src2->GetName()) || isFlagsTree(src2->GetName())) + continue; + if (findIndexBranchName(src2)) + continue; + if (!findMcCollisionIndexBranchName(src2)) + continue; + std::cerr << " [warn] no mccollision permutation for " + << src2->GetName() << " -> cloning as-is\n"; + dirOut->cd(); + TTree *c = src2->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); + c->Write(); + } + } + // non-tree objects: copy as-is (but for TMap use WriteTObject to preserve // class) it.Reset(); From a1fff0322b205ec4e9b0236a257b584ef32d0b9f Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Mon, 23 Mar 2026 13:48:14 +0100 Subject: [PATCH 295/362] Enforce merge-by-name AOD merging for MC-DATA embedding This is needed to preserve the same DF structure as in the parent file. --- MC/run/ANCHOR/anchorMC_DataEmbedding.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh index 74aecfd7b..6108e59eb 100755 --- a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh +++ b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh @@ -452,7 +452,7 @@ done if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then # produce the final merged AO2D find ./ -maxdepth 2 -mindepth 2 -name "AO2D.root" > aod_inputs.txt - o2-aod-merger --input aod_inputs.txt --output AO2D.root + o2-aod-merger --input aod_inputs.txt --output AO2D.root --merge-by-name # --merge-by-name restricts merging to folders of same name fi # From 110e721f60613efc43b9178e8d802f95eae0b451 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 20 Apr 2026 14:49:13 +0200 Subject: [PATCH 296/362] Clean up vertexing parameters in o2dpg_sim_config.py Removed unused vertexing parameters from configuration. Needed with merge of https://github.com/AliceO2Group/AliceO2/pull/15289 --- MC/bin/o2dpg_sim_config.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index 2958063b7..62aef7df1 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -40,9 +40,7 @@ def add(cfg, flatconfig): "ITSVertexerParam.duplicateDistance2Cut": 0.0117033, "ITSVertexerParam.clusterContributorsCut": 2, "ITSVertexerParam.seedMemberRadiusZ": 0, - "ITSVertexerParam.vertNsigmaCut": 4.0, - "ITSVertexerParam.vertRadiusSigma": 0.0452309, - "ITSVertexerParam.trackletSigma": 0.0025941}) + "ITSVertexerParam.nSigmaCut": 0.032841}) # primary vertexing settings if 301000 <= int(args.run) and int(args.run) <= 301999: add(config, {"pvertexer.acceptableScale2" : 9, From f401783c5446edb252ef36646d2f71e64e263268 Mon Sep 17 00:00:00 2001 From: MRazza <118839113+MRazza879@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:10:48 +0200 Subject: [PATCH 297/362] [PWGHF] removed primary deuteron from PYTHIA (#2328) [PWGHF] remove commented primary deuteron block Co-authored-by: Marta Razza --- .../PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg | 7 ------- 1 file changed, 7 deletions(-) diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg index dd7df4cd9..f59bc78da 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg @@ -10,13 +10,6 @@ SoftQCD:inelastic on # all inelastic processes ParticleDecays:limitTau0 on ParticleDecays:tau0Max 10. -# enable deuteron production by coalescence collisions -HadronLevel:DeuteronProduction = on -DeuteronProduction:channels = {2212 2112 > 22} -DeuteronProduction:models = {0} -DeuteronProduction:norm = 1 -DeuteronProduction:parms = {0.5 1} # coalescence momentum p0 in GeV/c - ### switching on Pythia Mode2 ColourReconnection:mode 1 ColourReconnection:allowDoubleJunRem off From 55530df3da80a1ced5b5c1df3e5f370608c59ec8 Mon Sep 17 00:00:00 2001 From: Rashi gupta <167059733+rashigupt@users.noreply.github.com> Date: Tue, 21 Apr 2026 20:34:17 +0530 Subject: [PATCH 298/362] =?UTF-8?q?Flat=20=CF=80=E2=81=B0=20and=20=CE=B7?= =?UTF-8?q?=20Distribution=20for=20High-=20pT=20=20=20=20Statistics=20(#23?= =?UTF-8?q?18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update GeneratorHF_Non_Hfe.json Flat pion and eta distributions are added to enhance statistics at high transverse momentum. * Update pythia8_NonHfe.cfg Remove CR mode2 * Update GeneratorHF_Non_Hfe.json * Remove number parameter * Update GeneratorHF_Non_Hfe.json --- .../PWGHF/hybrid/GeneratorHF_Non_Hfe.json | 31 +++++++++++++------ .../pythia8/generator/pythia8_NonHfe.cfg | 19 ------------ 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json b/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json index a80e0da31..c729060bb 100644 --- a/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json +++ b/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json @@ -3,12 +3,7 @@ { "name": "pythia8", "config": { - "config": "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg", - "hooksFileName": "", - "hooksFuncName": "", - "includePartonEvent": true, - "particleFilter": "", - "verbose": 0 + "config": "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NonHfe.cfg" }, "triggers": { "mode": "or", @@ -19,9 +14,27 @@ } ] } + }, + { + "name": "boxgen", + "config": { + "pdg": 111, + "prange[0]": 0.1, + "prange[1]": 50.0, + "eta[0]": -0.8, + "eta[1]": 0.8 + } + }, + { + "name": "boxgen", + "config": { + "pdg": 221, + "prange[0]": 0.1, + "prange[1]": 50.0, + "eta[0]": -0.8, + "eta[1]": 0.8 + } } ], - "fractions": [ - 1 - ] + "fractions": [1, 1, 1] } diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg index e4fe0e6f2..b19227718 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg @@ -14,25 +14,6 @@ SoftQCD:inelastic on # all inelastic processes ParticleDecays:limitTau0 on ParticleDecays:tau0Max 10. -### switching on Pythia Mode2 -ColourReconnection:mode 1 -ColourReconnection:allowDoubleJunRem off -ColourReconnection:m0 0.3 -ColourReconnection:allowJunctions on -ColourReconnection:junctionCorrection 1.20 -ColourReconnection:timeDilationMode 2 -ColourReconnection:timeDilationPar 0.18 -StringPT:sigma 0.335 -StringZ:aLund 0.36 -StringZ:bLund 0.56 -StringFlav:probQQtoQ 0.078 -StringFlav:ProbStoUD 0.2 -StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 -MultiPartonInteractions:pT0Ref 2.15 -BeamRemnants:remnantMode 1 -BeamRemnants:saturation 5 - - ### switch off all decay channels 111:onMode = off 221:onMode = off From 7d26cc3905c1352ef897d2b4fc2641dc387e158c Mon Sep 17 00:00:00 2001 From: spulawsk Date: Wed, 22 Apr 2026 15:01:02 +0200 Subject: [PATCH 299/362] Update of FIT digitizer parameters for 2025 data (#2330) * WIP: update digitizer params for 2025 (temporary values) * UPDATE of FIT digitizer parameters for 2025 data and recent digitizer upgrade * Add pO for trigger parameters * Correct pp FV0 settings --------- Co-authored-by: Szymon Pulawski --- MC/bin/o2dpg_sim_config.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index 62aef7df1..6261401a3 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -111,6 +111,29 @@ def add(cfg, flatconfig): if COLTYPEIR == "PbPb": # 4 ADC channels / MIP add(config, {"FV0DigParam.adcChannelsPerMip": "4"}) + # 2025 + # first and last run of 2025 + if 562260 <= int(args.run) and int(args.run) <= 568721: + # 14 ADC channels / MIP for FT0 + add(config, {"FT0DigParam.mMip_in_V": "7", "FT0DigParam.mMV_2_Nchannels": "2", "FT0DigParam.mMV_2_NchannelsInverse": "0.5"}) + if COLTYPEIR == "PbPb": + # 4 ADC channels / MIP + add(config, {"FV0DigParam.adcChannelsPerMip": "4"}) + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "1433", "FT0DigParam.mtrg_semicentral_trh": "35"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "1080"}) + if COLTYPEIR == "pp" or COLTYPEIR == "OO" or COLTYPEIR == "NeNe" or COLTYPEIR == "pO": + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "40", "FT0DigParam.mtrg_semicentral_trh": "20"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "8"}) + if COLTYPEIR == "pp": + # 15 ADC channels / MIP + add(config, {"FV0DigParam.adcChannelsPerMip": "15"}) + if COLTYPEIR == "OO" or COLTYPEIR == "NeNe" or COLTYPEIR == "pO": + # 11 ADC channels / MIP + add(config, {"FV0DigParam.adcChannelsPerMip": "11"}) return config From 3be71b2928521d25c51a7ec679c7274e7f3dfb85 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 22 Apr 2026 23:12:09 +0200 Subject: [PATCH 300/362] Revert at the moment to old syst.error for matched tracks time To have 2026 systematics compatible with previous years --- DATA/production/configurations/asyncReco/setenv_extra.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 329e9e9dc..55f97b10b 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -349,12 +349,7 @@ if [[ $ALIGNLEVEL == 0 ]]; then elif [[ $ALIGNLEVEL == 1 ]]; then ERRIB="100e-8" ERROB="100e-8" - if [[ $ALIEN_JDL_LPMANCHORYEAR == "2026" ]] ; then - [[ -z $TPCITSTIMEERR ]] && TPCITSTIMEERR="0.05" - EXTRA_PRIMVTX_TimeMargin="pvertexer.timeMarginVertexTime=0.3" - else - [[ -z $TPCITSTIMEERR ]] && TPCITSTIMEERR="0.2" - fi + [[ -z $TPCITSTIMEERR ]] && TPCITSTIMEERR="0.2" if [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" && $BEAMTYPE == "PbPb" && $ANCHORED_PASS_NUMBER -lt 5 ]] || [[ $PERIOD == "LHC24al" ]] ; then [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" ]] && [[ $BEAMTYPE == "PbPb" ]] && CUT_MATCH_CHI2=80 || CUT_MATCH_CHI2=100 export ITSTPCMATCH="tpcitsMatch.safeMarginTimeCorrErr=2.;tpcitsMatch.XMatchingRef=60.;tpcitsMatch.cutMatchingChi2=$CUT_MATCH_CHI2;;tpcitsMatch.crudeAbsDiffCut[0]=6;tpcitsMatch.crudeAbsDiffCut[1]=6;tpcitsMatch.crudeAbsDiffCut[2]=0.3;tpcitsMatch.crudeAbsDiffCut[3]=0.3;tpcitsMatch.crudeAbsDiffCut[4]=2.5;tpcitsMatch.crudeNSigma2Cut[0]=64;tpcitsMatch.crudeNSigma2Cut[1]=64;tpcitsMatch.crudeNSigma2Cut[2]=64;tpcitsMatch.crudeNSigma2Cut[3]=64;tpcitsMatch.crudeNSigma2Cut[4]=64;" From cf0e9a5b6a88dd35b015d256cdf99ab9de4d59f2 Mon Sep 17 00:00:00 2001 From: rmunzer <97919772+rmunzer@users.noreply.github.com> Date: Fri, 24 Apr 2026 10:26:20 +0200 Subject: [PATCH 301/362] Change range for Laser qc (#2332) --- DATA/production/calib/tpc-laser-aggregator.sh | 2 +- DATA/production/calib/tpc-laser.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DATA/production/calib/tpc-laser-aggregator.sh b/DATA/production/calib/tpc-laser-aggregator.sh index e409850eb..5dd282ade 100755 --- a/DATA/production/calib/tpc-laser-aggregator.sh +++ b/DATA/production/calib/tpc-laser-aggregator.sh @@ -8,7 +8,7 @@ FILEWORKDIR="/home/wiechula/processData/inputFilesTracking/triggeredLaser" PROXY_INSPEC="A:TPC/LASERTRACKS;B:TPC/CEDIGITS;D:TPC/CLUSREFS" -CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=300;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=602;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" +CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=600;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=1202;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" [[ $RUNTYPE == "SYNTHETIC" ]] && CCDB_PATH="http://ccdb-test.cern.ch:8080" || CCDB_PATH="http://o2-ccdb.internal" diff --git a/DATA/production/calib/tpc-laser.sh b/DATA/production/calib/tpc-laser.sh index 575e03300..b859d440d 100755 --- a/DATA/production/calib/tpc-laser.sh +++ b/DATA/production/calib/tpc-laser.sh @@ -48,7 +48,7 @@ fi PROXY_INSPEC="A:TPC/RAWDATA;dd:FLP/DISTSUBTIMEFRAME/0" CALIB_INSPEC="A:TPC/RAWDATA;dd:FLP/DISTSUBTIMEFRAME/0" -CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=250;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=502;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" +CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=400;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=802;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" CCDB_PATH="http://o2-ccdb.internal" From 198c1c80621fd5d24b77286e3c4ac7690093de56 Mon Sep 17 00:00:00 2001 From: rbailhac Date: Fri, 24 Apr 2026 15:39:13 +0200 Subject: [PATCH 302/362] Missing 10-20 and 20-30 centrality bin for Pb--Pb cocktail (#2333) --- .../ini/GeneratorEMCocktail_502PbPb_1020.ini | 6 ++ .../ini/GeneratorEMCocktail_502PbPb_2030.ini | 6 ++ .../tests/GeneratorEMCocktail_502PbPb_1020.C | 64 +++++++++++ .../tests/GeneratorEMCocktail_502PbPb_2030.C | 64 +++++++++++ .../parametrizations/PbPb5TeV_central.json | 100 ++++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_1020.ini create mode 100644 MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_2030.ini create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_1020.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_2030.C diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_1020.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_1020.ini new file mode 100644 index 000000000..a492a4a1e --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_1020.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_1020_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_2030.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_2030.ini new file mode 100644 index 000000000..0cc122f7b --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_2030.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_2030_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_1020.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_1020.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_1020.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_2030.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_2030.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_2030.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json b/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json index 8f724cdf3..546802e7f 100644 --- a/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json +++ b/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json @@ -99,6 +99,106 @@ "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, + "5TeV_1020_wRatio_etatest": { + "histoMtScaleFactor": { + "113": 0.85, + "223": 0.7, + "331": 0.4 + }, + "111_pt": "TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))", + "221_pt": "(2.25035e-05*TMath::Power((exp(--2.8764*sqrt(x*x+0.547*0.547-0.139*0.139)-0.734747*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.477784/2.25035e-05,-1./8.26791)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00603254),-8.26791)/TMath::Power((exp(--2.8764*x-0.734747*x*x)+x/0.00603254),-8.26791)+1.14358*TMath::Landau(x,2.10694,0.888101))*(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*(0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)" + }, + "5TeV_1020_wRatio_etatest_ratiosup": { + "histoMtScaleFactor": { + "113": 1.02, + "223": 0.84, + "331": 0.48 + }, + "111_pt": "TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))", + "221_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*((TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*((x<=0.5)*(-0.3/0.5*x+1.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*1.2*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748))))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))) *((x<=0.5)*(-0.3/0.5*x+1.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*1.2*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)))" + }, + "5TeV_1020_wRatio_etatest_ratiosdown": { + "histoMtScaleFactor": { + "113": 0.68, + "223": 0.56, + "331": 0.32 + }, + "111_pt": "TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))", + "221_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*((x<=0.5)*(0.3/0.5*x+0.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*0.8*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))) *((x<=0.5)*(0.3/0.5*x+0.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*0.8*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)))" + }, + "5TeV_1020_wRatio_etatest_pi0up": { + "histoMtScaleFactor": { + "113": 0.85, + "223": 0.7, + "331": 0.4 + }, + "111_pt": "TMath::TwoPi()*x*(111.543*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392547)+1748.52*pow(exp(-0.930464*x-0.532639*x*x)+x/0.467782,-5.54415))", + "221_pt": "(TMath::TwoPi()*x*(111.543*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392547)+1748.52*pow(exp(-0.930464*x-0.532639*x*x)+x/0.467782,-5.54415)))*(2.25035e-05*TMath::Power((exp(--2.8764*sqrt(x*x+0.547*0.547-0.139*0.139)-0.734747*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.477784/2.25035e-05,-1./8.26791)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00603254),-8.26791)/TMath::Power((exp(--2.8764*x-0.734747*x*x)+x/0.00603254),-8.26791)+1.14358*TMath::Landau(x,2.10694,0.888101))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*(0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)" + }, + "5TeV_1020_wRatio_etatest_pi0down": { + "histoMtScaleFactor": { + "113": 0.85, + "223": 0.7, + "331": 0.4 + }, + "111_pt": "TMath::TwoPi()*x*(93.2981*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.397978)+1354.67*pow(exp(-1.09806*x-0.414866*x*x)+x/0.487866,-5.55472))", + "221_pt": "(TMath::TwoPi()*x*(93.2981*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.397978)+1354.67*pow(exp(-1.09806*x-0.414866*x*x)+x/0.487866,-5.55472)))*(2.25035e-05*TMath::Power((exp(--2.8764*sqrt(x*x+0.547*0.547-0.139*0.139)-0.734747*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.477784/2.25035e-05,-1./8.26791)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00603254),-8.26791)/TMath::Power((exp(--2.8764*x-0.734747*x*x)+x/0.00603254),-8.26791)+1.14358*TMath::Landau(x,2.10694,0.888101))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*(0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)" + }, + "5TeV_2030_wRatio_etatest": { + "histoMtScaleFactor": { + "113": 0.85, + "223": 0.7, + "331": 0.4 + }, + "111_pt": "TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108))", + "221_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.00038991*TMath::Power((exp(--2.8689*sqrt(x*x+0.547*0.547-0.139*0.139)-0.716403*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478705/0.00038991,-1./7.39763)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00709108),-7.39763)/TMath::Power((exp(--2.8689*x-0.716403*x*x)+x/0.00709108),-7.39763)+0.917471*TMath::Landau(x,2.17426,0.976011))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)" + }, + "5TeV_2030_wRatio_etatest_ratiosup": { + "histoMtScaleFactor": { + "113": 1.02, + "223": 0.84, + "331": 0.48 + }, + "111_pt": "TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108))", + "221_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<11.3582)*(TMath::Max(TMath::Max(0.0622931*TMath::Power((exp(--0.430138*sqrt(x*x+0.547*0.547-0.139*0.139)-0.308378*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.497447/0.0622931,-1./7.93993)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.24166),-7.93993)/TMath::Power((exp(--0.430138*x-0.308378*x*x)+x/1.24166),-7.93993)+0.909031*TMath::Landau(x,2.74364,1.23978),0.00172495*TMath::Power((exp(-1.13225*sqrt(x*x+0.547*0.547-0.139*0.139)-0.126955*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496991/0.00172495,-1./0.657116)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.064674),-0.657116)/TMath::Power((exp(-1.13225*x-0.126955*x*x)+x/0.064674),-0.657116)+1.64346*TMath::Landau(x,2.12011,0.856277)),TMath::Max(0.000832695*TMath::Power((exp(-0.26446*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0253786*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.48268/0.000832695,-1./4.34962)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.110892),-4.34962)/TMath::Power((exp(-0.26446*x-0.0253786*x*x)+x/0.110892),-4.34962)+0.846008*TMath::Landau(x,3.42622,1.68176),0.00172495*TMath::Power((exp(-1.13225*sqrt(x*x+0.547*0.547-0.139*0.139)-0.126955*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496991/0.00172495,-1./0.657116)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.064674),-0.657116)/TMath::Power((exp(-1.13225*x-0.126955*x*x)+x/0.064674),-0.657116)+1.64346*TMath::Landau(x,2.12011,0.856277))))+(x>=11.3582)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<=0.5)*(-0.3/0.5*x+1.5)*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629))+(x>0.5)*1.2*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)))" + }, + "5TeV_2030_wRatio_etatest_ratiosdown": { + "histoMtScaleFactor": { + "113": 0.68, + "223": 0.56, + "331": 0.32 + }, + "111_pt": "TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108))", + "221_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<6.000000)*(0.940000*(TMath::Min(TMath::Min(0.00779577*TMath::Power((exp(--0.684847*sqrt(x*x+0.547*0.547-0.139*0.139)-1.53786*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00779577,-1./60.1223)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.685219),-60.1223)/TMath::Power((exp(--0.684847*x-1.53786*x*x)+x/0.685219),-60.1223)+1.63771*TMath::Landau(x,2.42852,0.955009),1.92417*TMath::Power((exp(-0.0810564*sqrt(x*x+0.547*0.547-0.139*0.139)-0.616729*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/1.92417,-1./68.3973)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.973421),-68.3973)/TMath::Power((exp(-0.0810564*x-0.616729*x*x)+x/0.973421),-68.3973)+1.5307*TMath::Landau(x,2.72093,1.07219)),TMath::Min(0.000514864*TMath::Power((exp(-1.38498*sqrt(x*x+0.547*0.547-0.139*0.139)-2.57506*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.466/0.000514864,-1./7.53845)*sqrt(x*x+0.547*0.547-0.139*0.139)/1e-09),-7.53845)/TMath::Power((exp(-1.38498*x-2.57506*x*x)+x/1e-09),-7.53845)+0.22292*TMath::Landau(x,0.338702,0.226932),1.92417*TMath::Power((exp(-0.0810564*sqrt(x*x+0.547*0.547-0.139*0.139)-0.616729*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/1.92417,-1./68.3973)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.973421),-68.3973)/TMath::Power((exp(-0.0810564*x-0.616729*x*x)+x/0.973421),-68.3973)+1.5307*TMath::Landau(x,2.72093,1.07219)))))+(x>=6.000000)*0.426)", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<=0.5)*(0.3/0.5*x+0.5)*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)) +(x>0.5)*0.8*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)))" + }, + "5TeV_2030_wRatio_etatest_pi0up": { + "histoMtScaleFactor": { + "113": 0.85, + "223": 0.7, + "331": 0.4 + }, + "111_pt": "TMath::TwoPi()*x*(54.9157*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.404309)+1436.73*pow(exp(-0.74937*x-0.556775*x*x)+x/0.478695,-5.61584))", + "221_pt": "(TMath::TwoPi()*x*(54.9157*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.404309)+1436.73*pow(exp(-0.74937*x-0.556775*x*x)+x/0.478695,-5.61584)))*(0.00038991*TMath::Power((exp(--2.8689*sqrt(x*x+0.547*0.547-0.139*0.139)-0.716403*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478705/0.00038991,-1./7.39763)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00709108),-7.39763)/TMath::Power((exp(--2.8689*x-0.716403*x*x)+x/0.00709108),-7.39763)+0.917471*TMath::Landau(x,2.17426,0.976011))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)" + }, + "5TeV_2030_wRatio_etatest_pi0down": { + "histoMtScaleFactor": { + "113": 0.85, + "223": 0.7, + "331": 0.4 + }, + "111_pt": "TMath::TwoPi()*x*(45.066*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41167)+1119.91*pow(exp(-0.905844*x-0.432426*x*x)+x/0.498136,-5.62645))", + "221_pt": "(TMath::TwoPi()*x*(45.066*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41167)+1119.91*pow(exp(-0.905844*x-0.432426*x*x)+x/0.498136,-5.62645)))*(0.00038991*TMath::Power((exp(--2.8689*sqrt(x*x+0.547*0.547-0.139*0.139)-0.716403*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478705/0.00038991,-1./7.39763)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00709108),-7.39763)/TMath::Power((exp(--2.8689*x-0.716403*x*x)+x/0.00709108),-7.39763)+0.917471*TMath::Landau(x,2.17426,0.976011))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)" + }, "5TeV_3040_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, From fd1719fc8269627bdc78fb99de34e169471c2631 Mon Sep 17 00:00:00 2001 From: rmunzer <97919772+rmunzer@users.noreply.github.com> Date: Mon, 27 Apr 2026 11:16:47 +0200 Subject: [PATCH 303/362] Add Parameters for CMV Readout (#2324) * Add Parameters for CMV Readout * Change unbound variable --- DATA/common/setenv_calib.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index 3b8dcf6a2..61e871a57 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -178,6 +178,9 @@ if [[ $CAN_DO_CALIB_TPC_SAC == 1 ]]; then fi fi fi +if [[ -z ${CALIB_TPC_CMV+x} ]]; then + CALIB_TPC_CMV=0; +fi ( [[ -z ${CALIB_FT0_INTEGRATEDCURR:-} ]] || [[ $CAN_DO_CALIB_FT0_INTEGRATEDCURR == 0 ]] ) && CALIB_FT0_INTEGRATEDCURR=0 ( [[ -z ${CALIB_FV0_INTEGRATEDCURR:-} ]] || [[ $CAN_DO_CALIB_FV0_INTEGRATEDCURR == 0 ]] ) && CALIB_FV0_INTEGRATEDCURR=0 @@ -307,6 +310,13 @@ if [[ -z ${CALIBDATASPEC_TPCIDC_C:-} ]]; then # TPC if [[ $CALIB_TPC_IDC == 1 ]]; then add_semicolon_separated CALIBDATASPEC_TPCIDC_C "idcsgroupc:TPC/IDCGROUPC"; fi fi +if [[ -z ${CALIBDATASPEC_TPCCMV:-} ]]; then + # TPC + if [[ $CALIB_TPC_CMV == 1 ]]; then + add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvgroup:TPC/CMVGROUP"; + add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvorbit:TPC/CMVORBITINFO"; + fi +fi # define spec for proxy for TPC SAC if [[ -z ${CALIBDATASPEC_TPCSAC:-} ]]; then From 7f1cb9feb0c640ab0ae54c8e4c4a780fc339a88d Mon Sep 17 00:00:00 2001 From: mbroz84 Date: Mon, 27 Apr 2026 14:52:39 +0200 Subject: [PATCH 304/362] New Tau decays in the python script (#2335) --- MC/config/PWGUD/ini/makeStarlightConfig.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/MC/config/PWGUD/ini/makeStarlightConfig.py b/MC/config/PWGUD/ini/makeStarlightConfig.py index cd68ac8a5..39f78de27 100755 --- a/MC/config/PWGUD/ini/makeStarlightConfig.py +++ b/MC/config/PWGUD/ini/makeStarlightConfig.py @@ -10,17 +10,17 @@ parser.add_argument('--collType',default='PbPb', choices=['PbPb', 'pPb', 'Pbp', 'pp', 'OO', 'pO', 'Op', 'NeNe'], help='Colission system') - + parser.add_argument('--eCM', type=float, default='5360', help='Centre-of-mass energy') parser.add_argument('--rapidity', default='cent', choices=['cent_rap', 'muon_rap', 'cent_eta', 'muon_eta'], help='Rapidity to select') -parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsiToLLbar', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToEl3Pi', 'kTauLowToPo3Pi', 'kTauMediumToEl3Pi', 'kTauMediumToPo3Pi', 'kTauHighToEl3Pi', 'kTauHighToPo3Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], +parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsiToLLbar', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToL+3Pi', 'kTauLowToL-3Pi', 'kTauLowToPi+3Pi', 'kTauLowToPi-3Pi', 'kTauLowTo6Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], help='Process to switch on') - - + + parser.add_argument('--output', default='GenStarlight.ini', help='Where to write the configuration') @@ -63,17 +63,17 @@ pZ = 8 pA = 16 tZ = 8 - tA = 16 + tA = 16 if 'pO' in args.collType: pZ = 1 pA = 1 tZ = 8 - tA = 16 + tA = 16 if 'Op' in args.collType: pZ = 8 pA = 16 tZ = 1 - tA = 1 + tA = 1 if 'NeNe' in args.collType: pZ = 10 pA = 20 @@ -95,7 +95,7 @@ else: fout.write('fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGUD/external/generator/GeneratorStarlight.C \n') fout.write('funcName = GeneratorStarlight("%s", %f, %d, %d, %d, %d, "%s", "%s") \n' % (args.process.split('_')[0],args.eCM ,pZ,pA,tZ,tA,args.extraPars,args.dpmjetConf)) - + ###Trigger if not 'kDpmjet' in args.process: fout.write('[TriggerExternal] \n') From 8871770ad7390957600a663a4892b9837b92ed54 Mon Sep 17 00:00:00 2001 From: shreyasiacharya <34233706+shreyasiacharya@users.noreply.github.com> Date: Mon, 27 Apr 2026 19:18:54 +0200 Subject: [PATCH 305/362] Update BTOPSIJPSITODIELECTRON.DEC with ChiC (#2338) --- .../BTOPSIJPSITODIELECTRON.DEC | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC index 64a835910..2a45f28c6 100644 --- a/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC +++ b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC @@ -38,6 +38,20 @@ Decay B0 0.000540000 J/psi K0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000800000 J/psi K*+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000660000 J/psi K*0 pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000011200 chi_c1 pi0 SVS; + 0.000395000 chi_c1 K0 SVS; + 0.000497000 chi_c1 K+ pi- PHSP; + 0.000320000 chi_c1 K0 pi+ pi- PHSP; + 0.000350000 chi_c1 K+ pi0 pi- PHSP; + +# --- chi_c2 --- + 0.000015000 chi_c2 K0 SVS; + 0.000049000 chi_c2 K*0 SVV_HELAMP 1.0 0.0 0.0; + 0.000072000 chi_c2 K+ pi- PHSP; + 0.000174000 chi_c2 pi+ pi- K0 PHSP; + 0.000074000 chi_c2 pi- pi0 K+ PHSP; Enddecay Decay anti-B0 @@ -78,6 +92,20 @@ Decay anti-B0 0.000540000 J/psi anti-K0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000800000 J/psi K*- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000660000 J/psi anti-K*0 pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000011200 chi_c1 pi0 SVS; + 0.000395000 chi_c1 anti-K0 SVS; + 0.000497000 chi_c1 K- pi+ PHSP; + 0.000320000 chi_c1 anti-K0 pi- pi+ PHSP; + 0.000350000 chi_c1 K- pi0 pi+ PHSP; + +# --- chi_c2 --- + 0.000015000 chi_c2 anti-K0 SVS; + 0.000049000 chi_c2 anti-K*0 SVV_HELAMP 1.0 0.0 0.0; + 0.000072000 chi_c2 K- pi+ PHSP; + 0.000174000 chi_c2 pi- pi+ anti-K0 PHSP; + 0.000074000 chi_c2 pi+ pi0 K- PHSP; Enddecay Decay B+ @@ -109,6 +137,21 @@ Decay B+ 0.000108000 J/psi eta K+ PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000350000 J/psi omega K+ PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000011800 J/psi p+ anti-Lambda0 PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000022000 chi_c1 pi+ SVS; + 0.000474000 chi_c1 K+ SVS; + 0.000300000 chi_c1 K*+ SVV_HELAMP 1.0 0.0 0.0; + 0.000329000 chi_c1 K+ pi0 PHSP; + 0.000580000 chi_c1 K0 pi+ PHSP; + 0.000374000 chi_c1 K+ pi+ pi- PHSP; + +# --- chi_c2 --- + 0.000110000 chi_c2 K+ SVS; + 0.000120000 chi_c2 K*+ SVV_HELAMP 1.0 0.0 0.0; + 0.000062000 chi_c2 K+ pi0 PHSP; + 0.000124000 chi_c2 K0 pi+ PHSP; + 0.000134000 chi_c2 K+ pi+ pi- PHSP; Enddecay Decay B- @@ -139,6 +182,21 @@ Decay B- 0.000108000 J/psi eta K- PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000350000 J/psi omega K- PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000011800 J/psi anti-p- Lambda0 PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000022000 chi_c1 pi- SVS; + 0.000474000 chi_c1 K- SVS; + 0.000300000 chi_c1 K*- SVV_HELAMP 1.0 0.0 0.0; + 0.000329000 chi_c1 K- pi0 PHSP; + 0.000580000 chi_c1 anti-K0 pi- PHSP; + 0.000374000 chi_c1 K- pi- pi+ PHSP; + +# --- chi_c2 --- + 0.000110000 chi_c2 K- SVS; + 0.000120000 chi_c2 K*- SVV_HELAMP 1.0 0.0 0.0; + 0.000062000 chi_c2 K- pi0 PHSP; + 0.000124000 chi_c2 anti-K0 pi- PHSP; + 0.000134000 chi_c2 K- pi- pi+ PHSP; Enddecay Decay B_s0 @@ -182,6 +240,9 @@ Decay B_s0 0.0002 J/psi pi0 pi0 PHSP; # PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e 0.0000023 phi e+ e- BTOSLLALI; + +# --- chi_c1 --- + 0.0001970 chi_c1 phi SVV_HELAMP 1.0 0.0 0.0; Enddecay Decay anti-B_s0 @@ -224,18 +285,29 @@ Decay anti-B_s0 0.0002 J/psi pi0 pi0 PHSP; # PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e 0.0000023 phi e- e+ BTOSLLALI; + +# --- chi_c1 --- + 0.0001970 chi_c1 phi SVV_HELAMP 1.0 0.0 0.0; Enddecay Decay Lambda_b0 ### 0.00038 Lambda0 psi(2S) PHSP; 0.00047 Lambda0 J/psi PHSP; + 0.0000760 chi_c1 p K- PHSP; + 0.0000050 chi_c1 p pi- PHSP; + 0.0000770 chi_c2 p K- PHSP; + 0.0000048 chi_c2 p pi- PHSP; Enddecay Decay anti-Lambda_b0 ### 0.00038 anti-Lambda0 psi(2S) PHSP; 0.00047 anti-Lambda0 J/psi PHSP; + 0.0000760 chi_c1 anti-p K+ PHSP; + 0.0000050 chi_c1 anti-p pi+ PHSP; + 0.0000770 chi_c2 anti-p K+ PHSP; + 0.0000048 chi_c2 anti-p pi+ PHSP; Enddecay Decay Xi_b- @@ -264,6 +336,19 @@ Decay anti-Omega_b+ Enddecay +# ============================================================================================================================= +# JPsi, Psi(2S), ChiC Decays +# ============================================================================================================================= +### +Decay chi_c1 + 1.000 J/psi gamma PHSP; +Enddecay + +### +Decay chi_c2 + 1.000 J/psi gamma PHSP; +Enddecay + Decay psi(2S) ### from DECAY.DEC 1.000 e+ e- PHOTOS VLL; From 509e034aeddff8ea718566606e414d79f4e16a79 Mon Sep 17 00:00:00 2001 From: SCHOTTER Romain <47983209+romainschotter@users.noreply.github.com> Date: Thu, 30 Apr 2026 09:50:46 +0200 Subject: [PATCH 306/362] Add configurations for rescattering in Pythia8 in pp 13.6 TeV and in Pythia8 Angantyr OO 5.36 TeV (#2340) * Add configuration for rescattering in Pythia8 pp 13.6 TeV * Add configuration for rescattering in Pythia8 OO 5.36 TeV --- .../ini/pythia8_pp_rescattering_136tev.ini | 9 +++++++ .../tests/pythia8_pp_rescattering_136tev.C | 24 +++++++++++++++++++ .../pythia8_pp_rescattering_136tev.cfg | 23 ++++++++++++++++++ .../ini/pythia8_OO_rescattering_536.ini | 9 +++++++ .../ini/tests/pythia8_OO_rescattering_536.C | 24 +++++++++++++++++++ .../generator/pythia8_OO_rescattering_536.cfg | 22 +++++++++++++++++ 6 files changed, 111 insertions(+) create mode 100644 MC/config/ALICE3/ini/pythia8_pp_rescattering_136tev.ini create mode 100644 MC/config/ALICE3/ini/tests/pythia8_pp_rescattering_136tev.C create mode 100644 MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg create mode 100644 MC/config/common/ini/pythia8_OO_rescattering_536.ini create mode 100644 MC/config/common/ini/tests/pythia8_OO_rescattering_536.C create mode 100644 MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_rescattering_136tev.ini b/MC/config/ALICE3/ini/pythia8_pp_rescattering_136tev.ini new file mode 100644 index 000000000..4189c775a --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_rescattering_136tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_rescattering_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_rescattering_136tev.C new file mode 100644 index 000000000..9b21ec151 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_rescattering_136tev.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg new file mode 100644 index 000000000..9d0adf1fe --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13600. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +### enable hadronic rescattering +HadronLevel:Rescatter = on # default = off +Fragmentation:setVertices = on # default = off +PartonVertex:setVertex = on # default = off +Rescattering:nearestNeighbours = off # default = on (but "require a larger retuning effort") +Rescattering:inelastic = on # default = on + +Random:setSeed = on diff --git a/MC/config/common/ini/pythia8_OO_rescattering_536.ini b/MC/config/common/ini/pythia8_OO_rescattering_536.ini new file mode 100644 index 000000000..a0f2fc2e5 --- /dev/null +++ b/MC/config/common/ini/pythia8_OO_rescattering_536.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg diff --git a/MC/config/common/ini/tests/pythia8_OO_rescattering_536.C b/MC/config/common/ini/tests/pythia8_OO_rescattering_536.C new file mode 100644 index 000000000..1c28040e2 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_OO_rescattering_536.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg b/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg new file mode 100644 index 000000000..cd0a11e50 --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg @@ -0,0 +1,22 @@ +### OO beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +### enable hadronic rescattering +HadronLevel:Rescatter = on # default = off +Fragmentation:setVertices = on # default = off +PartonVertex:setVertex = on # default = off +Rescattering:nearestNeighbours = off # default = on (but "require a larger retuning effort") +Rescattering:inelastic = on # default = on + +Random:setSeed = on From bc856656638179d09807a7a1bbabd88952394b3f Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Mon, 4 May 2026 11:23:09 +0200 Subject: [PATCH 307/362] PWGEM/MC: add cfg and ini for VM2ee (#2343) --- MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini | 10 ++++ .../PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C | 56 +++++++++++++++++++ .../generator/pythia8_pp_5360_VM2ee.cfg | 37 ++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini create mode 100644 MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini new file mode 100644 index 000000000..5b17885ed --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C new file mode 100644 index 000000000..aaee11ffc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // // check if each event has at least two oxygen ions + // for (int i = 0; i < nEvents; i++) + // { + // auto check = tree->GetEntry(i); + // int count = 0; + // for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + // { + // auto track = tracks->at(idxMCTrack); + // if (track.GetPdgCode() == 1000080160) + // { + // count++; + // } + // } + // if (count < 2) + // { + // std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + // return 1; + // } + // } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg new file mode 100644 index 000000000..b767c9ea3 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg @@ -0,0 +1,37 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# don't modify pion's PR as charged multiplicity is drived by them. + +# eta +221:oneChannel = 1 1.0 0 -11 11 22 + +# eta' +331:oneChannel = 1 0.294 0 -11 11 111 +331:addChannel = 1 0.706 0 -11 11 223 + +# rho +113:oneChannel = 1 1.0 0 -11 11 + +# omega +223:oneChannel = 1 0.088 0 -11 11 +223:addChannel = 1 0.912 0 -11 11 111 + +# phi +333:oneChannel = 1 0.710 0 -11 11 +333:addChannel = 1 0.032 0 -11 11 111 +333:addChannel = 1 0.258 0 -11 11 221 From 69aa1d7ee7224f030ae7c8b2a1dc78f15b5cc855 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Thu, 30 Apr 2026 16:12:35 +0200 Subject: [PATCH 308/362] setenv_calib.sh: additional check of TPC presence for CMV calib --- DATA/common/setenv_calib.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index 61e871a57..3ccb50b8e 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -20,7 +20,7 @@ if has_detector_calib TOF && has_detector_reco TOF && ( ( has_detectors_reco ITS if has_detector_calib TPC && has_detectors ITS TPC && has_detector_matching ITSTPC; then CAN_DO_CALIB_TPC_SCDCALIB=1; else CAN_DO_CALIB_TPC_SCDCALIB=0; fi if has_detector_calib TPC && has_processing_step TPC_DEDX; then CAN_DO_CALIB_TPC_TIMEGAIN=1; CAN_DO_CALIB_TPC_RESPADGAIN=1; else CAN_DO_CALIB_TPC_TIMEGAIN=0; CAN_DO_CALIB_TPC_RESPADGAIN=0; fi if has_detector_calib TPC && has_detectors ITS TPC && has_detector_matching ITSTPC; then CAN_DO_CALIB_TPC_VDRIFTTGL=1; else CAN_DO_CALIB_TPC_VDRIFTTGL=0; fi -if has_detector_calib TPC; then CAN_DO_CALIB_TPC_IDC=1; CAN_DO_CALIB_TPC_SAC=1; else CAN_DO_CALIB_TPC_IDC=0; CAN_DO_CALIB_TPC_SAC=0; fi +if has_detector_calib TPC; then CAN_DO_CALIB_TPC_IDC=1; CAN_DO_CALIB_TPC_SAC=1; CAN_DO_CALIB_TPC_CMV=1; else CAN_DO_CALIB_TPC_IDC=0; CAN_DO_CALIB_TPC_SAC=0; CAN_DO_CALIB_TPC_CMV=0; fi if [[ ! -z ${FLP_IDS:-} && ! $FLP_IDS =~ (^|,)"145"(,|$) ]] || [[ "${GEN_TOPO_DEPLOYMENT_TYPE:-}" == "ALICE_STAGING" ]]; then CAN_DO_CALIB_TPC_SAC=0; fi if has_detector_calib TRD && has_detectors ITS TPC TRD && has_detector_matching ITSTPCTRD; then CAN_DO_CALIB_TRD_VDRIFTEXB=1; CAN_DO_CALIB_TRD_GAIN=1; CAN_DO_CALIB_TRD_T0=1; else CAN_DO_CALIB_TRD_VDRIFTEXB=0; CAN_DO_CALIB_TRD_GAIN=0; CAN_DO_CALIB_TRD_T0=0; fi if has_detector_calib EMC && has_detector_reco EMC; then CAN_DO_CALIB_EMC_BADCHANNELCALIB=1; CAN_DO_CALIB_EMC_TIMECALIB=1; else CAN_DO_CALIB_EMC_BADCHANNELCALIB=0; CAN_DO_CALIB_EMC_TIMECALIB=0; fi @@ -178,8 +178,11 @@ if [[ $CAN_DO_CALIB_TPC_SAC == 1 ]]; then fi fi fi -if [[ -z ${CALIB_TPC_CMV+x} ]]; then - CALIB_TPC_CMV=0; +# CMV (be default, it is always disabled for now) +if [[ $CAN_DO_CALIB_TPC_CMV == 1 ]]; then + if [[ -z ${CALIB_TPC_CMV+x} ]]; then + CALIB_TPC_CMV=0; + fi fi ( [[ -z ${CALIB_FT0_INTEGRATEDCURR:-} ]] || [[ $CAN_DO_CALIB_FT0_INTEGRATEDCURR == 0 ]] ) && CALIB_FT0_INTEGRATEDCURR=0 @@ -312,7 +315,7 @@ if [[ -z ${CALIBDATASPEC_TPCIDC_C:-} ]]; then fi if [[ -z ${CALIBDATASPEC_TPCCMV:-} ]]; then # TPC - if [[ $CALIB_TPC_CMV == 1 ]]; then + if [[ $CALIB_TPC_CMV == 1 ]]; then add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvgroup:TPC/CMVGROUP"; add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvorbit:TPC/CMVORBITINFO"; fi From 1a8b75bf5be18450bce1fe64498251ff702d7011 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 28 Apr 2026 08:59:15 +0200 Subject: [PATCH 309/362] use FTO/Calib/EventsPerBc for collision context --- MC/bin/o2dpg_sim_workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index f11f66863..4b330fd10 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -672,10 +672,10 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): f'--timestamp {args.timestamp}', f'--import-external {args.data_anchoring}' if len(args.data_anchoring) > 0 else None, '--bcPatternFile ccdb', + ' --nontrivial-mu-distribution ccdb://https://alice-ccdb.cern.ch/FTO/Calib/EventsPerBc', f'--QEDinteraction {qedspec}' if includeQED else None ], configname = 'precollcontext') workflow['stages'].append(PreCollContextTask) -#TODO: in future add standard ' --nontrivial-mu-distribution ccdb://http://ccdb-test.cern.ch:8080/GLO/CALIB/EVSELQA/HBCTVX' if doembedding: if not usebkgcache: From 9c78c06f302994d4f4ceb940f85f5dcd33f70f96 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Mon, 4 May 2026 14:09:49 +0200 Subject: [PATCH 310/362] AODBcRewriter: fix MC particle intra-table index remapping after reorder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the patched version with a full refactor that fixes a critical correctness bug introduced by commit 95cc50b4dc ("Fix concatenation for McCollisions indexed Trees"). Problem ------- Stage 2 was added to reorder every table carrying fIndexMcCollisions (including O2mcparticle) so that rows are grouped by their new MC-collision parent. The fIndexMcCollisions column was correctly remapped, but two other index columns inside O2mcparticle were left untouched: • fIndexArray_Mothers — VLA of Int_t pointing to mother particles within the same O2mcparticle table • fIndexSlice_Daughters — fixed [2] array of Int_t giving the [first, last] daughter slice in the same table After reordering, these columns still held old row positions. The pointed-to rows now belonged to different MC collisions, producing structurally invalid output verified by 267,605 cross-collision violations in the example AO2D. O2Physics detected this at analysis time as: [FATAL] MC particle N with PDG P has daughter with index M > MC particle table size (+ offset) Additionally, label tables (O2mctracklabel, O2mcfwdtracklabel, O2mcmfttracklabel, O2mccalolabel) carry fIndexMcParticles / fIndexArrayMcParticles pointing into O2mcparticle. After O2mcparticle is reordered those pointers became stale; they were also not remapped. A latent memory-safety bug was also present: fIndexSlice_Daughters is stored as a fixed-size branch with leaf title fIndexSlice_Daughters[2] (8 bytes), but the generic branch I/O code allocated only 4 bytes for it (treating it as a plain scalar), causing a silent out-of-bounds write on every GetEntry call. Changes ------- 1. BranchDesc gains nElems (= leaf->GetLen()), so the I/O buffer is sized nElems * elemSize for fixed-size arrays as well as scalars. This fixes the fIndexSlice_Daughters buffer underallocation. 2. A new ExtraRemap struct and an extraRemaps parameter on rewriteTable() allow any number of additional integer columns to be remapped in-place within the same write pass. Each extra remap applies remapIdx() to every Int_t value in the branch (scalar, fixed array, or VLA) after GetEntry and before Fill, using the caller-supplied PermMap. 3. In stage2_MCCollIndexedTables, when processing O2mcparticle: - The self-permutation (oldRow → newRow) is computed from rowOrder before calling rewriteTable — this is exact because rowOrder contains unique source rows in output order. - fIndexArray_Mothers and fIndexSlice_Daughters are passed as ExtraRemaps using this self-permutation. The stable sort by new MC-collision position preserves the original within-collision particle order, so daughter slices remain contiguous and remapping [first, last] via the same permutation is correct. 4. processPasteJoinTables now locates the MC-particle permutation in allPerms and builds ExtraRemaps for fIndexMcParticles and fIndexArrayMcParticles in any table that carries those branches. Tables that need only index remapping (no row reordering) are processed with an identity rowOrder via rewriteTable instead of CloneTree. 5. A new AODBcRewriterValidate(fname) function (callable as a standalone ROOT macro) checks: - BC table is strictly monotonic in fGlobalBC. - All fIndexSlice_Daughters values are in [0, nMcParticle) and point to particles sharing the same fIndexMcCollisions as the parent row. - All fIndexArray_Mothers values satisfy the same constraints. Returns true/false and prints [FAIL] lines for each failing DF. Verification ------------ Validated on example_AOD/AO2D_pre.root (merged, pre-rewrite): AODBcRewriterValidate reports PASSED — confirms input was clean. Old rewriter output (AO2D_after.root): AODBcRewriterValidate reports FAILED — 267,605 cross-collision violations in DF_3594457012001 and DF_3594457012003. New rewriter output: AODBcRewriterValidate reports PASSED (3 DFs checked) — zero violations. Co-Authored-By: Claude Opus 4.7 --- MC/utils/AODBcRewriter.C | 2008 +++++++++++++++++++------------------- 1 file changed, 1004 insertions(+), 1004 deletions(-) diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C index f5d3f19ec..c8b5cd6df 100644 --- a/MC/utils/AODBcRewriter.C +++ b/MC/utils/AODBcRewriter.C @@ -1,1163 +1,1163 @@ // AODBcRewriter.C -// Usage: root -l -b -q 'AODBcRewriter.C("AO2D.root","AO2D_rewritten.root")' -// Fixes globalBC ordering and duplication problems in AO2D files; sorts and -// rewrites tables refering to the BC table generic branch code only; No -// knowledge of AOD dataformat used apart from the BC table. +// +// Usage: +// root -l -b -q 'AODBcRewriter.C("AO2D.root","AO2D_rewritten.root")' +// +// ----------------------------------------------------------------------------- +// PURPOSE +// ----------------------------------------------------------------------------- +// After merging two AO2D files the BC table (O2bc_*) can contain: +// (a) Non-monotonic fGlobalBC values — violating a framework requirement. +// (b) Duplicate fGlobalBC values — one logical BC spread across many rows. +// (c) Duplicate MCCollisions — the same MC event repeated because it +// appeared in both source files before merging. +// +// This tool fixes all three problems in one pass per DF_ directory: +// +// Stage 0 — Sort & deduplicate the BC table. Build BC permutation map: +// bcPerm[oldBCrow] = newBCrow. +// +// Stage 1 — Process every table that carries fIndexBCs / fIndexBC. +// Remap the index via bcPerm, sort rows by the new index, and +// record a permutation map for each such table so that tables +// paste-joined to it can follow. +// Special sub-case: O2mccollision_* is deduplicated here — +// rows whose (fIndexBCs, generator-level event ID) key has already +// been seen are dropped, and a FULL permutation map is produced +// (mcCollPerm[oldRow] = newRow, -1 = dropped). +// +// Stage 2 — Process every table that carries fIndexMcCollisions. +// Remap via mcCollPerm, sort, record mcCollXxxPerm if needed. +// +// Paste-join tables — tables that have NO index column but are implicitly +// joined row-for-row with another table (e.g. O2mccollisionlabel +// is paste-joined with O2collision). They must be reordered +// identically to their parent. The known paste-join relationships +// are listed in kPasteJoins below and are applied after the +// relevant stage has established the parent permutation. +// +// Unrelated tables — tables with no dependency on BCs or MCCollisions are +// copied verbatim. +// +// ----------------------------------------------------------------------------- +// DATA MODEL DEPENDENCY GRAPH (relevant subset) +// ----------------------------------------------------------------------------- +// +// BCs (O2bc_*) [Stage 0] +// │ fIndexBCs +// ├─► Collisions (O2collision_*) [Stage 1] +// │ │ paste-join ► McCollisionLabels (O2mccollisionlabel_*) +// │ │ fIndexCollisions (in tracks etc. — tracked by collPerm) +// │ └─► Tracks (O2track_*, O2trackiu_*, ...) [Stage 1] +// │ paste-join ► McTrackLabels (O2mctracklabel_*) +// │ +// └─► MCCollisions (O2mccollision_*) [Stage 1, deduplicated] +// │ fIndexMcCollisions +// ├─► HepMCXSections (O2hepmcxsection_*) [Stage 2] +// ├─► HepMCPdfInfos (O2hepmcpdfinfo_*) [Stage 2] +// └─► HepMCHeavyIons (O2hepmcheavyion_*) [Stage 2] +// +// All other tables (detector hits, ZDC, FT0, FV0, FDD, …) that carry +// fIndexBCs are handled generically in Stage 1 without special-casing. +// +// ----------------------------------------------------------------------------- #ifndef __CLING__ #include "RVersion.h" #include "TBranch.h" -#include "TBufferFile.h" -#include "TClass.h" #include "TDirectory.h" #include "TFile.h" #include "TKey.h" #include "TLeaf.h" -#include "TList.h" #include "TMap.h" -#include "TObjString.h" #include "TROOT.h" #include "TString.h" #include "TTree.h" - #include -#include #include +#include #include -#include +#include #include #include -#include #include #include #include #include #endif -// ----------------- small helpers ----------------- -static inline bool isDF(const char *name) { - return TString(name).BeginsWith("DF_"); +// ============================================================================ +// SECTION 1 — Types and small helpers +// ============================================================================ + +// A permutation map: permMap[oldRow] = newRow, -1 means "row was dropped". +using PermMap = std::vector; + +// Convenience: build an identity permutation of length n. +static PermMap identityPerm(Long64_t n) { + PermMap p(n); + std::iota(p.begin(), p.end(), 0); + return p; } -static inline bool isBCtree(const char *tname) { - return TString(tname).BeginsWith("O2bc_"); + +// Names of tables that begin with these prefixes are BC tables or flag tables +// and are handled specially in Stage 0. +static bool isBCTable(const char *name) { + return TString(name).BeginsWith("O2bc"); } -static inline bool isFlagsTree(const char *tname) { - return TString(tname) == "O2bcflag" || TString(tname) == "O2bcflags" || - TString(tname).BeginsWith("O2bcflag"); + +static bool isDF(const char *name) { + return TString(name).BeginsWith("DF_"); } -static const char *findIndexBranchName(TTree *t) { - if (!t) - return nullptr; - if (t->GetBranch("fIndexBCs")) - return "fIndexBCs"; - if (t->GetBranch("fIndexBC")) - return "fIndexBC"; + +// Return the name of the BC index branch if present, else nullptr. +static const char *bcIndexBranch(TTree *t) { + if (!t) return nullptr; + if (t->GetBranch("fIndexBCs")) return "fIndexBCs"; + if (t->GetBranch("fIndexBC")) return "fIndexBC"; return nullptr; } -static const char *findMcCollisionIndexBranchName(TTree *t) { - if (!t) - return nullptr; - if (t->GetBranch("fIndexMcCollisions")) - return "fIndexMcCollisions"; +// Return the name of the MCCollision index branch if present, else nullptr. +static const char *mcCollIndexBranch(TTree *t) { + if (!t) return nullptr; + if (t->GetBranch("fIndexMcCollisions")) return "fIndexMcCollisions"; return nullptr; } -static inline bool isMcCollisionTree(const char *tname) { - return TString(tname).BeginsWith("O2mccollision"); +// Return the name of the Collision index branch if present, else nullptr. +static const char *collIndexBranch(TTree *t) { + if (!t) return nullptr; + if (t->GetBranch("fIndexCollisions")) return "fIndexCollisions"; + return nullptr; } -// Scalar type tag +// ============================================================================ +// SECTION 2 — Generic ROOT branch I/O helpers +// ============================================================================ +// +// AO2D branches store plain scalar values (Int_t, ULong64_t, Float_t, …) or +// variable-length arrays (VLAs). We need to read and write them generically +// without knowing the concrete type at compile time. The trick is to allocate +// a raw byte buffer of the right size, set the branch address to it, and use +// the ScalarTag enum to know how to interpret it when we need to (e.g. for +// index remapping). + enum class ScalarTag { - kInt, - kUInt, - kShort, - kUShort, - kLong64, - kULong64, - kFloat, - kDouble, - kChar, - kUChar, - kBool, - kUnknown + kInt, kUInt, kShort, kUShort, kLong64, kULong64, + kFloat, kDouble, kChar, kUChar, kBool, kUnknown }; -static ScalarTag leafType(TLeaf *leaf) { - if (!leaf) - return ScalarTag::kUnknown; - TString tn = leaf->GetTypeName(); - if (tn == "Int_t") - return ScalarTag::kInt; - if (tn == "UInt_t") - return ScalarTag::kUInt; - if (tn == "Short_t") - return ScalarTag::kShort; - if (tn == "UShort_t") - return ScalarTag::kUShort; - if (tn == "Long64_t") - return ScalarTag::kLong64; - if (tn == "ULong64_t") - return ScalarTag::kULong64; - if (tn == "Float_t") - return ScalarTag::kFloat; - if (tn == "Double_t") - return ScalarTag::kDouble; - if (tn == "Char_t") - return ScalarTag::kChar; - if (tn == "UChar_t") - return ScalarTag::kUChar; - if (tn == "Bool_t") - return ScalarTag::kBool; + +static ScalarTag tagOf(TLeaf *leaf) { + if (!leaf) return ScalarTag::kUnknown; + TString t = leaf->GetTypeName(); + if (t == "Int_t") return ScalarTag::kInt; + if (t == "UInt_t") return ScalarTag::kUInt; + if (t == "Short_t") return ScalarTag::kShort; + if (t == "UShort_t") return ScalarTag::kUShort; + if (t == "Long64_t") return ScalarTag::kLong64; + if (t == "ULong64_t") return ScalarTag::kULong64; + if (t == "Float_t") return ScalarTag::kFloat; + if (t == "Double_t") return ScalarTag::kDouble; + if (t == "Char_t") return ScalarTag::kChar; + if (t == "UChar_t") return ScalarTag::kUChar; + if (t == "Bool_t") return ScalarTag::kBool; return ScalarTag::kUnknown; } -static size_t scalarSize(ScalarTag t) { + +static size_t byteSize(ScalarTag t) { switch (t) { - case ScalarTag::kInt: - return sizeof(Int_t); - case ScalarTag::kUInt: - return sizeof(UInt_t); - case ScalarTag::kShort: - return sizeof(Short_t); - case ScalarTag::kUShort: - return sizeof(UShort_t); - case ScalarTag::kLong64: - return sizeof(Long64_t); - case ScalarTag::kULong64: - return sizeof(ULong64_t); - case ScalarTag::kFloat: - return sizeof(Float_t); - case ScalarTag::kDouble: - return sizeof(Double_t); - case ScalarTag::kChar: - return sizeof(Char_t); - case ScalarTag::kUChar: - return sizeof(UChar_t); - case ScalarTag::kBool: - return sizeof(Bool_t); - default: - return 0; + case ScalarTag::kInt: return sizeof(Int_t); + case ScalarTag::kUInt: return sizeof(UInt_t); + case ScalarTag::kShort: return sizeof(Short_t); + case ScalarTag::kUShort: return sizeof(UShort_t); + case ScalarTag::kLong64: return sizeof(Long64_t); + case ScalarTag::kULong64: return sizeof(ULong64_t); + case ScalarTag::kFloat: return sizeof(Float_t); + case ScalarTag::kDouble: return sizeof(Double_t); + case ScalarTag::kChar: return sizeof(Char_t); + case ScalarTag::kUChar: return sizeof(UChar_t); + case ScalarTag::kBool: return sizeof(Bool_t); + default: return 0; } } -// small Buffer base for lifetime management -struct BufBase { - virtual ~BufBase() {} - virtual void *ptr() = 0; -}; -template struct ScalarBuf : BufBase { - T v; - void *ptr() override { return &v; } -}; -template struct ArrayBuf : BufBase { - std::vector a; - void *ptr() override { return a.data(); } -}; +// Read an integer value from a raw buffer regardless of its stored type. +// Used to extract index values (fIndexBCs etc.) from their buffers. +static Long64_t readAsInt(const void *buf, ScalarTag tag) { + switch (tag) { + case ScalarTag::kInt: return *static_cast(buf); + case ScalarTag::kUInt: return *static_cast(buf); + case ScalarTag::kShort: return *static_cast(buf); + case ScalarTag::kUShort: return *static_cast(buf); + case ScalarTag::kLong64: return *static_cast(buf); + case ScalarTag::kULong64: return (Long64_t)*static_cast(buf); + default: return -1; + } +} -template static std::unique_ptr makeScalarBuf() { - return std::make_unique>(); +// Write an integer value into a raw buffer. +static void writeAsInt(void *buf, ScalarTag tag, Long64_t val) { + switch (tag) { + case ScalarTag::kInt: *static_cast(buf) = (Int_t)val; break; + case ScalarTag::kUInt: *static_cast(buf) = (UInt_t)val; break; + case ScalarTag::kShort: *static_cast(buf) = (Short_t)val; break; + case ScalarTag::kUShort: *static_cast(buf) = (UShort_t)val; break; + case ScalarTag::kLong64: *static_cast(buf) = (Long64_t)val; break; + default: break; + } } -template static std::unique_ptr makeArrayBuf(size_t n) { - auto p = std::make_unique>(); - if (n == 0) - n = 1; - p->a.resize(n); - return p; + +// Remap a single Int_t index value through a PermMap. Returns -1 for any +// out-of-range or already-invalid (negative) value. +static Int_t remapIdx(Int_t val, const PermMap &perm) { + if (val < 0 || (size_t)val >= perm.size()) return -1; + return perm[(size_t)val]; } -// prescan the count branch to determine max length for a VLA -static Long64_t prescanMaxLen(TTree *src, TBranch *countBr, - ScalarTag countTag) { - if (!countBr) - return 1; - // temporary buffer - std::unique_ptr tmp; - switch (countTag) { - case ScalarTag::kInt: - tmp = makeScalarBuf(); - break; - case ScalarTag::kUInt: - tmp = makeScalarBuf(); - break; - case ScalarTag::kShort: - tmp = makeScalarBuf(); - break; - case ScalarTag::kUShort: - tmp = makeScalarBuf(); - break; - case ScalarTag::kLong64: - tmp = makeScalarBuf(); - break; - case ScalarTag::kULong64: - tmp = makeScalarBuf(); - break; - default: - tmp = makeScalarBuf(); - break; +// A description of one branch in a tree: its name, scalar type tag, byte +// size, and whether it is a VLA (variable-length array). For VLAs we also +// keep the name of the count branch and the maximum observed element count +// (needed for buffer sizing). +struct BranchDesc { + std::string name; + ScalarTag tag = ScalarTag::kUnknown; + size_t elemSize = 0; // byte size of one element + int nElems = 1; // >1 for fixed-size arrays (e.g. fIndexSlice_Daughters[2]) + bool isVLA = false; + std::string countBranchName; // only for VLAs + Long64_t maxElems = 1; // only for VLAs +}; + +// Scan all branches of a tree and return their descriptors. Count branches +// for VLAs are represented only once (as the count side of the data branch) +// and are marked so they don't also appear as standalone entries. +static std::vector describeBranches(TTree *tree) { + std::vector result; + std::unordered_set countBranchNames; + + // First pass: identify all count branches for VLAs + for (auto *obj : *tree->GetListOfBranches()) { + TBranch *br = static_cast(obj); + TLeaf *leaf = static_cast(br->GetListOfLeaves()->At(0)); + if (!leaf) continue; + if (TLeaf *cnt = leaf->GetLeafCount()) + countBranchNames.insert(cnt->GetBranch()->GetName()); } - countBr->SetAddress(tmp->ptr()); - Long64_t maxLen = 0; - Long64_t nEnt = src->GetEntries(); - for (Long64_t i = 0; i < nEnt; ++i) { - countBr->GetEntry(i); - Long64_t v = 0; - switch (countTag) { - case ScalarTag::kInt: - v = *(Int_t *)tmp->ptr(); - break; - case ScalarTag::kUInt: - v = *(UInt_t *)tmp->ptr(); - break; - case ScalarTag::kShort: - v = *(Short_t *)tmp->ptr(); - break; - case ScalarTag::kUShort: - v = *(UShort_t *)tmp->ptr(); - break; - case ScalarTag::kLong64: - v = *(Long64_t *)tmp->ptr(); - break; - case ScalarTag::kULong64: - v = *(ULong64_t *)tmp->ptr(); - break; - default: - v = *(Int_t *)tmp->ptr(); - break; + + // Second pass: build descriptors + for (auto *obj : *tree->GetListOfBranches()) { + TBranch *br = static_cast(obj); + std::string bname = br->GetName(); + TLeaf *leaf = static_cast(br->GetListOfLeaves()->At(0)); + if (!leaf) { std::cerr << " [warn] branch without leaf: " << bname << "\n"; continue; } + + BranchDesc d; + d.name = bname; + d.tag = tagOf(leaf); + + if (TLeaf *cnt = leaf->GetLeafCount()) { + // This is a VLA data branch + d.isVLA = true; + d.countBranchName = cnt->GetBranch()->GetName(); + d.tag = tagOf(leaf); + d.elemSize = byteSize(d.tag); + + // Pre-scan to find the maximum array length (needed for buffer) + TBranch *cntBr = cnt->GetBranch(); + ScalarTag cntTag = tagOf(cnt); + size_t cntSz = byteSize(cntTag); + if (cntSz == 0) { std::cerr << " [warn] VLA count branch has unknown type: " << bname << "\n"; continue; } + std::vector cntBuf(cntSz, 0); + cntBr->SetAddress(cntBuf.data()); + Long64_t maxLen = 1; + for (Long64_t i = 0; i < tree->GetEntries(); ++i) { + cntBr->GetEntry(i); + Long64_t v = readAsInt(cntBuf.data(), cntTag); + if (v > maxLen) maxLen = v; + } + d.maxElems = maxLen; + + } else if (countBranchNames.count(bname)) { + // This is a count branch — skip it here; handled together with its VLA + continue; + } else { + // Plain scalar or fixed-size array branch (e.g. fIndexSlice_Daughters[2]) + d.isVLA = false; + d.elemSize = byteSize(d.tag); + d.nElems = leaf->GetLen(); // 1 for scalars, >1 for fixed arrays + if (d.elemSize == 0) { + std::cerr << " [warn] branch " << bname << " has unknown type " + << leaf->GetTypeName() << " — will be skipped\n"; + continue; + } } - if (v > maxLen) - maxLen = v; + result.push_back(std::move(d)); } - return maxLen; + return result; } -// bind scalar branch (in and out share same buffer) -static std::unique_ptr bindScalarBranch(TBranch *inBr, TBranch *outBr, - ScalarTag tag) { - switch (tag) { - case ScalarTag::kInt: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kUInt: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kShort: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kUShort: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kLong64: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kULong64: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kFloat: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kDouble: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; - } - case ScalarTag::kChar: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; +// ============================================================================ +// SECTION 3 — Table rewriting engine +// ============================================================================ +// +// rewriteTable() is the single generic function that handles any table. +// It takes: +// - src : the source TTree +// - dirOut : directory to write the output TTree into +// - rowOrder : which source rows to include and in what order +// (a vector of source row indices, possibly a subset) +// - indexBranch : name of the index branch to remap, or "" if none +// - parentPerm : PermMap for remapping that index (may be empty) +// - extraRemaps : additional index columns to remap in-place via their own +// PermMaps (used for intra-table and cross-table indices +// that are not the primary sort key, e.g. mother/daughter +// indices in O2mcparticle or fIndexMcParticles in labels) +// +// It returns the permutation of source rows implied by rowOrder, expressed +// as a PermMap: perm[srcRow] = outputRow, -1 if the row was dropped. + +// Describes one extra index column to remap independently of the sort key. +struct ExtraRemap { + std::string branchName; // branch whose integer values to remap + const PermMap *perm; // remapping table: newVal = (*perm)[oldVal] +}; + +static PermMap rewriteTable(TTree *src, TDirectory *dirOut, + const std::vector &rowOrder, + const std::string &indexBranch, + const PermMap &parentPerm, + const std::vector &extraRemaps = {}) { + + Long64_t nSrc = src->GetEntries(); + + // Build the inverse permutation (srcRow → outRow) from rowOrder + PermMap srcToOut(nSrc, -1); + for (Long64_t outRow = 0; outRow < (Long64_t)rowOrder.size(); ++outRow) + srcToOut[rowOrder[outRow]] = (Int_t)outRow; + + // Describe all branches + auto descs = describeBranches(src); + + // Allocate raw buffers: for each branch one buffer (for VLAs: data buffer + // sized maxElems * elemSize, plus a separate count buffer). + // We use a std::vector per branch (automatically memory-safe). + struct BranchIO { + BranchDesc desc; + std::vector dataBuf; // scalar: elemSize bytes; VLA: maxElems*elemSize bytes + std::vector countBuf; // VLA only + ScalarTag countTag = ScalarTag::kUnknown; + TBranch *inBr = nullptr; + TBranch *inCntBr = nullptr; + }; + std::vector ios; + ios.reserve(descs.size()); + + for (auto &d : descs) { + BranchIO io; + io.desc = d; + if (!d.isVLA) { + // Allocate for all elements (nElems>1 for fixed arrays like fIndexSlice_Daughters[2]) + io.dataBuf.assign(d.nElems * d.elemSize, 0); + } else { + io.dataBuf.assign(d.maxElems * d.elemSize, 0); + TBranch *cntBr = src->GetBranch(d.countBranchName.c_str()); + TLeaf *cntLeaf = cntBr ? static_cast(cntBr->GetListOfLeaves()->At(0)) : nullptr; + io.countTag = cntLeaf ? tagOf(cntLeaf) : ScalarTag::kUnknown; + io.countBuf.assign(byteSize(io.countTag), 0); + io.inCntBr = cntBr; + } + io.inBr = src->GetBranch(d.name.c_str()); + ios.push_back(std::move(io)); } - case ScalarTag::kUChar: { - auto b = makeScalarBuf(); - inBr->SetAddress(b->ptr()); - outBr->SetAddress(b->ptr()); - return b; + + // Set input branch addresses + for (auto &io : ios) { + if (io.inBr) io.inBr->SetAddress(io.dataBuf.data()); + if (io.inCntBr) io.inCntBr->SetAddress(io.countBuf.data()); } - default: - return nullptr; + + // Create output tree and set output branch addresses. + // We clone the tree structure (no entries) and reset addresses. + dirOut->cd(); + TTree *out = src->CloneTree(0, "fast"); + + // Find the index branch (if any) — we will update its value on the fly + ScalarTag idxTag = ScalarTag::kUnknown; + std::vector newIdxBuf; + TBranch *outIdxBr = nullptr; + if (!indexBranch.empty()) { + TBranch *inIdxBr = src->GetBranch(indexBranch.c_str()); + TLeaf *idxLeaf = inIdxBr ? static_cast(inIdxBr->GetListOfLeaves()->At(0)) : nullptr; + idxTag = idxLeaf ? tagOf(idxLeaf) : ScalarTag::kUnknown; + if (idxTag != ScalarTag::kUnknown) { + newIdxBuf.assign(byteSize(idxTag), 0); + outIdxBr = out->GetBranch(indexBranch.c_str()); + if (outIdxBr) outIdxBr->SetAddress(newIdxBuf.data()); + } } -} -// bind VLA typed: returns data buffer and outputs count buffer (via -// outCountBuf) -template -static std::unique_ptr -bindArrayTyped(TBranch *inData, TBranch *outData, TBranch *inCount, - TBranch *outCount, ScalarTag countTag, Long64_t maxLen, - std::unique_ptr &outCountBuf) { - // create count buffer - std::unique_ptr countBuf; - switch (countTag) { - case ScalarTag::kInt: - countBuf = makeScalarBuf(); - break; - case ScalarTag::kUInt: - countBuf = makeScalarBuf(); - break; - case ScalarTag::kShort: - countBuf = makeScalarBuf(); - break; - case ScalarTag::kUShort: - countBuf = makeScalarBuf(); - break; - case ScalarTag::kLong64: - countBuf = makeScalarBuf(); - break; - case ScalarTag::kULong64: - countBuf = makeScalarBuf(); - break; - default: - countBuf = makeScalarBuf(); - break; + // Set all other output branch addresses to the same data buffers as input + for (auto &io : ios) { + if (io.desc.name == indexBranch) continue; // handled separately above + TBranch *outBr = out->GetBranch(io.desc.name.c_str()); + if (!outBr) { std::cerr << " [warn] no output branch for " << io.desc.name << "\n"; continue; } + outBr->SetAddress(io.dataBuf.data()); + if (io.desc.isVLA) { + TBranch *outCntBr = out->GetBranch(io.desc.countBranchName.c_str()); + if (outCntBr) outCntBr->SetAddress(io.countBuf.data()); + } } - // data buffer (allocate maxLen) - auto dataBuf = makeArrayBuf((size_t)std::max(1, maxLen)); - inCount->SetAddress(countBuf->ptr()); - outCount->SetAddress(countBuf->ptr()); - inData->SetAddress(dataBuf->ptr()); - outData->SetAddress(dataBuf->ptr()); + // Fill the output tree row by row in the requested order + Long64_t nRemapped = 0; + for (Long64_t srcRow : rowOrder) { + src->GetEntry(srcRow); + + // Remap the index branch if required + if (outIdxBr && idxTag != ScalarTag::kUnknown && !parentPerm.empty()) { + // Read old index from the input branch's buffer (one of the ios entries) + Long64_t oldIdx = -1; + for (auto &io : ios) { + if (io.desc.name == indexBranch) { oldIdx = readAsInt(io.dataBuf.data(), idxTag); break; } + } + Long64_t newIdx = -1; + if (oldIdx >= 0 && oldIdx < (Long64_t)parentPerm.size()) + newIdx = parentPerm[oldIdx]; + writeAsInt(newIdxBuf.data(), idxTag, newIdx >= 0 ? newIdx : -1); + if (newIdx != oldIdx) ++nRemapped; + } - outCountBuf = std::move(countBuf); - return dataBuf; + // Apply extra in-place index remaps (e.g. intra-table mother/daughter + // indices in O2mcparticle, or fIndexMcParticles in label tables). + // The output branch shares the same buffer, so modifying dataBuf here + // is read by out->Fill() below. + for (auto &er : extraRemaps) { + for (auto &io : ios) { + if (io.desc.name != er.branchName) continue; + if (io.desc.isVLA) { + // VLA: remap each element according to count + Long64_t cnt = readAsInt(io.countBuf.data(), io.countTag); + auto *p = reinterpret_cast(io.dataBuf.data()); + for (Long64_t j = 0; j < cnt; ++j) + p[j] = remapIdx(p[j], *er.perm); + } else { + // Scalar or fixed-size array: remap all nElems integers + auto *p = reinterpret_cast(io.dataBuf.data()); + for (int j = 0; j < io.desc.nElems; ++j) + p[j] = remapIdx(p[j], *er.perm); + } + break; + } + } + + out->Fill(); + } + + std::cout << " wrote " << out->GetEntries() << " / " << nSrc + << " rows; " << nRemapped << " index values remapped\n"; + out->Write(); + return srcToOut; } -// ----------------- BC maps builder ----------------- -struct BCMaps { - std::vector originalBCs; - std::vector indexMap; - std::vector uniqueBCs; - std::unordered_map> newIndexOrigins; +// ============================================================================ +// SECTION 4 — Stage 0: BC table sort + deduplication +// ============================================================================ +// +// Reads fGlobalBC from the BC tree, sorts rows, drops exact-duplicate BC +// values, and writes the compacted table. Returns bcPerm[oldRow] = newRow. - // McCollision scheme (populated when O2mccollision is sorted) during first stage - std::vector mcOldEntries; - std::vector mcNewEntries; +struct BCStage0Result { + PermMap bcPerm; // bcPerm[oldRow] = newRow in sorted/deduped BC table + Long64_t nUnique = 0; }; -static BCMaps buildBCMaps(TTree *treeBCs) { - BCMaps maps; - if (!treeBCs) - return maps; - TBranch *br = treeBCs->GetBranch("fGlobalBC"); - if (!br) { - std::cerr << "ERROR: no fGlobalBC\n"; - return maps; - } - ULong64_t v = 0; - br->SetAddress(&v); +static BCStage0Result stage0_sortBCs(TTree *treeBCs, TDirectory *dirOut) { + BCStage0Result res; Long64_t n = treeBCs->GetEntries(); - maps.originalBCs.reserve(n); - for (Long64_t i = 0; i < n; ++i) { - treeBCs->GetEntry(i); - maps.originalBCs.push_back(v); - } + if (n == 0) return res; - std::vector order(n); + TBranch *brGBC = treeBCs->GetBranch("fGlobalBC"); + if (!brGBC) { std::cerr << "ERROR: O2bc_* tree has no fGlobalBC branch!\n"; return res; } + + ULong64_t gbc = 0; + brGBC->SetAddress(&gbc); + std::vector gbcs(n); + for (Long64_t i = 0; i < n; ++i) { treeBCs->GetEntry(i); gbcs[i] = gbc; } + + // Sort row indices by fGlobalBC + std::vector order(n); std::iota(order.begin(), order.end(), 0); - std::sort(order.begin(), order.end(), [&](size_t a, size_t b) { - return maps.originalBCs[a] < maps.originalBCs[b]; - }); + std::stable_sort(order.begin(), order.end(), + [&](Long64_t a, Long64_t b){ return gbcs[a] < gbcs[b]; }); - maps.indexMap.assign(n, -1); - Int_t newIdx = -1; + // Build deduplicated row list and the permutation + res.bcPerm.assign(n, -1); + std::vector rowOrder; // source rows to keep, in output order ULong64_t prev = ULong64_t(-1); - for (auto oldIdx : order) { - ULong64_t val = maps.originalBCs[oldIdx]; - if (newIdx < 0 || val != prev) { - ++newIdx; - prev = val; - maps.uniqueBCs.push_back(val); + Int_t newRow = -1; + for (Long64_t srcRow : order) { + if (gbcs[srcRow] != prev) { + ++newRow; + prev = gbcs[srcRow]; + rowOrder.push_back(srcRow); } - maps.indexMap[oldIdx] = newIdx; - maps.newIndexOrigins[newIdx].push_back(oldIdx); + // All rows with the same globalBC map to the same new row (deduplication) + res.bcPerm[srcRow] = newRow; } - std::cout << " BCMaps: oldEntries=" << n - << " unique=" << maps.uniqueBCs.size() << "\n"; - return maps; -} + res.nUnique = rowOrder.size(); -// ----------------- small helper used for BC/flags copy ----------------- -/* - copyTreeSimple: - - inTree: input tree (assumed POD-only of types Int_t, ULong64_t, UChar_t) - - entryMap: list of input-entry indices to use, in desired output order; - (size_t)-1 entries are skipped - - outName: name for the output tree -*/ -static TTree *copyTreeSimple(TTree *inTree, const std::vector &entryMap, - const char *outName = nullptr) { - if (!inTree) - return nullptr; - TString tname = outName ? outName : inTree->GetName(); - TTree *outTree = new TTree(tname, "rebuilt tree"); - - std::vector inBufs, outBufs; - std::vector inBranches; - std::vector types; - std::vector leafCodes; - std::vector bnames; - - for (auto brObj : *inTree->GetListOfBranches()) { - TBranch *br = (TBranch *)brObj; - TString bname = br->GetName(); - TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); - if (!leaf) - continue; - TString type = leaf->GetTypeName(); - - void *inBuf = nullptr; - void *outBuf = nullptr; - TString leafCode; - - if (type == "Int_t") { - inBuf = new Int_t; - outBuf = new Int_t; - leafCode = "I"; - } else if (type == "ULong64_t") { - inBuf = new ULong64_t; - outBuf = new ULong64_t; - leafCode = "l"; - } else if (type == "UChar_t") { - inBuf = new UChar_t; - outBuf = new UChar_t; - leafCode = "b"; - } else { - std::cerr << "Unsupported branch type " << type << " in " - << inTree->GetName() << " branch " << bname << " — skipping\n"; - continue; - } + std::cout << " BC stage: " << n << " rows -> " << res.nUnique << " unique\n"; - br->SetAddress(inBuf); - outTree->Branch(bname, outBuf, bname + "/" + leafCode); + // Write the BC table (no index remapping needed for the table itself) + rewriteTable(treeBCs, dirOut, rowOrder, /*indexBranch=*/"", /*parentPerm=*/{}); - inBufs.push_back(inBuf); - outBufs.push_back(outBuf); - inBranches.push_back(br); - types.push_back(type); - leafCodes.push_back(leafCode); - bnames.push_back(bname); - } + return res; +} - // fill using entryMap (representative input indices) - for (size_t idx : entryMap) { - if (idx == (size_t)-1) - continue; - inTree->GetEntry((Long64_t)idx); - for (size_t ib = 0; ib < inBranches.size(); ++ib) { - if (types[ib] == "Int_t") - *(Int_t *)outBufs[ib] = *(Int_t *)inBufs[ib]; - else if (types[ib] == "ULong64_t") - *(ULong64_t *)outBufs[ib] = *(ULong64_t *)inBufs[ib]; - else if (types[ib] == "UChar_t") - *(UChar_t *)outBufs[ib] = *(UChar_t *)inBufs[ib]; - } - outTree->Fill(); +// ============================================================================ +// SECTION 5 — Stage 0b: BC flags table (follows BC row order exactly) +// ============================================================================ + +static void stage0_copyBCFlags(TTree *treeFlags, TDirectory *dirOut, + const PermMap &bcPerm) { + if (!treeFlags) return; + Long64_t nSrc = treeFlags->GetEntries(); + + // Build rowOrder: for each unique output BC row, pick the first source row + // that mapped to it + std::vector rowOrder; + std::map first; // newBCrow -> first srcRow + for (Long64_t i = 0; i < (Long64_t)bcPerm.size(); ++i) + if (bcPerm[i] >= 0) first.emplace(bcPerm[i], i); // emplace keeps first + rowOrder.reserve(first.size()); + for (auto &kv : first) rowOrder.push_back(kv.second); + + rewriteTable(treeFlags, dirOut, rowOrder, /*indexBranch=*/"", /*parentPerm=*/{}); +} + +// ============================================================================ +// SECTION 6 — Stage 1: Tables indexed by BCs (generic + MCCollisions special) +// ============================================================================ +// +// Returns a map: treeName -> PermMap, containing the row permutation for +// every table processed at this stage. Callers use this for paste-joined +// tables and for Stage 2. + +// Key used to detect duplicate MCCollisions. +// +// Two MCCollision rows are considered identical when BOTH of the following hold: +// 1. They map to the same BC row after remapping (same globalBC). +// 2. They carry the same fEventWeight value. +// +// fEventWeight is a float written by the generator for every event and is +// unique enough (in combination with the BC) to distinguish distinct events +// from the same generator that happen to land in the same BC. +// +// IMPORTANT: if fEventWeight is absent from the tree we do NOT deduplicate at +// all, because we have no reliable way to distinguish distinct events that share +// the same BC. Deduplicating on BC alone would incorrectly merge different MC +// events that were placed in the same bunch crossing. +struct MCCollKey { + Long64_t newBCrow; + Float_t weight; + bool operator==(const MCCollKey &o) const { + return newBCrow == o.newBCrow && weight == o.weight; + } +}; +struct MCCollKeyHash { + size_t operator()(const MCCollKey &k) const { + size_t h1 = std::hash{}(k.newBCrow); + // Bit-cast float to uint32 for hashing — avoids UB and NaN weirdness + uint32_t wbits; + std::memcpy(&wbits, &k.weight, sizeof(wbits)); + return h1 ^ (size_t(wbits) << 32) ^ size_t(wbits); } +}; - return outTree; -} +static std::unordered_map +stage1_BCindexedTables(TDirectory *dirIn, TDirectory *dirOut, + const PermMap &bcPerm) { + std::unordered_map tablePerms; -// ----------------- Rebuild BCs and Flags (refactored) ----------------- -void rebuildBCsAndFlags(TDirectory *dirIn, TDirectory *dirOut, TTree *&outBCs, - BCMaps &maps) { - std::cout << "------------------------------------------------\n"; - std::cout << "Rebuild BCs+flags in " << dirIn->GetName() << "\n"; + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (isBCTable(tname.c_str())) continue; // handled in stage 0 + + const char *idxBr = bcIndexBranch(src); + if (!idxBr) continue; // not BC-indexed — handled elsewhere + + std::cout << " Stage1 [BC-indexed]: " << tname << "\n"; + + Long64_t nSrc = src->GetEntries(); + + // Read all index values to build the sort order + TBranch *inIdxBr = src->GetBranch(idxBr); + TLeaf *idxLeaf = static_cast(inIdxBr->GetListOfLeaves()->At(0)); + ScalarTag idxTag = tagOf(idxLeaf); + size_t idxSz = byteSize(idxTag); + std::vector idxBuf(idxSz, 0); + inIdxBr->SetAddress(idxBuf.data()); + + // For MCCollision deduplication: also read fEventWeight if available. + // If absent, deduplication is disabled -- see MCCollKey comment for why. + bool isMCColl = TString(tname.c_str()).BeginsWith("O2mccollision"); + TBranch *wBr = isMCColl ? src->GetBranch("fEventWeight") : nullptr; + Float_t wVal = 0.f; + if (wBr) wBr->SetAddress(&wVal); + bool canDedup = isMCColl && (wBr != nullptr); + if (isMCColl && !canDedup) + std::cout << " MCCollision: fEventWeight absent -- deduplication disabled\n"; + + // Build (newBCrow, srcRow) pairs + struct SortEntry { Long64_t newBC; Long64_t srcRow; }; + std::vector entries; + entries.reserve(nSrc); + + std::unordered_set seenMCColl; + std::vector keep(nSrc, true); + + for (Long64_t i = 0; i < nSrc; ++i) { + inIdxBr->GetEntry(i); + if (wBr) wBr->GetEntry(i); + Long64_t oldBC = readAsInt(idxBuf.data(), idxTag); + Long64_t newBC = (oldBC >= 0 && oldBC < (Long64_t)bcPerm.size()) + ? bcPerm[oldBC] : -1; + + if (canDedup) { + // Deduplication: drop rows with a (newBC, weight) pair seen before. + // First occurrence in source row order is kept. + MCCollKey k{newBC, wVal}; + if (!seenMCColl.insert(k).second) { + keep[i] = false; + } + } + entries.push_back({newBC, i}); + } - // find O2bc_* (pick first matching) and O2bcflag - TTree *treeBCs = nullptr; - TTree *treeFlags = nullptr; + // Stable-sort by newBC (invalid = -1 sink to end) + std::stable_sort(entries.begin(), entries.end(), + [](const SortEntry &a, const SortEntry &b){ + if (a.newBC < 0 && b.newBC >= 0) return false; + if (a.newBC >= 0 && b.newBC < 0) return true; + return a.newBC < b.newBC; + }); + + // Build rowOrder, respecting the keep[] mask for MCCollisions + std::vector rowOrder; + rowOrder.reserve(nSrc); + for (auto &e : entries) { + if (keep[e.srcRow]) rowOrder.push_back(e.srcRow); + } - for (auto keyObj : *dirIn->GetListOfKeys()) { - TKey *key = (TKey *)keyObj; - TObject *obj = dirIn->Get(key->GetName()); - if (!obj) - continue; - if (!obj->InheritsFrom(TTree::Class())) - continue; - TTree *t = (TTree *)obj; - if (isBCtree(t->GetName())) { - treeBCs = t; - } else if (isFlagsTree(t->GetName())) { - treeFlags = t; + if (isMCColl) { + Long64_t dropped = nSrc - (Long64_t)rowOrder.size(); + std::cout << " MCCollision dedup: dropped " << dropped + << " duplicate rows (" << rowOrder.size() << " kept)\n"; } - } - if (!treeBCs) { - std::cerr << " No BCs tree found in " << dirIn->GetName() - << " — skipping\n"; - outBCs = nullptr; - return; + PermMap perm = rewriteTable(src, dirOut, rowOrder, idxBr, bcPerm); + tablePerms[tname] = std::move(perm); } + return tablePerms; +} - // build maps (dedupe/sort) - maps = buildBCMaps(treeBCs); +// ============================================================================ +// SECTION 7 — Stage 2: Tables indexed by MCCollisions +// ============================================================================ - // build representative entryMap: one input entry per new BC index (use first - // contributor) - std::vector entryMap(maps.uniqueBCs.size(), (size_t)-1); - for (size_t newIdx = 0; newIdx < maps.uniqueBCs.size(); ++newIdx) { - const auto &vec = maps.newIndexOrigins.at(newIdx); - if (!vec.empty()) - entryMap[newIdx] = vec.front(); - } +static std::unordered_map +stage2_MCCollIndexedTables(TDirectory *dirIn, TDirectory *dirOut, + const PermMap &mcCollPerm) { + std::unordered_map tablePerms; - dirOut->cd(); - // copy BCs tree using representative entries - outBCs = copyTreeSimple(treeBCs, entryMap, treeBCs->GetName()); - if (outBCs) { - outBCs->SetDirectory(dirOut); - outBCs->Write(); - std::cout << " Wrote " << outBCs->GetName() << " with " - << outBCs->GetEntries() << " entries\n"; - } + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (isBCTable(tname.c_str())) continue; + if (bcIndexBranch(src)) continue; // already handled in stage 1 + + const char *idxBr = mcCollIndexBranch(src); + if (!idxBr) continue; + + std::cout << " Stage2 [MCColl-indexed]: " << tname << "\n"; + + Long64_t nSrc = src->GetEntries(); + TBranch *inIdxBr = src->GetBranch(idxBr); + TLeaf *idxLeaf = static_cast(inIdxBr->GetListOfLeaves()->At(0)); + ScalarTag idxTag = tagOf(idxLeaf); + size_t idxSz = byteSize(idxTag); + std::vector idxBuf(idxSz, 0); + inIdxBr->SetAddress(idxBuf.data()); + + struct SortEntry { Long64_t newMCColl; Long64_t srcRow; }; + std::vector entries; + entries.reserve(nSrc); + + for (Long64_t i = 0; i < nSrc; ++i) { + inIdxBr->GetEntry(i); + Long64_t oldIdx = readAsInt(idxBuf.data(), idxTag); + Long64_t newIdx = (oldIdx >= 0 && oldIdx < (Long64_t)mcCollPerm.size()) + ? mcCollPerm[oldIdx] : -1; + entries.push_back({newIdx, i}); + } - // copy flags if present - if (treeFlags) { - TTree *outFlags = copyTreeSimple(treeFlags, entryMap, treeFlags->GetName()); - if (outFlags) { - outFlags->SetDirectory(dirOut); - outFlags->Write(); - std::cout << " Wrote " << outFlags->GetName() << " with " - << outFlags->GetEntries() << " entries\n"; + // Drop rows whose MCCollision parent was dropped (newIdx == -1 due to dedup) + // and sort the rest + std::stable_sort(entries.begin(), entries.end(), + [](const SortEntry &a, const SortEntry &b){ + if (a.newMCColl < 0 && b.newMCColl >= 0) return false; + if (a.newMCColl >= 0 && b.newMCColl < 0) return true; + return a.newMCColl < b.newMCColl; + }); + + std::vector rowOrder; + rowOrder.reserve(nSrc); + Long64_t dropped = 0; + for (auto &e : entries) { + if (e.newMCColl >= 0) rowOrder.push_back(e.srcRow); + else ++dropped; + } + if (dropped) + std::cout << " dropped " << dropped + << " rows whose MCCollision parent was deduplicated\n"; + + // For O2mcparticle: compute the self-permutation (old row -> new row) from + // the row order BEFORE calling rewriteTable, then pass it as extra remaps + // so that intra-table mother/daughter indices are updated in the same pass. + // The stable sort above preserves within-collision particle order, which + // keeps fIndexSlice_Daughters contiguous — so remapping [first,last] via + // selfPerm is correct. + std::vector extraRemaps; + PermMap selfPerm; + if (TString(tname.c_str()).BeginsWith("O2mcparticle")) { + selfPerm.assign(nSrc, -1); + for (Long64_t outRow = 0; outRow < (Long64_t)rowOrder.size(); ++outRow) + selfPerm[rowOrder[outRow]] = (Int_t)outRow; + extraRemaps.push_back({"fIndexArray_Mothers", &selfPerm}); + extraRemaps.push_back({"fIndexSlice_Daughters", &selfPerm}); + std::cout << " O2mcparticle: will remap intra-table mother/daughter indices\n"; } + + PermMap perm = rewriteTable(src, dirOut, rowOrder, idxBr, mcCollPerm, extraRemaps); + tablePerms[tname] = std::move(perm); } + return tablePerms; +} + +// ============================================================================ +// SECTION 8 — Paste-join table handling +// ============================================================================ +// +// A paste-joined table has NO index column. Its row N corresponds to row N +// of its parent table. When the parent is reordered, the paste-join table +// must follow with the identical row permutation. +// +// Known paste-join relationships in the AO2D data model +// (parent table prefix -> paste-joined table prefix): +// +// O2collision_* -> O2mccollisionlabel_* +// O2track_* -> O2mctracklabel_* +// O2trackiu_* -> O2mctracklabel_* (alternative track table) +// O2fwdtrack_* -> O2mcfwdtracklabel_* +// O2mfttrack_* -> O2mcmfttracklabel_* +// +// The PermMap from the parent stage is used directly as the row order. + +// Build the row order from a PermMap (srcRow -> outRow), inverted. +static std::vector rowOrderFromPerm(const PermMap &perm) { + // perm[srcRow] = outRow (or -1 if dropped) + // We need: outRow -> srcRow, i.e. a sorted list of (outRow, srcRow) pairs + std::vector> pairs; + pairs.reserve(perm.size()); + for (Long64_t srcRow = 0; srcRow < (Long64_t)perm.size(); ++srcRow) + if (perm[srcRow] >= 0) pairs.push_back({perm[srcRow], srcRow}); + std::sort(pairs.begin(), pairs.end()); + std::vector order; + order.reserve(pairs.size()); + for (auto &p : pairs) order.push_back(p.second); + return order; } -// ----------------- payload rewriting with VLA support ----------------- -struct SortKey { - Long64_t entry; - Long64_t newBC; +// The paste-join map: paste-joined table prefix -> parent table prefix +// We match by prefix (BeginsWith) because table names carry a numeric suffix. +static const std::vector> kPasteJoins = { + // { paste-joined prefix, parent prefix } + { "O2mccollisionlabel", "O2collision" }, + { "O2mctracklabel", "O2track" }, + { "O2mctracklabel", "O2trackiu" }, // same label table, alt parent + { "O2mcfwdtracklabel", "O2fwdtrack" }, + { "O2mcmfttracklabel", "O2mfttrack" }, }; -static bool isVLA(TBranch *br) { - if (!br) - return false; - TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); - return leaf && leaf->GetLeafCount(); -} +static void processPasteJoinTables( + TDirectory *dirIn, TDirectory *dirOut, + const std::unordered_map &allPerms, + const std::unordered_set &alreadyWritten) { + + // Find the MC-particle permutation (produced by stage2 for O2mcparticle_*). + // Label tables (O2mctracklabel, O2mcfwdtracklabel, O2mcmfttracklabel, + // O2mccalolabel) carry fIndexMcParticles / fIndexArrayMcParticles that must + // be remapped via this permutation regardless of whether the label table's + // row order changes. + const PermMap *mcParticlePerm = nullptr; + for (auto &[name, perm] : allPerms) { + if (TString(name.c_str()).BeginsWith("O2mcparticle")) { + mcParticlePerm = &perm; + break; + } + } -// This is the VLA-aware rewritePayloadSorted implementation (keeps previous -// tested behavior) -static void rewritePayloadSorted(TDirectory *dirIn, TDirectory *dirOut, - BCMaps &maps) { - std::unordered_set skipNames; // for count branches TIter it(dirIn->GetListOfKeys()); - while (TKey *k = (TKey *)it()) { - if (TString(k->GetClassName()) != "TTree") - continue; - std::unique_ptr holder(k->ReadObj()); // keep alive - TTree *src = dynamic_cast(holder.get()); - if (!src) - continue; - const char *tname = src->GetName(); - - if (isBCtree(tname) || isFlagsTree(tname)) { - std::cout << " skipping BC/flag tree " << tname << "\n"; - continue; + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (alreadyWritten.count(tname)) continue; + if (isBCTable(tname.c_str())) continue; + if (bcIndexBranch(src) || mcCollIndexBranch(src)) continue; + + // Build extra remaps for any fIndexMcParticles / fIndexArrayMcParticles + // branches in this table (label tables pointing into O2mcparticle). + std::vector extraRemaps; + if (mcParticlePerm) { + if (src->GetBranch("fIndexMcParticles")) + extraRemaps.push_back({"fIndexMcParticles", mcParticlePerm}); + if (src->GetBranch("fIndexArrayMcParticles")) + extraRemaps.push_back({"fIndexArrayMcParticles", mcParticlePerm}); } - const char *idxName = findIndexBranchName(src); - if (!idxName) { - // Tables indexed by McCollisions (not BCs) are forwarded to the second - // stage where the sorting scheme is available. - if (findMcCollisionIndexBranchName(src)) { - std::cout << " [forward] " << tname - << " (McCollision-indexed) -> second stage\n"; - continue; + // Check if this is a known paste-join table + const PermMap *parentPerm = nullptr; + std::string parentName; + for (auto &[pastePrefix, parentPrefix] : kPasteJoins) { + if (!TString(tname.c_str()).BeginsWith(pastePrefix.c_str())) continue; + for (auto &[pname, perm] : allPerms) { + if (TString(pname.c_str()).BeginsWith(parentPrefix.c_str())) { + parentPerm = &perm; + parentName = pname; + break; + } } - dirOut->cd(); - std::cout << " [copy] " << tname << " (no index) -> cloning\n"; - TTree *c = src->CloneTree(-1, "fast"); - c->SetDirectory(dirOut); - c->Write(); - continue; + if (parentPerm) break; } - std::cout << " [proc] reindex+SORT " << tname << " (index=" << idxName - << ")\n"; - // detect index type and bind input buffer - TBranch *inIdxBr = src->GetBranch(idxName); - if (!inIdxBr) { - std::cerr << " ERR no index branch found\n"; - continue; - } - TLeaf *idxLeaf = (TLeaf *)inIdxBr->GetListOfLeaves()->At(0); - TString idxType = idxLeaf->GetTypeName(); - - enum class IdKind { kI, kUi, kS, kUs, kUnknown }; - IdKind idk = IdKind::kUnknown; - Int_t oldI = 0, newI = 0; - UInt_t oldUi = 0, newUi = 0; - Short_t oldS = 0, newS = 0; - UShort_t oldUs = 0, newUs = 0; - - if (idxType == "Int_t") { - idk = IdKind::kI; - inIdxBr->SetAddress(&oldI); - } else if (idxType == "UInt_t") { - idk = IdKind::kUi; - inIdxBr->SetAddress(&oldUi); - } else if (idxType == "Short_t") { - idk = IdKind::kS; - inIdxBr->SetAddress(&oldS); - } else if (idxType == "UShort_t") { - idk = IdKind::kUs; - inIdxBr->SetAddress(&oldUs); + if (parentPerm) { + std::cout << " Paste-join: " << tname << " follows " << parentName << "\n"; + auto rowOrder = rowOrderFromPerm(*parentPerm); + if ((Long64_t)rowOrder.size() != src->GetEntries()) { + std::cerr << " [warn] paste-join size mismatch: " << tname + << " has " << src->GetEntries() << " rows but parent perm covers " + << rowOrder.size() << " — cloning as-is\n"; + dirOut->cd(); + TTree *c = src->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); + c->Write(); + } else { + rewriteTable(src, dirOut, rowOrder, "", {}, extraRemaps); + } + } else if (!extraRemaps.empty()) { + // Not paste-joined but has indices that need remapping (e.g. O2mccalolabel + // which is not in kPasteJoins but carries fIndexArrayMcParticles). + std::cout << " Remap-only: " << tname << "\n"; + Long64_t n = src->GetEntries(); + std::vector identity(n); + std::iota(identity.begin(), identity.end(), 0LL); + rewriteTable(src, dirOut, identity, "", {}, extraRemaps); } else { - std::cerr << " unsupported index type " << idxType - << " -> cloning as-is\n"; + // No paste-join and no index remapping needed — fast clone + std::cout << " Copy (no dependency): " << tname << "\n"; dirOut->cd(); - auto *c = src->CloneTree(-1, "fast"); + TTree *c = src->CloneTree(-1, "fast"); c->SetDirectory(dirOut); c->Write(); - continue; - } - - // build keys vector - Long64_t nEnt = src->GetEntries(); - std::vector keys; - keys.reserve(nEnt); - for (Long64_t i = 0; i < nEnt; ++i) { - inIdxBr->GetEntry(i); - Long64_t oldIdx = 0; - switch (idk) { - case IdKind::kI: - oldIdx = oldI; - break; - case IdKind::kUi: - oldIdx = oldUi; - break; - case IdKind::kS: - oldIdx = oldS; - break; - case IdKind::kUs: - oldIdx = oldUs; - break; - default: - break; - } - Long64_t newBC = -1; - if (oldIdx >= 0 && (size_t)oldIdx < maps.indexMap.size()) - newBC = maps.indexMap[(size_t)oldIdx]; - keys.push_back({i, newBC}); } + } +} - std::stable_sort(keys.begin(), keys.end(), - [](const SortKey &a, const SortKey &b) { - bool ai = (a.newBC < 0), bi = (b.newBC < 0); - if (ai != bi) - return !ai && bi; // valid first - if (a.newBC != b.newBC) - return a.newBC < b.newBC; - return a.entry < b.entry; - }); - - // If this is the McCollision tree, record the sort permutation so that - // tables indexed by McCollisions (fIndexMcCollisions) can be reordered consistently - if (isMcCollisionTree(tname)) { - maps.mcOldEntries.resize(keys.size()); - maps.mcNewEntries.assign(nEnt, -1); - for (Long64_t j = 0; j < (Long64_t)keys.size(); ++j) { - maps.mcOldEntries[j] = keys[j].entry; - if (keys[j].entry >= 0) - maps.mcNewEntries[keys[j].entry] = j; - } - } +// ============================================================================ +// SECTION 9 — Non-tree object copying (TMap metadata etc.) +// ============================================================================ - // prepare output tree +static void copyNonTreeObjects(TDirectory *dirIn, TDirectory *dirOut) { + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) == "TTree") continue; + std::unique_ptr obj(key->ReadObj()); dirOut->cd(); - TTree *out = src->CloneTree(0, "fast"); - // map branches - std::unordered_map inBranches, outBranches; - for (auto *bobj : *src->GetListOfBranches()) - inBranches[((TBranch *)bobj)->GetName()] = (TBranch *)bobj; - for (auto *bobj : *out->GetListOfBranches()) - outBranches[((TBranch *)bobj)->GetName()] = (TBranch *)bobj; - - // allocate buffers and bind: scalars & VLAs - std::vector> scalarBuffers; // shared in/out - std::vector> vlaDataBuffers; - std::vector> vlaCountBuffers; - std::vector vlaMaxLens; - std::vector vlaCountTags; - // bind index branch in output to new variable - TBranch *outIdxBr = out->GetBranch(idxName); - switch (idk) { - case IdKind::kI: - outIdxBr->SetAddress(&newI); - break; - case IdKind::kUi: - outIdxBr->SetAddress(&newUi); - break; - case IdKind::kS: - outIdxBr->SetAddress(&newS); - break; - case IdKind::kUs: - outIdxBr->SetAddress(&newUs); - break; - default: - break; - } - skipNames.clear(); - skipNames.insert(idxName); + if (obj->IsA()->InheritsFrom(TMap::Class())) + dirOut->WriteTObject(obj.get(), key->GetName(), "Overwrite"); + else + obj->Write(key->GetName(), TObject::kOverwrite); + } +} - // loop inBranches and bind - for (auto &kv : inBranches) { - const std::string bname = kv.first; - if (skipNames.count(bname)) - continue; - TBranch *inBr = kv.second; - TBranch *ouBr = outBranches.count(bname) ? outBranches[bname] : nullptr; - if (!ouBr) { - std::cerr << " [warn] no out branch for " << bname << " -> skip\n"; - continue; - } - TLeaf *leaf = (TLeaf *)inBr->GetListOfLeaves()->At(0); - if (!leaf) { - std::cerr << " [warn] branch w/o leaf " << bname << "\n"; - continue; - } +// ============================================================================ +// SECTION 10 — Per-DF directory driver +// ============================================================================ + +static void processDF(TDirectory *dirIn, TDirectory *dirOut) { + std::cout << "========================================\n"; + std::cout << "Processing " << dirIn->GetName() << "\n"; + + // ---- Find BC tree and optional flags tree ---- + TTree *treeBCs = nullptr; + TTree *treeFlags = nullptr; + { + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + TTree *t = static_cast(dirIn->Get(key->GetName())); + if (!t) continue; + TString tname = t->GetName(); + if (tname.BeginsWith("O2bc_")) { treeBCs = t; } + if (tname.BeginsWith("O2bcflag")){ treeFlags = t; } + } + } - if (!isVLA(inBr)) { - // scalar - ScalarTag tag = leafType(leaf); - if (tag == ScalarTag::kUnknown) { - std::cerr << " [warn] unknown scalar type " - << leaf->GetTypeName() << " for " << bname << "\n"; - continue; - } - auto sb = bindScalarBranch(inBr, ouBr, tag); - if (sb) - scalarBuffers.emplace_back(std::move(sb)); + if (!treeBCs) { + // No BC table — deep-copy everything unchanged + std::cout << " No BC table found — copying directory verbatim\n"; + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + std::unique_ptr obj(key->ReadObj()); + dirOut->cd(); + if (obj->InheritsFrom(TTree::Class())) { + TTree *c = static_cast(obj.get())->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); c->Write(); + } else if (obj->IsA()->InheritsFrom(TMap::Class())) { + dirOut->WriteTObject(obj.get(), key->GetName(), "Overwrite"); } else { - // VLA -> find count leaf & branch - TLeaf *cntLeaf = leaf->GetLeafCount(); - if (!cntLeaf) { - std::cerr << " [warn] VLA " << bname - << " has no count leaf -> skip\n"; - continue; - } - TBranch *inCnt = cntLeaf->GetBranch(); - TBranch *outCnt = outBranches.count(inCnt->GetName()) - ? outBranches[inCnt->GetName()] - : nullptr; - if (!outCnt) { - std::cerr << " [warn] missing out count branch " - << inCnt->GetName() << " for VLA " << bname << "\n"; - continue; - } - // avoid double-binding count branch as scalar later - skipNames.insert(inCnt->GetName()); - // detect tags - ScalarTag dataTag = leafType(leaf); - ScalarTag cntTag = leafType(cntLeaf); - if (dataTag == ScalarTag::kUnknown || cntTag == ScalarTag::kUnknown) { - std::cerr << " [warn] unsupported VLA types for " << bname - << "\n"; - continue; - } - // prescan max len - Long64_t maxLen = prescanMaxLen(src, inCnt, cntTag); - if (maxLen <= 0) - maxLen = leaf->GetMaximum(); - if (maxLen <= 0) - maxLen = 1; - // bind typed - std::unique_ptr countBufLocal; - std::unique_ptr dataBufLocal; - switch (dataTag) { - case ScalarTag::kInt: - dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, - cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kUInt: - dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, - cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kShort: - dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, - cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kUShort: - dataBufLocal = bindArrayTyped( - inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kLong64: - dataBufLocal = bindArrayTyped( - inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kULong64: - dataBufLocal = bindArrayTyped( - inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kFloat: - dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, - cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kDouble: - dataBufLocal = bindArrayTyped( - inBr, ouBr, inCnt, outCnt, cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kChar: - dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, - cntTag, maxLen, countBufLocal); - break; - case ScalarTag::kUChar: - dataBufLocal = bindArrayTyped(inBr, ouBr, inCnt, outCnt, - cntTag, maxLen, countBufLocal); - break; - default: - break; - } - if (dataBufLocal) - vlaDataBuffers.emplace_back(std::move(dataBufLocal)); - if (countBufLocal) { - vlaCountBuffers.emplace_back(std::move(countBufLocal)); - vlaMaxLens.push_back(maxLen); - vlaCountTags.push_back(cntTag); - } + obj->Write(key->GetName(), TObject::kOverwrite); } - } // end for branches - - // Now fill out in sorted order. For each key: src->GetEntry(entry) -> clamp - // counts -> set new index -> out->Fill() - Long64_t changed = 0; - for (const auto &sk : keys) { - src->GetEntry(sk.entry); - - // clamp count buffers before fill - for (size_t ic = 0; ic < vlaCountBuffers.size(); ++ic) { - void *p = vlaCountBuffers[ic]->ptr(); - Long64_t cnt = 0; - switch (vlaCountTags[ic]) { - case ScalarTag::kInt: - cnt = *(Int_t *)p; - break; - case ScalarTag::kUInt: - cnt = *(UInt_t *)p; - break; - case ScalarTag::kShort: - cnt = *(Short_t *)p; - break; - case ScalarTag::kUShort: - cnt = *(UShort_t *)p; - break; - case ScalarTag::kLong64: - cnt = *(Long64_t *)p; - break; - case ScalarTag::kULong64: - cnt = *(ULong64_t *)p; - break; - default: - cnt = *(Int_t *)p; - break; - } - if (cnt < 0) - cnt = 0; - if (cnt > vlaMaxLens[ic]) { - std::cerr << "WARNING: clamping VLA count " << cnt << " to max " - << vlaMaxLens[ic] << " for tree " << tname << "\n"; - // write back - if (vlaMaxLens[ic] <= std::numeric_limits::max()) { - *(Int_t *)p = (Int_t)vlaMaxLens[ic]; - } else { - *(Long64_t *)p = (Long64_t)vlaMaxLens[ic]; - } - } - } - - // set new index value in out buffer - switch (idk) { - case IdKind::kI: { - Int_t prev = oldI; - newI = (sk.newBC >= 0 ? (Int_t)sk.newBC : -1); - if (newI != prev) - ++changed; - } break; - case IdKind::kUi: { - UInt_t prev = oldUi; - newUi = (sk.newBC >= 0 ? (UInt_t)sk.newBC : 0u); - if (newUi != prev) - ++changed; - } break; - case IdKind::kS: { - Short_t prev = oldS; - newS = (sk.newBC >= 0 ? (Short_t)sk.newBC : (Short_t)-1); - if (newS != prev) - ++changed; - } break; - case IdKind::kUs: { - UShort_t prev = oldUs; - newUs = (sk.newBC >= 0 ? (UShort_t)sk.newBC : (UShort_t)0); - if (newUs != prev) - ++changed; - } break; - default: - break; - } - - out->Fill(); } + return; + } - std::cout << " wrote " << out->GetEntries() << " rows; remapped " - << changed << " index values; sorted\n"; - out->Write(); - } // end while keys in dir - - // ---- second stage: tables indexed by McCollisions using fIndexMcCollisions ---- - if (!maps.mcNewEntries.empty()) { - TIter it2(dirIn->GetListOfKeys()); - while (TKey *k2 = (TKey *)it2()) { - if (TString(k2->GetClassName()) != "TTree") - continue; - std::unique_ptr holder2(k2->ReadObj()); - TTree *src2 = dynamic_cast(holder2.get()); - if (!src2) - continue; - const char *tname2 = src2->GetName(); - if (isBCtree(tname2) || isFlagsTree(tname2)) - continue; - if (findIndexBranchName(src2)) - continue; // handled in first stage - const char *mcIdxName = findMcCollisionIndexBranchName(src2); - if (!mcIdxName) { - // No BC index and no McCollision index → already handled (copied) earlier - continue; - } + // ---- Stage 0: sort & deduplicate BCs ---- + std::cout << "-- Stage 0: BCs --\n"; + dirOut->cd(); + BCStage0Result s0 = stage0_sortBCs(treeBCs, dirOut); + if (treeFlags) stage0_copyBCFlags(treeFlags, dirOut, s0.bcPerm); + + // Track which tree names have been written so we don't double-write + std::unordered_set written; + written.insert(treeBCs->GetName()); + if (treeFlags) written.insert(treeFlags->GetName()); + + // ---- Stage 1: BC-indexed tables (including MCCollisions dedup) ---- + std::cout << "-- Stage 1: BC-indexed tables --\n"; + auto stage1Perms = stage1_BCindexedTables(dirIn, dirOut, s0.bcPerm); + for (auto &kv : stage1Perms) written.insert(kv.first); + + // ---- Stage 2: MCCollision-indexed tables ---- + // Find the MCCollision permutation from stage 1 + std::cout << "-- Stage 2: MCCollision-indexed tables --\n"; + PermMap mcCollPerm; + for (auto &[tname, perm] : stage1Perms) { + if (TString(tname.c_str()).BeginsWith("O2mccollision")) { + mcCollPerm = perm; + break; + } + } + if (!mcCollPerm.empty()) { + auto stage2Perms = stage2_MCCollIndexedTables(dirIn, dirOut, mcCollPerm); + for (auto &kv : stage2Perms) { + written.insert(kv.first); + stage1Perms[kv.first] = kv.second; // merge into allPerms for paste-join lookup + } + } else { + std::cout << " (no MCCollision table found — skipping stage 2)\n"; + } - std::cout << " [proc] reindex+SORT " << tname2 - << " (McCollision index=" << mcIdxName << ")\n"; + // ---- Paste-join tables + unrelated tables ---- + std::cout << "-- Paste-join and unrelated tables --\n"; + processPasteJoinTables(dirIn, dirOut, stage1Perms, written); - TBranch *inMcIdxBr = src2->GetBranch(mcIdxName); - if (!inMcIdxBr) { - std::cerr << " ERR no McCollision index branch\n"; - continue; - } - Int_t oldMcI = 0, newMcI = 0; - inMcIdxBr->SetAddress(&oldMcI); - - // Build sort keys: sort by new McCollision position. - Long64_t nEnt2 = src2->GetEntries(); - std::vector keys2; - keys2.reserve(nEnt2); - for (Long64_t i = 0; i < nEnt2; ++i) { - inMcIdxBr->GetEntry(i); - Long64_t newMcPos = -1; - if (oldMcI >= 0 && - (size_t)oldMcI < maps.mcNewEntries.size()) - newMcPos = maps.mcNewEntries[(size_t)oldMcI]; - keys2.push_back({i, newMcPos}); - } - std::stable_sort(keys2.begin(), keys2.end(), - [](const SortKey &a, const SortKey &b) { - bool ai = (a.newBC < 0), bi = (b.newBC < 0); - if (ai != bi) - return !ai && bi; - if (a.newBC != b.newBC) - return a.newBC < b.newBC; - return a.entry < b.entry; - }); + // ---- Non-tree objects (TMap metadata) ---- + copyNonTreeObjects(dirIn, dirOut); - dirOut->cd(); - TTree *out2 = src2->CloneTree(0, "fast"); - - std::unordered_map inBrs2, outBrs2; - for (auto *b : *src2->GetListOfBranches()) - inBrs2[((TBranch *)b)->GetName()] = (TBranch *)b; - for (auto *b : *out2->GetListOfBranches()) - outBrs2[((TBranch *)b)->GetName()] = (TBranch *)b; - - TBranch *outMcIdxBr = out2->GetBranch(mcIdxName); - outMcIdxBr->SetAddress(&newMcI); - - std::unordered_set skipNames2; - skipNames2.insert(mcIdxName); - - std::vector> scalarBufs2; - for (auto &kv : inBrs2) { - if (skipNames2.count(kv.first)) - continue; - TBranch *inBr = kv.second; - TBranch *ouBr = outBrs2.count(kv.first) ? outBrs2[kv.first] : nullptr; - if (!ouBr) - continue; - TLeaf *leaf = (TLeaf *)inBr->GetListOfLeaves()->At(0); - if (!leaf || isVLA(inBr)) - continue; // no variable-length arrays seen in McCollision-indexed tables (could be changed in the future) - ScalarTag tag = leafType(leaf); - if (tag == ScalarTag::kUnknown) - continue; - auto sb = bindScalarBranch(inBr, ouBr, tag); - if (sb) - scalarBufs2.emplace_back(std::move(sb)); - } + std::cout << "Done: " << dirIn->GetName() << "\n"; +} - Long64_t changed2 = 0; - for (const auto &sk : keys2) { - src2->GetEntry(sk.entry); - Int_t prev = oldMcI; - newMcI = (sk.newBC >= 0 ? (Int_t)sk.newBC : -1); - if (newMcI != prev) - ++changed2; - out2->Fill(); - } - std::cout << " wrote " << out2->GetEntries() - << " rows; remapped " << changed2 - << " McCollision index values; sorted\n"; - out2->Write(); - } - } else { - // No mccollision permutation available: clone deferred trees as-is - TIter it2(dirIn->GetListOfKeys()); - while (TKey *k2 = (TKey *)it2()) { - if (TString(k2->GetClassName()) != "TTree") - continue; - std::unique_ptr holder2(k2->ReadObj()); - TTree *src2 = dynamic_cast(holder2.get()); - if (!src2) - continue; - if (isBCtree(src2->GetName()) || isFlagsTree(src2->GetName())) - continue; - if (findIndexBranchName(src2)) - continue; - if (!findMcCollisionIndexBranchName(src2)) - continue; - std::cerr << " [warn] no mccollision permutation for " - << src2->GetName() << " -> cloning as-is\n"; - dirOut->cd(); - TTree *c = src2->CloneTree(-1, "fast"); - c->SetDirectory(dirOut); - c->Write(); - } +// ============================================================================ +// SECTION 11 — Post-write validation +// ============================================================================ +// +// AODBcRewriterValidate() opens a rewritten AO2D and checks key invariants: +// 1. BC table is strictly monotonic in fGlobalBC. +// 2. MC particle intra-table daughter/mother indices are in range and point +// to particles belonging to the same MC collision. +// 3. fIndexMcParticles in label tables is in range. +// +// Returns true if all checks pass. Prints a summary to stdout. + +static bool validateDF(TDirectory *d) { + bool ok = true; + + // ---- BC monotonicity ---- + TIter it(d->GetListOfKeys()); + TKey *k; + TTree *bcTree = nullptr; + TTree *mcpTree = nullptr; + while ((k = (TKey*)it())) { + TObject *obj = d->Get(k->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + TTree *t = (TTree*)obj; + TString tn = t->GetName(); + if (tn.BeginsWith("O2bc_")) bcTree = t; + if (tn.BeginsWith("O2mcparticle")) mcpTree = t; } - // non-tree objects: copy as-is (but for TMap use WriteTObject to preserve - // class) - it.Reset(); - while (TKey *k = (TKey *)it()) { - if (TString(k->GetClassName()) == "TTree") - continue; - TObject *obj = k->ReadObj(); - dirOut->cd(); - if (obj->IsA()->InheritsFrom(TMap::Class())) { - std::cout << " Copying TMap " << k->GetName() << " as a whole\n"; - dirOut->WriteTObject(obj, k->GetName(), "Overwrite"); - } else { - obj->Write(k->GetName(), TObject::kOverwrite); + if (bcTree) { + ULong64_t gbc = 0, prev = 0; + bcTree->SetBranchAddress("fGlobalBC", &gbc); + Long64_t nBC = bcTree->GetEntries(); + Long64_t nBad = 0; + for (Long64_t i = 0; i < nBC; ++i) { + bcTree->GetEntry(i); + if (i > 0 && gbc <= prev) ++nBad; + prev = gbc; + } + if (nBad > 0) { + std::cerr << " [FAIL] " << bcTree->GetName() + << ": " << nBad << " non-monotonic BC entries\n"; + ok = false; } } -} -// ----------------- per-DF driver ----------------- -static void processDF(TDirectory *dIn, TDirectory *dOut) { - std::cout << "------------------------------------------------\n"; - std::cout << "Processing DF: " << dIn->GetName() << "\n"; - - // 1) rebuild BCs & flags -> maps - TTree *bcOut = nullptr; - BCMaps maps; - rebuildBCsAndFlags(dIn, dOut, bcOut, maps); - - if (!bcOut) { - std::cout << " No BCs -> deep copying directory\n"; - TIter it(dIn->GetListOfKeys()); - while (TKey *k = (TKey *)it()) { - TObject *obj = k->ReadObj(); - dOut->cd(); - if (obj->InheritsFrom(TTree::Class())) { - TTree *t = (TTree *)obj; - TTree *c = t->CloneTree(-1, "fast"); - c->SetDirectory(dOut); - c->Write(); - } else { - if (obj->IsA()->InheritsFrom(TMap::Class())) { - dOut->WriteTObject(obj, k->GetName(), "Overwrite"); - } else { - obj->Write(k->GetName(), TObject::kOverwrite); + // ---- MC particle intra-table indices ---- + if (mcpTree) { + Long64_t nMcp = mcpTree->GetEntries(); + Int_t daughters[2] = {-1,-1}, mcCollIdx = -1, motherSize = 0, mothers[200] = {}; + mcpTree->SetBranchStatus("*", 0); + mcpTree->SetBranchStatus("fIndexSlice_Daughters", 1); + mcpTree->SetBranchStatus("fIndexMcCollisions", 1); + mcpTree->SetBranchStatus("fIndexArray_Mothers_size",1); + mcpTree->SetBranchStatus("fIndexArray_Mothers", 1); + mcpTree->SetBranchAddress("fIndexSlice_Daughters", daughters); + mcpTree->SetBranchAddress("fIndexMcCollisions", &mcCollIdx); + mcpTree->SetBranchAddress("fIndexArray_Mothers_size",&motherSize); + mcpTree->SetBranchAddress("fIndexArray_Mothers", mothers); + + // Pre-load MC collision index for cross-collision check + std::vector allMcColl(nMcp); + for (Long64_t i = 0; i < nMcp; ++i) { mcpTree->GetEntry(i); allMcColl[i] = mcCollIdx; } + + Long64_t badSlice = 0, badMother = 0, badXcoll = 0; + for (Long64_t i = 0; i < nMcp; ++i) { + mcpTree->GetEntry(i); + if (daughters[0] >= 0) { + if (daughters[0] >= nMcp || daughters[1] >= nMcp || daughters[0] > daughters[1]) + ++badSlice; + else for (Int_t d2 = daughters[0]; d2 <= daughters[1]; ++d2) + if (allMcColl[d2] != mcCollIdx) ++badXcoll; + } + for (int m = 0; m < std::min(motherSize, 200); ++m) { + if (mothers[m] >= 0) { + if (mothers[m] >= nMcp) ++badMother; + else if (allMcColl[mothers[m]] != mcCollIdx) ++badXcoll; } } } - return; + if (badSlice || badMother || badXcoll) { + std::cerr << " [FAIL] " << mcpTree->GetName() + << ": bad_slice=" << badSlice + << " bad_mother=" << badMother + << " cross_coll=" << badXcoll << "\n"; + ok = false; + } + mcpTree->SetBranchStatus("*", 1); } - // 2) rewrite payload tables (reindex+sort) - rewritePayloadSorted(dIn, dOut, maps); + return ok; +} - std::cout << "Finished DF: " << dIn->GetName() << "\n"; +bool AODBcRewriterValidate(const char *fname = "AO2D_rewritten.root") { + std::cout << "Validating " << fname << "\n"; + std::unique_ptr f(TFile::Open(fname, "READ")); + if (!f || f->IsZombie()) { std::cerr << "Cannot open " << fname << "\n"; return false; } + + bool allOk = true; + int nDF = 0; + TIter top(f->GetListOfKeys()); + TKey *k; + while ((k = (TKey*)top())) { + if (!TString(k->GetName()).BeginsWith("DF_")) continue; + TDirectory *d = (TDirectory*)f->Get(k->GetName()); + bool dfOk = validateDF(d); + if (!dfOk) std::cerr << " -> FAILED in " << k->GetName() << "\n"; + allOk = allOk && dfOk; + ++nDF; + } + f->Close(); + if (allOk) + std::cout << "VALIDATION PASSED (" << nDF << " DFs checked)\n"; + else + std::cout << "VALIDATION FAILED — see [FAIL] lines above\n"; + return allOk; } -// ----------------- top-level driver ----------------- -void AODBcRewriter(const char *inFileName = "AO2D.root", +// ============================================================================ +// SECTION 12 — Top-level entry point +// ============================================================================ + +void AODBcRewriter(const char *inFileName = "AO2D.root", const char *outFileName = "AO2D_rewritten.root") { - std::cout << "Opening input file: " << inFileName << "\n"; + + std::cout << "AODBcRewriter: input=" << inFileName + << " output=" << outFileName << "\n"; + std::unique_ptr fin(TFile::Open(inFileName, "READ")); - if (!fin || fin->IsZombie()) { - std::cerr << "ERROR opening input\n"; - return; - } + if (!fin || fin->IsZombie()) { std::cerr << "ERROR: cannot open " << inFileName << "\n"; return; } int algo = fin->GetCompressionAlgorithm(); - int lvl = fin->GetCompressionLevel(); - std::cout << "Input compression: algo=" << algo << " level=" << lvl << "\n"; + int lvl = fin->GetCompressionLevel(); - // create output applying same compression level when available #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 30, 0) std::unique_ptr fout(TFile::Open(outFileName, "RECREATE", "", lvl)); #else std::unique_ptr fout(TFile::Open(outFileName, "RECREATE")); #endif - if (!fout || fout->IsZombie()) { - std::cerr << "ERROR creating output\n"; - return; - } + if (!fout || fout->IsZombie()) { std::cerr << "ERROR: cannot create " << outFileName << "\n"; return; } fout->SetCompressionAlgorithm(algo); fout->SetCompressionLevel(lvl); - // top-level keys TIter top(fin->GetListOfKeys()); - while (TKey *key = (TKey *)top()) { + while (TKey *key = static_cast(top())) { TString name = key->GetName(); - TObject *obj = key->ReadObj(); + std::unique_ptr obj(key->ReadObj()); + if (obj->InheritsFrom(TDirectory::Class()) && isDF(name)) { - std::cout << "Found DF folder: " << name << "\n"; - TDirectory *din = (TDirectory *)obj; + TDirectory *din = static_cast(obj.get()); TDirectory *dout = fout->mkdir(name); processDF(din, dout); } else { + // Top-level non-DF objects (metadata TMaps etc.) fout->cd(); - if (obj->IsA()->InheritsFrom(TMap::Class())) { - std::cout << "Copying top-level TMap: " << name << "\n"; - fout->WriteTObject(obj, name, "Overwrite"); - } else { - std::cout << "Copying top-level object: " << name << " [" - << obj->ClassName() << "]\n"; + if (obj->IsA()->InheritsFrom(TMap::Class())) + fout->WriteTObject(obj.get(), name, "Overwrite"); + else obj->Write(name, TObject::kOverwrite); - } } } fout->Write("", TObject::kOverwrite); fout->Close(); fin->Close(); - std::cout << "All done. Output written to " << outFileName << "\n"; + std::cout << "All done. Output: " << outFileName << "\n"; } From 47b6c57c6147939c2a0a0b789ff14491fde8e90e Mon Sep 17 00:00:00 2001 From: Rashi gupta <167059733+rashigupt@users.noreply.github.com> Date: Tue, 5 May 2026 13:46:25 +0530 Subject: [PATCH 311/362] Add BoxGen function to implement flat pT generation for Non-HFE efficiency studies (#2334) * Update GeneratorHF_Non_Hfe.json Flat pion and eta distributions are added to enhance statistics at high transverse momentum. * Update pythia8_NonHfe.cfg Remove CR mode2 * Update GeneratorHF_Non_Hfe.json * Remove number parameter * Update GeneratorHF_Non_Hfe.json * implement flat pT generation for pi0 and eta * implement flat pT generation for pi0 and eta * implement flat pT generation for pi0 and eta * Update GeneratorHF_Non_Hfe.ini * Update GeneratorHF_Non_Hfe.ini * Update GeneratorHF_Non_Hfe.C * Rename MC/config/PWGHF/trigger/selectNonHfe.C to MC/config/PWGHF/external/generator/selectNonHfe.C * Update GeneratorHF_Non_Hfe.ini * Update GeneratorHF_Non_Hfe.C --- .../PWGHF/external/generator/selectNonHfe.C | 96 +++++++++++++++++++ MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini | 11 ++- .../PWGHF/ini/tests/GeneratorHF_Non_Hfe.C | 2 +- .../pythia8/generator/pythia8_NonHfe.cfg | 5 +- MC/config/PWGHF/trigger/selectNonHfe.C | 41 -------- 5 files changed, 108 insertions(+), 47 deletions(-) create mode 100644 MC/config/PWGHF/external/generator/selectNonHfe.C delete mode 100644 MC/config/PWGHF/trigger/selectNonHfe.C diff --git a/MC/config/PWGHF/external/generator/selectNonHfe.C b/MC/config/PWGHF/external/generator/selectNonHfe.C new file mode 100644 index 000000000..7c685c585 --- /dev/null +++ b/MC/config/PWGHF/external/generator/selectNonHfe.C @@ -0,0 +1,96 @@ +/// Select π⁰ and η within a given rapidity window for enhancement +/// pdgPartForAccCut: PDG of the particle to select (111=π⁰, 221=η) +/// minNb: minimum number of such particles per event for enhancement + +//// authors: Rashi Gupta (rashi.gupta@cern.ch) +/// authors: Ravindra Singh (ravindra.singh@cern.ch) + + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include +#include +#endif + +#include "Pythia8/Pythia.h" +using namespace Pythia8; + +class GeneratorPythia8Box : public o2::eventgen::GeneratorPythia8 +{ +public: + + GeneratorPythia8Box(std::vector pdgList, int nInject = 3, float ptMin = 0.1, float ptMax = 50.0, float etaMin = -0.8, float etaMax = 0.8) + : mPdgList(pdgList), nParticles(nInject), genMinPt(ptMin), genMaxPt(ptMax), genMinEta(etaMin), genMaxEta(etaMax) + { + } + + ~GeneratorPythia8Box() = default; + +Bool_t generateEvent() override +{ + bool hasElectron = false; + + while (!hasElectron) { + mPythia.event.reset(); + + for (int i{0}; i < nParticles; ++i) + { + int currentPdg = mPdgList[gRandom->Integer(mPdgList.size())]; + double mass = TDatabasePDG::Instance()->GetParticle(currentPdg)->Mass(); + + const double pt = gRandom->Uniform(genMinPt, genMaxPt); + const double eta = gRandom->Uniform(genMinEta, genMaxEta); + 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), mass)}; + + + mPythia.event.append(currentPdg, 11, 0, 0, px, py, pz, et, mass); + } + + + if (!mPythia.next()) continue; + + + for (int i = 0; i < mPythia.event.size(); ++i) { + if (std::abs(mPythia.event[i].id()) == 11) { + + + double childPt = mPythia.event[i].pT(); + double childEta = mPythia.event[i].eta(); + + if (childPt > 0.1 && std::abs(childEta) < 1.2) { + hasElectron = true; // Mil gaya! + break; + } + } + } + + } + + return true; +} + +private: + std::vector mPdgList; + double genMinPt, genMaxPt; + double genMinEta, genMaxEta; + int nParticles; +}; + + +FairGenerator *generatePythia8Box(float ptMin = 0.1, float ptMax = 50.0) +{ + + std::vector pdgList = {111, 221}; + return new GeneratorPythia8Box(pdgList, 3, ptMin, ptMax, -0.8, 0.8); +} diff --git a/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini b/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini index 7ed9bb10b..f5455e34d 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini @@ -1,4 +1,7 @@ -#### This configuration uses the Hybrid external generator to trigger π⁰/η production within the specified rapidity window - -[GeneratorHybrid] -configFile = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json +#### This configuration uses the Box generator to trigger π⁰/η production within the specified rapidity window +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/selectNonHfe.C +funcName = generatePythia8Box(0.1, 50.0) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C b/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C index ba9dcb737..fb2c280d9 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C @@ -1,4 +1,4 @@ -int Hybrid() { +int External() { std::string path{"o2sim_Kine.root"}; const int pdgPi0 = 111; diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg index b19227718..3feaa6585 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg @@ -8,11 +8,14 @@ Beams:idB 2212 # proton Beams:eCM 13600. # GeV ### processes -SoftQCD:inelastic on # all inelastic processes + +ProcessLevel:all = off ### decays ParticleDecays:limitTau0 on ParticleDecays:tau0Max 10. +### processes + ### switch off all decay channels 111:onMode = off diff --git a/MC/config/PWGHF/trigger/selectNonHfe.C b/MC/config/PWGHF/trigger/selectNonHfe.C deleted file mode 100644 index 2acfc23fe..000000000 --- a/MC/config/PWGHF/trigger/selectNonHfe.C +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include "Generators/Trigger.h" -#include -#include - -///============================================================================ - -/// Select π⁰ and η within a given rapidity window for enhancement -/// pdgPartForAccCut: PDG of the particle to select (111=π⁰, 221=η) -/// minNb: minimum number of such particles per event for enhancement - -//// authors: Rashi Gupta (rashi.gupta@cern.ch) -/// authors: Ravindra Singh (ravindra.singh@cern.ch) -/// ============================================================================ -o2::eventgen::Trigger selectPionEtaWithinAcc(TString pdgPartForAccCut = "111;221", double rapidityMin = -1.5, double rapidityMax = 1.5, int minNb = 1) -{ - return [pdgPartForAccCut, rapidityMin, rapidityMax, minNb](const std::vector& particles) -> bool { - TObjArray* obj = pdgPartForAccCut.Tokenize(";"); - int count = 0; - for (const auto& particle : particles) { - int pdg = TMath::Abs(particle.GetPdgCode()); - double y = particle.Y(); - - if (y < rapidityMin || y > rapidityMax) continue; - - for (int i = 0; i < obj->GetEntriesFast(); ++i) { - int pdgCode = std::stoi(obj->At(i)->GetName()); - - if (pdg == pdgCode) { - count++; - break; - } - } - } - // Only accept events with at least minNb π⁰/η - if (count >= minNb) - return kTRUE; - else - return kFALSE; - }; -} From d844ea9d79b07df81f3af81bd78d7bc0f4ac31b1 Mon Sep 17 00:00:00 2001 From: lgansbartl Date: Thu, 7 May 2026 09:54:51 +0200 Subject: [PATCH 312/362] PWGEM: Update pythia config for Dalitz Decay MC (#2348) Co-authored-by: Laura Gansbartl --- .../pythia8/generator/configPythia_ForcedDalitz.cfg | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg b/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg index d51c6f20e..fca369b49 100644 --- a/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg +++ b/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg @@ -12,10 +12,9 @@ ParticleDecays:limitTau0 on ParticleDecays:tau0Max 10 -#decay eta -> e+ e- gamma BR = 100% -221:onMode = off -221:onIfMatch = 22 11 -11 -#221:addChannel = 1 1 0 22 11 -11 +#decay eta -> e+ e- gamma, BR = 100% +221:oneChannel = 1 1 0 22 11 -11 #decay pi0 -> e+ e- gamma BR = 10% -111:addChannel = 1 0.10 0 22 11 -11" +111:oneChannel = 1 0.9 0 22 22 +111:addChannel = 1 0.1 0 22 11 -11 From 9c18dd0b2ff23966934e16176328dc6a1372bb40 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Wed, 6 May 2026 14:10:18 +0200 Subject: [PATCH 313/362] setenv_calib.sh: add additional check for CALIB_TPC_CMV --- DATA/common/setenv_calib.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index 3ccb50b8e..26bb86deb 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -199,6 +199,7 @@ fi ( [[ -z ${CALIB_TPC_RESPADGAIN:-} ]] || [[ $CAN_DO_CALIB_TPC_RESPADGAIN == 0 ]] ) && CALIB_TPC_RESPADGAIN=0 ( [[ -z ${CALIB_TPC_IDC:-} ]] || [[ $CAN_DO_CALIB_TPC_IDC == 0 ]] ) && CALIB_TPC_IDC=0 ( [[ -z ${CALIB_TPC_SAC:-} ]] || [[ $CAN_DO_CALIB_TPC_SAC == 0 ]] ) && CALIB_TPC_SAC=0 +( [[ -z ${CALIB_TPC_CMV:-} ]] || [[ $CAN_DO_CALIB_TPC_CMV == 0 ]] ) && CALIB_TPC_CMV=0 ( [[ -z ${CALIB_TPC_VDRIFTTGL:-} ]] || [[ $CAN_DO_CALIB_TPC_VDRIFTTGL == 0 ]] ) && CALIB_TPC_VDRIFTTGL=0 ( [[ -z ${CALIB_TRD_VDRIFTEXB:-} ]] || [[ $CAN_DO_CALIB_TRD_VDRIFTEXB == 0 ]] ) && CALIB_TRD_VDRIFTEXB=0 ( [[ -z ${CALIB_TRD_GAIN:-} ]] || [[ $CAN_DO_CALIB_TRD_GAIN == 0 ]] ) && CALIB_TRD_GAIN=0 @@ -313,11 +314,12 @@ if [[ -z ${CALIBDATASPEC_TPCIDC_C:-} ]]; then # TPC if [[ $CALIB_TPC_IDC == 1 ]]; then add_semicolon_separated CALIBDATASPEC_TPCIDC_C "idcsgroupc:TPC/IDCGROUPC"; fi fi +# define spec for proxy for TPC CMVs if [[ -z ${CALIBDATASPEC_TPCCMV:-} ]]; then # TPC if [[ $CALIB_TPC_CMV == 1 ]]; then - add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvgroup:TPC/CMVGROUP"; - add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvorbit:TPC/CMVORBITINFO"; + add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvgroup:TPC/CMVGROUP"; + add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvorbit:TPC/CMVORBITINFO"; fi fi From 89b4dce6bc022082b60a31691d803b717a86c830 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Thu, 7 May 2026 14:30:56 +0200 Subject: [PATCH 314/362] production.desc: add TPC CMV processing as calib collection --- DATA/production/production.desc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/production/production.desc b/DATA/production/production.desc index 509adf585..d12b00d4d 100644 --- a/DATA/production/production.desc +++ b/DATA/production/production.desc @@ -1,3 +1,3 @@ synchronous-workflow: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 production/dpl-workflow.sh" synchronous-workflow-1numa: "O2PDPSuite" reco,128,126,"SYNCMODE=1 production/dpl-workflow.sh" -synchronous-workflow-calib: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_TF SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_SPORADIC SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_IDCBOTH_SAC SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" +synchronous-workflow-calib: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_TF SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_SPORADIC SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_IDCBOTH_SAC SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,64,"AGGREGATOR_TASKS=TPC_CMV SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" From 851f56f0674cea983604ceda70281fcb1c7f1764 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 8 May 2026 13:17:55 +0200 Subject: [PATCH 315/362] MC/PWGEM: update configs in pp at 5.36 TeV (#2351) --- ...tor_pythia8_GapTriggered_HFLepton_pp5360.C | 224 ++++++++++++++++++ ...gered_BeautyForcedDecay_Gap5_pp5360GeV.ini | 7 + ...red_BeautyNoForcedDecay_Gap5_pp5360GeV.ini | 7 + ...torHFGapTriggered_Charm_Gap5_pp5360GeV.ini | 7 + ...iggered_BeautyForcedDecay_Gap5_pp5360GeV.C | 118 +++++++++ ...gered_BeautyNoForcedDecay_Gap5_pp5360GeV.C | 113 +++++++++ ...ratorHFGapTriggered_Charm_Gap5_pp5360GeV.C | 117 +++++++++ .../generator/pythia8_pp_5360_MB_gapevent.cfg | 15 ++ .../generator/pythia8_pp_5360_bbbar.cfg | 36 +++ ..._pp_5360_bbbar_forceddecayscharmbeauty.cfg | 127 ++++++++++ .../pythia8_pp_5360_cr2_forceddecayscharm.cfg | 70 ++++++ MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh | 50 ++++ ...AnchoredHFGapToDielectrons_pp_5360_Gap5.sh | 57 +++++ 13 files changed, 948 insertions(+) create mode 100644 MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini create mode 100644 MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.C create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg create mode 100644 MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg create mode 100644 MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh create mode 100644 MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_5360_Gap5.sh diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C new file mode 100644 index 000000000..3daa246ae --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C @@ -0,0 +1,224 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include +//#include // for std::pair + +using namespace Pythia8; + +class GeneratorPythia8GapTriggeredHFLepton : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapTriggeredHFLepton() = default; + + /// constructor + GeneratorPythia8GapTriggeredHFLepton(TString configsignal, int quarkPdg = 4, int lInputTriggerRatio = 5, int lInputExternalID = 0) + { + + lGeneratedEvents = 0; + lInverseTriggerRatio = lInputTriggerRatio; + lExternalID = lInputExternalID; + mQuarkPdg = quarkPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(lInverseTriggerRatio)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg"); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + // flag the generators using type + // addCocktailConstituent(type, "interesting"); + // addCocktailConstitent(0, "minbias"); + // Add Sub generators + addSubGenerator(0, "default generator"); + addSubGenerator(1, "charm lepton"); + addSubGenerator(2, "beauty forced decay"); + addSubGenerator(3, "beauty no foced decay"); + } + + /// Destructor + ~GeneratorPythia8GapTriggeredHFLepton() = default; + + void addTriggerOnDaughter(int nb, int pdg) + { + mNbDaughter = nb; + mPdgDaughter = pdg; + }; + void setQuarkRapidity(float yMin, float yMax) + { + mQuarkRapidityMin = yMin; + mQuarkRapidityMax = yMax; + }; + void setDaughterRapidity(float yMin, float yMax) + { + mDaughterRapidityMin = yMin; + mDaughterRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Simple straightforward check to alternate generators + if (lGeneratedEvents % lInverseTriggerRatio == 0) { + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + } else { + // Generate minimum-bias event + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + notifySubGenerator(0); + } + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + bool isGoodAtPartonLevel = false, isGoodAtDaughterLevel = (mPdgDaughter != 0) ? false : true; + int nbDaughter = 0; + for (auto iPart{0}; iPart < event.size(); ++iPart) { + // search for Q-Qbar mother with at least one Q in rapidity window + if (!isGoodAtPartonLevel) { + auto daughterList = event[iPart].daughterList(); + bool hasQ = false, hasQbar = false, atSelectedY = false; + for (auto iDau : daughterList) { + if (event[iDau].id() == mQuarkPdg) { + hasQ = true; + } + if (event[iDau].id() == -mQuarkPdg) { + hasQbar = true; + } + if ((std::abs(event[iDau].id()) == mQuarkPdg) && (event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + atSelectedY = true; + } + if (hasQ && hasQbar && atSelectedY) { + isGoodAtPartonLevel = true; + } + } + // search for mNbDaughter daughters of type mPdgDaughter in rapidity window + if (!isGoodAtDaughterLevel) { + int id = std::abs(event[iPart].id()); + float rap = event[iPart].y(); + if (id == mPdgDaughter) { + int motherindexa = event[iPart].mother1(); + if (motherindexa > 0) { + int idmother = std::abs(event[motherindexa].id()); + if (int(std::abs(idmother) / 100.) == 4 || int(std::abs(idmother) / 1000.) == 4 || int(std::abs(idmother) / 100.) == 5 || int(std::abs(idmother) / 1000.) == 5) { + if (rap > mDaughterRapidityMin && rap < mDaughterRapidityMax) { + nbDaughter++; + if (nbDaughter >= mNbDaughter) isGoodAtDaughterLevel = true; + } + } + } + } + } + // we send the trigger + if (isGoodAtPartonLevel && isGoodAtDaughterLevel) { + return true; + } + } + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mQuarkPdg; + float mQuarkRapidityMin; + float mQuarkRapidityMax; + int mPdgDaughter; + int mNbDaughter; + float mDaughterRapidityMin; + float mDaughterRapidityMax; + + // Control gap-triggering + Long64_t lGeneratedEvents; + int lInverseTriggerRatio; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectMinimumBias; ///Minimum bias collision generator + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +// Charm-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredCharmLepton(int inputTriggerRatio, int inputExternalID, float yMin = -1.5, float yMax = 1.5) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLepton("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg", 4, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMin, yMax); + myGen->addTriggerOnDaughter(2, 11); + myGen->setDaughterRapidity(-1., 1.); + return myGen; +} + +// Beauty-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyForcedDecays(int inputTriggerRatio, int inputExternalID, float yMin = -1.5, float yMax = 1.5) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLepton("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMin, yMax); + myGen->addTriggerOnDaughter(2, 11); + myGen->setDaughterRapidity(-1., 1.); + return myGen; +} + +// Beauty-enriched no forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyNoForcedDecays(int inputTriggerRatio, int inputExternalID, float yMin = -1.5, float yMax = 1.5) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLepton("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMin, yMax); + myGen->addTriggerOnDaughter(2, 11); + myGen->setDaughterRapidity(-1., 1.); + return myGen; +} diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..54de7afa1 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C +funcName = GeneratorPythia8GapTriggeredBeautyForcedDecays(5,2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..0cc38a529 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C +funcName = GeneratorPythia8GapTriggeredBeautyNoForcedDecays(5,3) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..e653a993b --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C +funcName = GeneratorPythia8GapTriggeredCharmLepton(5,1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.C new file mode 100644 index 000000000..5bee390cc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.C @@ -0,0 +1,118 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + printf("Event %d\n",i); + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.C new file mode 100644 index 000000000..10907110b --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.C @@ -0,0 +1,113 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.C new file mode 100644 index 000000000..9081b8a81 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.C @@ -0,0 +1,117 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3.; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg new file mode 100644 index 000000000..b3fdfdd99 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg @@ -0,0 +1,15 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### per default it is Monash anyway +Tune:pp = 14 + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg new file mode 100644 index 000000000..3e1df36b7 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg @@ -0,0 +1,36 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +#HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg new file mode 100644 index 000000000..c3beca4d5 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg @@ -0,0 +1,127 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +#HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 + +### only semileptonic decays from https://pdg.lbl.gov/2025/ +### D+ +411:oneChannel = 1 0.0881 0 -311 -11 12 +411:addChannel = 1 0.0402 0 -321 211 -11 12 +411:addChannel = 1 0.0540 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.0354 0 -321 -11 12 +421:addChannel = 1 0.0216 0 -323 -11 12 +421:addChannel = 1 0.0160 0 -321 111 -11 12 +421:addChannel = 1 0.0144 0 -311 211 -11 12 +### Ds +431:oneChannel = 1 0.0234 0 333 -11 12 +431:addChannel = 1 0.0227 0 221 -11 12 +431:addChannel = 1 0.0081 0 331 -11 12 +431:addChannel = 1 0.0029 0 311 -11 12 +431:addChannel = 1 0.0021 0 313 -11 12 +### Lambdac +4122:oneChannel = 1 0.0356 0 3122 -11 12 +4122:oneChannel = 1 0.0009 0 2212 -321 -11 12 +4122:oneChannel = 1 0.0010 0 3124 -11 12 +4122:oneChannel = 1 0.0004 0 3126 -11 12 +### Xi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### Xi_{c}^{0} +4132:oneChannel = 1 0.0105 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +### only semileptonic decays for beauty from https://pdg.lbl.gov/2025/ +### B0 +511:oneChannel = 1 0.021000 0 12 -11 -411 +511:addChannel = 1 0.048700 0 12 -11 -413 +511:addChannel = 1 0.002300 0 12 -11 -415 +511:addChannel = 1 0.000150 0 12 -11 -211 +511:addChannel = 1 0.000294 0 12 -11 -213 +#511:addChannel = 1 0.004500 0 12 -11 -10411 +#511:addChannel = 1 0.005200 0 12 -11 -10413 +#511:addChannel = 1 0.008300 0 12 -11 -20413 +511:addChannel = 1 0.003640 0 12 -11 -421 -211 +511:addChannel = 1 0.005440 0 12 -11 -423 -211 +511:addChannel = 1 0.001450 0 12 -11 -411 -211 211 +511:addChannel = 1 0.000510 0 12 -11 -413 -211 211 + +### B+ +521:oneChannel = 1 0.000078 0 12 -11 111 +521:addChannel = 1 0.000158 0 12 -11 113 +521:addChannel = 1 0.000035 0 12 -11 221 +521:addChannel = 1 0.000119 0 12 -11 223 +521:addChannel = 1 0.000024 0 12 -11 331 +521:addChannel = 1 0.022600 0 12 -11 -421 +521:addChannel = 1 0.052600 0 12 -11 -423 +521:addChannel = 1 0.001590 0 12 -11 -425 +#521:addChannel = 1 0.000900 0 12 -11 -10421 +#521:addChannel = 1 0.002840 0 12 -11 -10423 +#521:addChannel = 1 0.001700 0 12 -11 -20423 +521:addChannel = 1 0.003820 0 12 -11 -411 211 +521:addChannel = 1 0.005420 0 12 -11 -413 211 +521:addChannel = 1 0.001730 0 12 -11 -421 -211 211 +521:addChannel = 1 0.000700 0 12 -11 -423 -211 211 +521:addChannel = 1 0.000300 0 12 -11 -431 321 +521:addChannel = 1 0.000290 0 12 -11 -433 321 + +### Bs +531:oneChannel = 1 0.000106 0 12 -11 -321 +531:addChannel = 1 0.000300 0 12 -11 -323 +531:addChannel = 1 0.022900 0 12 -11 -431 +531:addChannel = 1 0.052000 0 12 -11 -433 +531:addChannel = 1 0.007000 0 12 -11 -435 +531:addChannel = 1 0.000300 0 12 -11 -10323 +531:addChannel = 1 0.004000 0 12 -11 -10431 +531:addChannel = 1 0.007000 0 12 -11 -10433 +531:addChannel = 1 0.000200 0 12 -11 -20323 +531:addChannel = 1 0.004000 0 12 -11 -20433 + +### Lambdab +5122:oneChannel = 1 0.0546000 0 -12 11 4122 +5122:addChannel = 1 0.0096000 0 -12 11 4124 +5122:addChannel = 1 0.0128000 0 -12 11 14122 + +### Xi_{b}^{-} +5132:oneChannel = 1 0.1080010 0 -12 11 4 3101 +5132:addChannel = 1 0.0020000 0 -12 11 2 3101 +### Xi_{b}^{0} +5232:oneChannel = 1 0.1080010 0 -12 11 4 3201 +5232:addChannel = 1 0.0020000 0 -12 11 2 3201 +### Omega_{b}^{-} +5332:oneChannel = 1 0.1080010 1 -12 11 4 3303 +5332:oneChannel = 1 0.0020000 1 -12 11 2 3303 + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 + diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg new file mode 100644 index 000000000..bcac14ef5 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg @@ -0,0 +1,70 @@ +### main + +Main:timesAllowErrors 2000 +#allow more errors in the pythia. + + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +# HardQCD:hardccbar on # ccbar production +SoftQCD:inelastic = on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 + +### only semileptonic decays from https://pdg.lbl.gov/2025/ +### D+ +411:oneChannel = 1 0.0881 0 -311 -11 12 +411:addChannel = 1 0.0402 0 -321 211 -11 12 +411:addChannel = 1 0.0540 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.0354 0 -321 -11 12 +421:addChannel = 1 0.0216 0 -323 -11 12 +421:addChannel = 1 0.0160 0 -321 111 -11 12 +421:addChannel = 1 0.0144 0 -311 211 -11 12 +### Ds +431:oneChannel = 1 0.0234 0 333 -11 12 +431:addChannel = 1 0.0227 0 221 -11 12 +431:addChannel = 1 0.0081 0 331 -11 12 +431:addChannel = 1 0.0029 0 311 -11 12 +431:addChannel = 1 0.0021 0 313 -11 12 +### Lambdac +4122:oneChannel = 1 0.0356 0 3122 -11 12 +4122:oneChannel = 1 0.0009 0 2212 -321 -11 12 +4122:oneChannel = 1 0.0010 0 3124 -11 12 +4122:oneChannel = 1 0.0004 0 3126 -11 12 +### Xi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### Xi_{c}^{0} +4132:oneChannel = 1 0.0105 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh b/MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh new file mode 100644 index 000000000..6d703d179 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC24ap,aq apass1 +# + +# example anchoring +# taken from https://its.cern.ch/jira/browse/O2-5670 +export ALIEN_JDL_LPMANCHORPASSNAME=apass1 +export ALIEN_JDL_MCANCHOR=apass1 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=559348 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC24a6 +export ALIEN_JDL_LPMANCHORRUN=559348 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC24ap +export ALIEN_JDL_LPMANCHORYEAR=2024 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 20/40/40 sampling for different generators +# generate random number +#RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_5360_Gap5.sh b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_5360_Gap5.sh new file mode 100644 index 000000000..019a53415 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_5360_Gap5.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC24ap,aq apass1 +# + +# example anchoring +# taken from https://its.cern.ch/jira/browse/O2-5670 +export ALIEN_JDL_LPMANCHORPASSNAME=apass1 +export ALIEN_JDL_MCANCHOR=apass1 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=559348 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC24a6 +export ALIEN_JDL_LPMANCHORRUN=559348 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC24ap +export ALIEN_JDL_LPMANCHORYEAR=2024 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 20/40/40 sampling for different generators +# generate random number +RNDSIG=$(($RANDOM % 100)) + + +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 20 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini" +elif [[ $RNDSIG -ge 20 && $RNDSIG -lt 100 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini" +fi + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh From c33b9e8d672b7046ce4dc7e9c8c3f56983149129 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 8 May 2026 23:08:26 +0200 Subject: [PATCH 316/362] MC/PWGEM: fix typo in #2351 (#2352) --- ...8_pp_5360_bbbar_forceddecayscharmbeauty.cfg | 18 +++++++++++++----- .../pythia8_pp_5360_cr2_forceddecayscharm.cfg | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg index c3beca4d5..375c72768 100644 --- a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg @@ -32,14 +32,22 @@ BeamRemnants:saturation =5 ### only semileptonic decays from https://pdg.lbl.gov/2025/ ### D+ -411:oneChannel = 1 0.0881 0 -311 -11 12 -411:addChannel = 1 0.0402 0 -321 211 -11 12 -411:addChannel = 1 0.0540 0 -313 -11 12 +411:oneChannel = 1 0.08810 0 -311 -11 12 +#411:addChannel = 1 0.04020 0 -321 211 -11 12 # may be double counting +411:addChannel = 1 0.05400 0 -313 -11 12 +411:addChannel = 1 0.00372 0 111 -11 12 +411:addChannel = 1 0.00111 0 221 -11 12 +411:addChannel = 1 0.00187 0 113 -11 12 +411:addChannel = 1 0.00169 0 223 -11 12 +411:addChannel = 1 0.00020 0 331 -11 12 ### D0 421:oneChannel = 1 0.0354 0 -321 -11 12 421:addChannel = 1 0.0216 0 -323 -11 12 -421:addChannel = 1 0.0160 0 -321 111 -11 12 -421:addChannel = 1 0.0144 0 -311 211 -11 12 +#421:addChannel = 1 0.0160 0 -321 111 -11 12 # may be double counting +#421:addChannel = 1 0.0144 0 -311 211 -11 12 # may be double counting +421:addChannel = 1 0.00291 0 -211 -11 12 +421:addChannel = 1 0.00145 0 -211 111 -11 12 +421:addChannel = 1 0.00146 0 -213 -11 12 ### Ds 431:oneChannel = 1 0.0234 0 333 -11 12 431:addChannel = 1 0.0227 0 221 -11 12 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg index bcac14ef5..2ee27cad6 100644 --- a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg @@ -38,14 +38,22 @@ BeamRemnants:saturation =5 ### only semileptonic decays from https://pdg.lbl.gov/2025/ ### D+ -411:oneChannel = 1 0.0881 0 -311 -11 12 -411:addChannel = 1 0.0402 0 -321 211 -11 12 -411:addChannel = 1 0.0540 0 -313 -11 12 +411:oneChannel = 1 0.08810 0 -311 -11 12 +#411:addChannel = 1 0.04020 0 -321 211 -11 12 # may be double counting +411:addChannel = 1 0.05400 0 -313 -11 12 +411:addChannel = 1 0.00372 0 111 -11 12 +411:addChannel = 1 0.00111 0 221 -11 12 +411:addChannel = 1 0.00187 0 113 -11 12 +411:addChannel = 1 0.00169 0 223 -11 12 +411:addChannel = 1 0.00020 0 331 -11 12 ### D0 421:oneChannel = 1 0.0354 0 -321 -11 12 421:addChannel = 1 0.0216 0 -323 -11 12 -421:addChannel = 1 0.0160 0 -321 111 -11 12 -421:addChannel = 1 0.0144 0 -311 211 -11 12 +#421:addChannel = 1 0.0160 0 -321 111 -11 12 # may be double counting +#421:addChannel = 1 0.0144 0 -311 211 -11 12 # may be double counting +421:addChannel = 1 0.00291 0 -211 -11 12 +421:addChannel = 1 0.00145 0 -211 111 -11 12 +421:addChannel = 1 0.00146 0 -213 -11 12 ### Ds 431:oneChannel = 1 0.0234 0 333 -11 12 431:addChannel = 1 0.0227 0 221 -11 12 From 549c6ab7a80b77896b074a84096197eba68ed6d4 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 10 May 2026 21:50:25 +0200 Subject: [PATCH 317/362] Validate number of entries of tree vs branches (#2347) --- DATA/production/common/readAO2Ds.C | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/DATA/production/common/readAO2Ds.C b/DATA/production/common/readAO2Ds.C index 2574b8230..3a25e4342 100644 --- a/DATA/production/common/readAO2Ds.C +++ b/DATA/production/common/readAO2Ds.C @@ -35,6 +35,17 @@ int readAO2Ds(const char* filename = "AO2D.root") std::cout << onameKeyInDir.Data() << std::endl; } TTree* t = (TTree*)d->Get(onameKeyInDir.Data()); + // Check that every branch has the same number of entries as the tree itself. + // A mismatch indicates a corrupted or truncated write. + long long treeEntries = t->GetEntries(); + for (auto* b : *t->GetListOfBranches()) { + auto* br = (TBranch*)b; + if (br->GetEntries() != treeEntries) { + printf("MISMATCH %s/%s branch %s: tree=%lld branch=%lld\n", + onameKeyInFile.Data(), onameKeyInDir.Data(), br->GetName(), treeEntries, br->GetEntries()); + retCode |= 4; + } + } if (onameKeyInDir.BeginsWith("O2track") && !onameKeyInDir.Contains("O2tracked") && !onameKeyInDir.Contains("O2trackqa")) { vectNEntriesPerTree.push_back({onameKeyInDir.Data(), t->GetEntries()}); } From 25e1bc27c50043709ea0303b7203e87d53b48e8e Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Mon, 11 May 2026 19:09:07 +0200 Subject: [PATCH 318/362] TPC: add tpc-scalers workflow to standalone workflows --- DATA/production/calib/tpc-laser-filter.sh | 7 ++++--- DATA/production/calib/tpc-laser.sh | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/DATA/production/calib/tpc-laser-filter.sh b/DATA/production/calib/tpc-laser-filter.sh index 80a9e6b79..1bc4be8ab 100755 --- a/DATA/production/calib/tpc-laser-filter.sh +++ b/DATA/production/calib/tpc-laser-filter.sh @@ -4,7 +4,7 @@ source common/setenv.sh source common/getCommonArgs.sh -source common/gen_topo_helper_functions.sh +source common/gen_topo_helper_functions.sh FILEWORKDIR="/home/wiechula/processData/inputFilesTracking/triggeredLaser" @@ -63,7 +63,7 @@ REMAP="--condition-remap \"file://${FILEWORKDIR}=GLO/Config/GRPECS,GLO/Config/GR RECO_CONFIG="NameConf.mDirGRP=$FILEWORKDIR;" RECO_CONFIG+="NameConf.mDirGeom=$FILEWORKDIR2;" RECO_CONFIG+="NameConf.mDirCollContext=$FILEWORKDIR;" -RECO_CONFIG+="NameConf.mDirMatLUT=$FILEWORKDIR;" +RECO_CONFIG+="NameConf.mDirMatLUT=$FILEWORKDIR;" RECO_CONFIG+="align-geom.mDetectors=none;" RECO_CONFIG+="GPU_global.deviceType=$GPUTYPE;" RECO_CONFIG+="GPU_proc.tpcIncreasedMinClustersPerRow=500000;" @@ -81,7 +81,8 @@ RECO_CONFIG+="GPU_rec_tpc.trackFollowingMaxRowGap=15;GPU_rec_tpc.trackFollowingM WORKFLOW= add_W o2-dpl-raw-proxy "--dataspec \"$PROXY_INSPEC\" --inject-missing-data --channel-config \"name=readout-proxy,type=pull,method=connect,address=ipc://@tf-builder-pipe-0,transport=shmem,rateLogging=1\"" "" 0 add_W o2-tpc-raw-to-digits-workflow "--ignore-grp --input-spec \"$CALIB_INSPEC\" --remove-duplicates --pipeline tpc-raw-to-digits-0:20 --send-ce-digits " "${RAWDIGIT_CONFIG}" -add_W o2-tpc-reco-workflow " ${TPC_CORR_SCALING:-} --disable-ctp-lumi-request --input-type digitizer --output-type \"tracks,disable-writer,clusters\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP} " "${RECO_CONFIG}" +add_W o2-tpc-scaler-workflow "--disable-IDC-scalers --disable-ctp-lumi-request" +add_W o2-tpc-reco-workflow " --input-type digitizer --output-type \"tracks,disable-writer,clusters\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP} " "${RECO_CONFIG}" add_W o2-tpc-laser-track-filter "" "" 0 add_W o2-dpl-output-proxy " --proxy-name tpc-laser-input-proxy --proxy-channel-name tpc-laser-input-proxy --dataspec \"$PROXY_OUTSPEC\" --channel-config \"name=tpc-laser-input-proxy,method=connect,type=push,transport=zeromq,rateLogging=0\" " "" 0 add_QC_from_apricot "${QC_CONFIG}" "--local --host localhost" diff --git a/DATA/production/calib/tpc-laser.sh b/DATA/production/calib/tpc-laser.sh index b859d440d..0ace43717 100755 --- a/DATA/production/calib/tpc-laser.sh +++ b/DATA/production/calib/tpc-laser.sh @@ -4,7 +4,7 @@ source common/setenv.sh source common/getCommonArgs.sh -source common/gen_topo_helper_functions.sh +source common/gen_topo_helper_functions.sh FILEWORKDIR="/home/wiechula/processData/inputFilesTracking/triggeredLaser" @@ -77,7 +77,7 @@ if [[ ! -z ${TPC_CALIB_LANES_PAD_RAW:-} ]]; then num_lanes=${TPC_CALIB_LANES_PAD_RAW} fi -EXTRA_CONFIG="--calib-type ce --publish-after-tfs ${publish_after} --max-events ${max_events} --lanes ${num_lanes} --check-calib-infos" +EXTRA_CONFIG="--calib-type ce --publish-after-tfs ${publish_after} --max-events ${max_events} --lanes ${num_lanes} --check-calib-infos" LASER_DECODER_ADD='' @@ -100,7 +100,8 @@ RECO_CONFIG+="GPU_rec_tpc.trackFollowingMaxRowGap=15;GPU_rec_tpc.trackFollowingM WORKFLOW= add_W o2-dpl-raw-proxy "--dataspec \"$PROXY_INSPEC\" --inject-missing-data --channel-config \"name=readout-proxy,type=pull,method=connect,address=ipc://@tf-builder-pipe-0,transport=shmem,rateLogging=1\"" "" 0 add_W o2-tpc-raw-to-digits-workflow "--ignore-grp --input-spec \"$CALIB_INSPEC\" --remove-duplicates --pipeline tpc-raw-to-digits-0:20 --send-ce-digits " "${RAWDIGIT_CONFIG}" -add_W o2-tpc-reco-workflow " --disable-ctp-lumi-request --input-type digitizer --output-type \"tracks,disable-writer\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP}" "${RECO_CONFIG}" +add_W o2-tpc-scaler-workflow "--disable-IDC-scalers --disable-ctp-lumi-request" +add_W o2-tpc-reco-workflow "--input-type digitizer --output-type \"tracks,disable-writer\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP}" "${RECO_CONFIG}" add_W o2-tpc-laser-track-filter "" "" 0 add_W o2-tpc-calib-laser-tracks "--use-filtered-tracks ${EXTRA_CONFIG_TRACKS} --min-tfs=${min_tracks}" add_W o2-tpc-calib-pad-raw " ${EXTRA_CONFIG}" "${CALIB_CONFIG}" From 8867bb9c89982e02fef5e5b532bda568f207a407 Mon Sep 17 00:00:00 2001 From: Nicole Bastid <75683312+NicoleBastid@users.noreply.github.com> Date: Fri, 15 May 2026 16:09:25 +0200 Subject: [PATCH 319/362] PWGHF: beauty production with natural decay at forward rapidity (#2353) * Add files via upload add a new .cfg for natural decay with PYTHIA8 Mode 2 * Add files via upload new .ini file for beauty with natural decay at forward rapidity * Add files via upload .C file for beauty with natural decay at forward rapidity --- ...orHF_bbbar_fwd_gap4_natural_inel_Mode2.ini | 9 ++ ...atorHF_bbbar_fwd_gap4_natural_inel_Mode2.C | 103 ++++++++++++++++++ .../pythia8/generator/pythia8_inel_Mode2.cfg | 38 +++++++ 3 files changed, 150 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.ini new file mode 100644 index 000000000..a2b849bc3 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(4, -4.3, -2.2) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg +includePartonEvent=true + \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.C new file mode 100644 index 000000000..34072820e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.C @@ -0,0 +1,103 @@ +int External() { + + int checkPdgDecayMuon = 13; + int checkPdgQuark = 5; + + float ratioTrigger = 1. / 4; // one event triggered out of 4 + + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}; + int nEventsInj{}; + int nQuarks{}; + int nMuons{}; + + int nMuonsInAcceptance{}; + + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } // if event header + + int nmuonsev = 0; + int nmuonsevinacc = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } // pdgquark + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayMuon) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nMuons++; + nmuonsev++; + if (-4.3 < y && y < -2.2) { + nMuonsInAcceptance++; + nmuonsevinacc++; + } + } // gmpdg + + } // pdgdecay + + } // loop track + // std::cout << "#muons per event: " << nmuonsev << "\n"; + // std::cout << "#muons in acceptance per event: " << nmuonsev << "\n"; + } // events + + std::cout << "#events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) + << nEventsInj << "\n"; + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || + nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark + << " different than expected\n"; + return 1; + } + std::cout << "#muons: " << nMuons << "\n"; + std::cout << "#muons in acceptance: " << nMuonsInAcceptance << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg new file mode 100644 index 000000000..b022e3612 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg @@ -0,0 +1,38 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + From 0ae184a3467d7c864789d7f9a88d0fd1b83847c0 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 18 May 2026 15:18:25 +0200 Subject: [PATCH 320/362] Expand o2-analysis-qa-event-track.json configuration (#2321) --- .../json/dpl/o2-analysis-qa-event-track.json | 145 ++++++++++++++++-- 1 file changed, 135 insertions(+), 10 deletions(-) diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json b/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json index 07aacee70..0c4adc582 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json @@ -1,13 +1,138 @@ { "qa-event-track": { - "checkOnlyPVContributor": "true", - "overwriteAxisRangeForPbPb": "!OVERWRITEAXISRANGEFORPBPBVALUE!", - "processData": "!ANALYSIS_QC_is_data!", - "processDataIU": "false", - "processDataIUFiltered": "false", - "processMC": "!ANALYSIS_QC_is_mc!", - "processTableData": "false", - "processTableMC": "false", - "trackSelection": "1" - } + "maxEta": "2", + "checkOnlyPVContributor": "1", + "minPhi": "-1", + "binsPt": { + "values": [ + 0, + 0, + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8, + 0.9, + 1, + 1.1, + 1.2, + 1.3, + 1.4, + 1.5, + 2, + 5, + 10, + 20, + 50 + ] + }, + "minPt": "-10", + "selectPrim": "0", + "selectSec": "0", + "forceTRD": "0", + "processDataIU": "0", + "doDebug": "0", + "minTPCcrossedRows": "70", + "processTrackMatch": "!ANALYSIS_QC_is_data!", + "binsDeltaPt": { + "values": [ + 100, + -0.495, + 0.505 + ] + }, + "selectPID": "0", + "PartIdentifier": "2", + "forceNotTRD": "0", + "binsInvPt": { + "values": [ + 0, + 0, + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8, + 0.9, + 1, + 1.1, + 1.2, + 1.3, + 1.4, + 1.5, + 2, + 5, + 10, + 20, + 50 + ] + }, + "minEta": "-2", + "doExtraPIDqa": "0", + "tfCut": "1", + "processRun2ConvertedData": "0", + "addRunInfo": "1", + "maxPhi": "10", + "binsVertexPosZ": { + "values": [ + 100, + -20, + 20 + ] + }, + "selectGoodEvents": "1", + "maxPt": "1e+10", + "binsDeltaSigned1Pt": { + "values": [ + 100, + -0.495, + 0.505 + ] + }, + "binsSigned1Pt": { + "values": [ + 300, + -5, + 5 + ] + }, + "binsVertexNumContrib": { + "values": [ + 200, + 0, + 200 + ] + }, + "binsTrackMultiplicity": { + "values": [ + 1000, + 0, + 1000 + ] + }, + "checkFakeMatches": "0", + "overwriteAxisRangeForPbPb": "!OVERWRITEAXISRANGEFORPBPBVALUE!", + "activateChecksTRD": "0", + "binsVertexPosXY": { + "values": [ + 500, + -1, + 1 + ] + }, + "processData": "!ANALYSIS_QC_is_data!", + "trackSelection": "1", + "selectCharge": "0", + "checkPIDforTracking": "0", + "processRun2ConvertedMC": "0", + "isRun3": "1", + "processMC": "!ANALYSIS_QC_is_mc!", + "processDataIUFiltered": "0" + } } From e82b065a77242a3feff1ce215fd2023ee132e3e9 Mon Sep 17 00:00:00 2001 From: Francesca Ercolessi Date: Tue, 19 May 2026 13:56:12 +0200 Subject: [PATCH 321/362] [PWGLF] add new config files for Deuteron production in pythia at pp 5.36 TeV (#2357) * Add Pythia coal with pp 5.36 TeV config * Add Pythia INEL with pp 5.36 TeV config --- .../PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini | 6 ++++ .../PWGLF/ini/GeneratorLF_pp536_wDeInel.ini | 6 ++++ .../ini/tests/GeneratorLF_pp536_wDeCoal.C | 28 +++++++++++++++++++ .../ini/tests/GeneratorLF_pp536_wDeInel.C | 28 +++++++++++++++++++ .../generator/pythia8_inel_536tev_wDeCoal.cfg | 23 +++++++++++++++ .../generator/pythia8_inel_536tev_wDeInel.cfg | 19 +++++++++++++ 6 files changed, 110 insertions(+) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini create mode 100644 MC/config/PWGLF/ini/GeneratorLF_pp536_wDeInel.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeCoal.C create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeInel.C create mode 100644 MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg create mode 100644 MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini new file mode 100644 index 000000000..126aa66ca --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeInel.ini b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeInel.ini new file mode 100644 index 000000000..10d233002 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeInel.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeCoal.C b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeCoal.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeCoal.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeInel.C b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeInel.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeInel.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg new file mode 100644 index 000000000..6ad09b191 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# enable deuteron production by coalescence collisions +HadronLevel:DeuteronProduction = on +DeuteronProduction:channels = {2212 2112 > 22} +DeuteronProduction:models = {0} +DeuteronProduction:norm = 1 +DeuteronProduction:parms = {0.195 1} diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg new file mode 100644 index 000000000..b1154ea4f --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg @@ -0,0 +1,19 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# enable deuteron production by inelastic collisions +HadronLevel:DeuteronProduction = on From 9cb9cf9a76841a155169711ba73c4443758b3e2d Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 19 May 2026 13:53:07 +0200 Subject: [PATCH 322/362] workflow-multiplicities.sh: adjusting default ITS multiplicity cuts for PbPb --- DATA/production/workflow-multiplicities.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DATA/production/workflow-multiplicities.sh b/DATA/production/workflow-multiplicities.sh index cc6a2abcc..213eeb2e1 100644 --- a/DATA/production/workflow-multiplicities.sh +++ b/DATA/production/workflow-multiplicities.sh @@ -301,8 +301,8 @@ if [[ "$HIGH_RATE_PP" == "1" ]]; then : ${CUT_RANDOM_FRACTION_ITS:=0.97} elif [[ $BEAMTYPE == "PbPb" ]]; then : ${CUT_RANDOM_FRACTION_ITS:=-1} - : ${CUT_MULT_MIN_ITS:=100} - : ${CUT_MULT_MAX_ITS:=200} + : ${CUT_MULT_MIN_ITS:=0} + : ${CUT_MULT_MAX_ITS:=400} : ${CUT_MULT_VTX_ITS:=20} else : ${CUT_RANDOM_FRACTION_ITS:=0.95} From caafdc54d2933f6e3e054c914a4e4d1b41c0a4bc Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Tue, 19 May 2026 15:56:51 +0200 Subject: [PATCH 323/362] production.desc: increase number of calib cores for TPC_CMV collection to 128 --- DATA/production/production.desc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/production/production.desc b/DATA/production/production.desc index d12b00d4d..0691ccdeb 100644 --- a/DATA/production/production.desc +++ b/DATA/production/production.desc @@ -1,3 +1,3 @@ synchronous-workflow: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 production/dpl-workflow.sh" synchronous-workflow-1numa: "O2PDPSuite" reco,128,126,"SYNCMODE=1 production/dpl-workflow.sh" -synchronous-workflow-calib: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_TF SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_SPORADIC SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_IDCBOTH_SAC SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,64,"AGGREGATOR_TASKS=TPC_CMV SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" +synchronous-workflow-calib: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_TF SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_SPORADIC SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_IDCBOTH_SAC SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_CMV SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" From d683d77c91370ec1374babcde7f7c07228e4ce05 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 20 May 2026 01:14:35 +0200 Subject: [PATCH 324/362] TPC series workflow can be added with TPC only --- DATA/common/setenv_calib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index 26bb86deb..b44de438a 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -34,7 +34,7 @@ if [[ $SYNCMODE == 1 ]] && has_processing_step ENTROPY_ENCODER && [[ ! -z "$WORK # for async recalibration if has_detector_calib EMC && has_detector_reco EMC && [[ $SYNCMODE != 1 ]]; then CAN_DO_CALIB_EMC_ASYNC_RECALIB=1; else CAN_DO_CALIB_EMC_ASYNC_RECALIB=0; fi if [[ $SYNCMODE != 1 ]] && has_detector_reco TPC; then CAN_DO_CALIB_ASYNC_EXTRACTTPCCURRENTS=1; else CAN_DO_CALIB_ASYNC_EXTRACTTPCCURRENTS=0; fi -if [[ $SYNCMODE != 1 ]] && has_detector_reco TPC && has_detector_reco ITS && has_detector_reco FT0; then CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=1; else CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=0; fi +if [[ $SYNCMODE != 1 ]] && has_detector_reco TPC; then CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=1; else CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=0; fi # additional individual settings for calibration workflows if has_detector CTP; then export CALIB_TPC_SCDCALIB_CTP_INPUT="--enable-ctp"; else export CALIB_TPC_SCDCALIB_CTP_INPUT=""; fi From b11cd3de0fdcf7659e7f909129e75c7e154266d6 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 19 May 2026 18:27:22 +0200 Subject: [PATCH 325/362] AODBcRewriter: fix paste-join children after row reorder/dedup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Paste-joined ("implicit-join") tables — row N of the child matches row N of the parent — must keep equal row counts and have embedded index columns remapped when the parent is reordered or deduped. Two bugs fixed: 1. O2mccollisionlabel was routed through Stage 2 because it carries fIndexMcCollisions; Stage 2 then sorted and dropped rows whose MC collision was dedup'd, breaking the 1:1 join with O2collision and crashing downstream consumers on the misaligned tables. 2. The SOA SLICE_INDEX_COLUMN fIndexSliceBCs[2]/I — present only on O2ambiguous{track,mfttr,fwdtr}, which Stage 1 does not touch — was never remapped after BC dedup, so slice endpoints pointed past the compacted BC table. Stage 2 now defers paste-join children to the paste-join handler, which preserves the parent's row order and applies value-wise remaps for fIndexMcCollisions / fIndexCollisions / fIndexSliceBCs / fIndexBCs / fIndexBC via the existing ExtraRemap path. bcPerm is passed as an explicit argument to avoid an unordered_map iteration- order side effect that broke O2mccalolabel -> O2calo prefix lookup. kPasteJoins extended to all pairs documented in AnalysisDataModel.h (adds O2bcflag/O2bc, O2mccalolabel/O2calo, O2trackcov_iu/O2track_iu, O2trackextra/O2track_iu, O2fwdtrackcov/O2fwdtrack). AODBcRewriterValidate gains paste-join row-count parity checks and a generic fIndex* range check (kIndexBranchToTable) that handles scalar, fixed-size, and VLA branches uniformly. CLAUDE.md updated. Co-Authored-By: Claude Opus 4.7 --- MC/utils/AODBcRewriter.C | 317 ++++++++++++++++++++++++++++++++------- MC/utils/CLAUDE.md | 281 ++++++++++++++++++++++++++++++++++ 2 files changed, 543 insertions(+), 55 deletions(-) create mode 100644 MC/utils/CLAUDE.md diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C index c8b5cd6df..c6ff68879 100644 --- a/MC/utils/AODBcRewriter.C +++ b/MC/utils/AODBcRewriter.C @@ -132,6 +132,45 @@ static const char *collIndexBranch(TTree *t) { return nullptr; } +// ---------------------------------------------------------------------------- +// Paste-join relationships (authoritative; derived from AnalysisDataModel.h +// comments such as "Table joined to the collision table containing the MC +// index" and from the SOA EXTENDED_TABLE declarations for cov / extra tables). +// +// A paste-joined CHILD has NO row of its own — its row N corresponds to row N +// of its PARENT. If the parent is reordered or has rows dropped, the child +// must follow row-for-row to preserve the 1:1 alignment. Any index columns +// the child carries (e.g. fIndexMcCollisions in O2mccollisionlabel) are then +// remapped *value-wise* via the appropriate parent stage's permutation, but +// rows are NEVER added or dropped on the child's own initiative. +// +// Matching uses TString::BeginsWith on the child name; parent matching uses +// allPerms keys (so versioned names like O2collision_001 resolve via prefix). +// When several parent candidates are listed for the same child, the first one +// found in allPerms wins (this lets us prefer O2track_iu over O2track). +static const std::vector> kPasteJoins = { + // { paste-joined child prefix, parent prefix } + { "O2bcflag", "O2bc" }, // BCFlags joinable with BCs + { "O2mccollisionlabel", "O2collision" }, // McCollisionLabels -> Collisions + { "O2mctracklabel", "O2track_iu" }, // McTrackLabels -> Tracks (prefer _iu) + { "O2mctracklabel", "O2track" }, + { "O2mcfwdtracklabel", "O2fwdtrack" }, // McFwdTrackLabels -> FwdTracks + { "O2mcmfttracklabel", "O2mfttrack" }, // McMFTTrackLabels -> MFTTracks + { "O2mccalolabel", "O2calo" }, // McCaloLabels -> Calos + { "O2trackcov_iu", "O2track_iu" }, // TracksCovIU -> TracksIU (cov) + { "O2trackextra", "O2track_iu" }, // TracksExtra -> TracksIU + { "O2fwdtrackcov", "O2fwdtrack" }, // FwdTracksCov -> FwdTracks + // Note: O2mfttrackcov has its own fIndexMFTTracks column — it is NOT + // paste-joined and must NOT be listed here. +}; + +// True if the given tree name matches any registered paste-join child prefix. +static bool isPasteJoinChild(const std::string &tname) { + for (auto &kv : kPasteJoins) + if (TString(tname.c_str()).BeginsWith(kv.first.c_str())) return true; + return false; +} + // ============================================================================ // SECTION 2 — Generic ROOT branch I/O helpers // ============================================================================ @@ -691,6 +730,16 @@ stage2_MCCollIndexedTables(TDirectory *dirIn, TDirectory *dirOut, const char *idxBr = mcCollIndexBranch(src); if (!idxBr) continue; + // A paste-join child (e.g. O2mccollisionlabel) MUST follow its parent's + // row order and never drop rows on its own. Defer it to + // processPasteJoinTables, which will remap any of its own index columns + // (fIndexMcCollisions, ...) value-wise without touching the row count. + if (isPasteJoinChild(tname)) { + std::cout << " Stage2: deferring paste-join child " << tname + << " to paste-join handler\n"; + continue; + } + std::cout << " Stage2 [MCColl-indexed]: " << tname << "\n"; Long64_t nSrc = src->GetEntries(); @@ -760,20 +809,23 @@ stage2_MCCollIndexedTables(TDirectory *dirIn, TDirectory *dirOut, // SECTION 8 — Paste-join table handling // ============================================================================ // -// A paste-joined table has NO index column. Its row N corresponds to row N -// of its parent table. When the parent is reordered, the paste-join table -// must follow with the identical row permutation. +// A paste-joined CHILD has no row of its own — its row N corresponds to row N +// of its PARENT table. When the parent is reordered, the child must follow +// row-for-row to preserve the 1:1 alignment. Paste-join children may still +// carry their own index columns; those values are remapped in-place via the +// appropriate parent-stage permutation. // -// Known paste-join relationships in the AO2D data model -// (parent table prefix -> paste-joined table prefix): +// The list of paste-join pairs is in kPasteJoins (Section 1). // -// O2collision_* -> O2mccollisionlabel_* -// O2track_* -> O2mctracklabel_* -// O2trackiu_* -> O2mctracklabel_* (alternative track table) -// O2fwdtrack_* -> O2mcfwdtracklabel_* -// O2mfttrack_* -> O2mcmfttracklabel_* +// Index columns we know how to remap in a child: +// fIndexMcCollisions -> via mcCollPerm +// fIndexCollisions -> via collPerm +// fIndexMcParticles -> via mcParticlePerm +// fIndexArrayMcParticles -> via mcParticlePerm (VLA) // -// The PermMap from the parent stage is used directly as the row order. +// When the named parent is not in allPerms (e.g. tracks aren't reordered in +// this build), the child is processed with identity row order so the +// value-wise remaps still apply but the row order is unchanged. // Build the row order from a PermMap (srcRow -> outRow), inverted. static std::vector rowOrderFromPerm(const PermMap &perm) { @@ -790,34 +842,35 @@ static std::vector rowOrderFromPerm(const PermMap &perm) { return order; } -// The paste-join map: paste-joined table prefix -> parent table prefix -// We match by prefix (BeginsWith) because table names carry a numeric suffix. -static const std::vector> kPasteJoins = { - // { paste-joined prefix, parent prefix } - { "O2mccollisionlabel", "O2collision" }, - { "O2mctracklabel", "O2track" }, - { "O2mctracklabel", "O2trackiu" }, // same label table, alt parent - { "O2mcfwdtracklabel", "O2fwdtrack" }, - { "O2mcmfttracklabel", "O2mfttrack" }, -}; - -static void processPasteJoinTables( - TDirectory *dirIn, TDirectory *dirOut, +// Locate a permutation in allPerms whose key begins with a given prefix. +// Returns nullptr if none found. +static const PermMap *findPermByPrefix( const std::unordered_map &allPerms, - const std::unordered_set &alreadyWritten) { - - // Find the MC-particle permutation (produced by stage2 for O2mcparticle_*). - // Label tables (O2mctracklabel, O2mcfwdtracklabel, O2mcmfttracklabel, - // O2mccalolabel) carry fIndexMcParticles / fIndexArrayMcParticles that must - // be remapped via this permutation regardless of whether the label table's - // row order changes. - const PermMap *mcParticlePerm = nullptr; + const char *prefix, + std::string *foundName = nullptr) { for (auto &[name, perm] : allPerms) { - if (TString(name.c_str()).BeginsWith("O2mcparticle")) { - mcParticlePerm = &perm; - break; + if (TString(name.c_str()).BeginsWith(prefix)) { + if (foundName) *foundName = name; + return &perm; } } + return nullptr; +} + +static void processPasteJoinTables( + TDirectory *dirIn, TDirectory *dirOut, + const std::unordered_map &allPerms, + const std::unordered_set &alreadyWritten, + const PermMap *bcPermP = nullptr) { + + // Pre-locate the parent permutations that paste-join children may want to + // apply to their own index columns. Any of these may legitimately be null + // (e.g. mcParticlePerm absent if there is no O2mcparticle in this DF). + const PermMap *mcParticlePerm = findPermByPrefix(allPerms, "O2mcparticle"); + const PermMap *mcCollPermP = findPermByPrefix(allPerms, "O2mccollision_"); + const PermMap *collPermP = findPermByPrefix(allPerms, "O2collision_"); + // bcPermP is passed in from processDF (the BC table is the only stage + // whose permutation isn't already published in allPerms). TIter it(dirIn->GetListOfKeys()); while (TKey *key = static_cast(it())) { @@ -829,10 +882,14 @@ static void processPasteJoinTables( std::string tname = src->GetName(); if (alreadyWritten.count(tname)) continue; if (isBCTable(tname.c_str())) continue; - if (bcIndexBranch(src) || mcCollIndexBranch(src)) continue; - - // Build extra remaps for any fIndexMcParticles / fIndexArrayMcParticles - // branches in this table (label tables pointing into O2mcparticle). + // Stage-1 BC-indexed and Stage-2 MCColl-indexed non-paste-join tables are + // already in alreadyWritten. A paste-join child carrying its own MCColl + // index (e.g. O2mccollisionlabel) was deferred from stage2 and lands here. + if (bcIndexBranch(src)) continue; + if (mcCollIndexBranch(src) && !isPasteJoinChild(tname)) continue; + + // Build value-wise extra remaps for any index column this table carries + // that points into a table whose row order may have changed. std::vector extraRemaps; if (mcParticlePerm) { if (src->GetBranch("fIndexMcParticles")) @@ -840,19 +897,32 @@ static void processPasteJoinTables( if (src->GetBranch("fIndexArrayMcParticles")) extraRemaps.push_back({"fIndexArrayMcParticles", mcParticlePerm}); } + if (mcCollPermP && src->GetBranch("fIndexMcCollisions")) + extraRemaps.push_back({"fIndexMcCollisions", mcCollPermP}); + if (collPermP && src->GetBranch("fIndexCollisions")) + extraRemaps.push_back({"fIndexCollisions", collPermP}); + if (bcPermP) { + // BC-pointing indices that weren't already remapped in Stage 1. + // Stage-1 BC-indexed tables (with fIndexBCs / fIndexBC) are in + // alreadyWritten by now, so this only fires for tables that escaped + // Stage 1 — chiefly the O2ambiguous* family, which carries the SOA + // SLICE_INDEX_COLUMN(BC, bc) stored on disk as fIndexSliceBCs[2]/I. + // After BC dedup the slice endpoints would otherwise point past the + // compacted BC table; remapping through bcPerm fixes this. + if (src->GetBranch("fIndexSliceBCs")) + extraRemaps.push_back({"fIndexSliceBCs", bcPermP}); + if (src->GetBranch("fIndexBCs")) + extraRemaps.push_back({"fIndexBCs", bcPermP}); + if (src->GetBranch("fIndexBC")) + extraRemaps.push_back({"fIndexBC", bcPermP}); + } - // Check if this is a known paste-join table + // Find a paste-join parent for this table (kPasteJoins lookup). const PermMap *parentPerm = nullptr; std::string parentName; for (auto &[pastePrefix, parentPrefix] : kPasteJoins) { if (!TString(tname.c_str()).BeginsWith(pastePrefix.c_str())) continue; - for (auto &[pname, perm] : allPerms) { - if (TString(pname.c_str()).BeginsWith(parentPrefix.c_str())) { - parentPerm = &perm; - parentName = pname; - break; - } - } + parentPerm = findPermByPrefix(allPerms, parentPrefix.c_str(), &parentName); if (parentPerm) break; } @@ -870,10 +940,11 @@ static void processPasteJoinTables( } else { rewriteTable(src, dirOut, rowOrder, "", {}, extraRemaps); } - } else if (!extraRemaps.empty()) { - // Not paste-joined but has indices that need remapping (e.g. O2mccalolabel - // which is not in kPasteJoins but carries fIndexArrayMcParticles). - std::cout << " Remap-only: " << tname << "\n"; + } else if (!extraRemaps.empty() || isPasteJoinChild(tname)) { + // Parent wasn't reordered (or not present in this DF) — keep row order + // identical but still apply value-wise index remaps and follow the + // paste-join 1:1 invariant by going through the identity row order. + std::cout << " Identity-order remap: " << tname << "\n"; Long64_t n = src->GetEntries(); std::vector identity(n); std::iota(identity.begin(), identity.end(), 0LL); @@ -986,7 +1057,7 @@ static void processDF(TDirectory *dirIn, TDirectory *dirOut) { // ---- Paste-join tables + unrelated tables ---- std::cout << "-- Paste-join and unrelated tables --\n"; - processPasteJoinTables(dirIn, dirOut, stage1Perms, written); + processPasteJoinTables(dirIn, dirOut, stage1Perms, written, &s0.bcPerm); // ---- Non-tree objects (TMap metadata) ---- copyNonTreeObjects(dirIn, dirOut); @@ -1002,14 +1073,109 @@ static void processDF(TDirectory *dirIn, TDirectory *dirOut) { // 1. BC table is strictly monotonic in fGlobalBC. // 2. MC particle intra-table daughter/mother indices are in range and point // to particles belonging to the same MC collision. -// 3. fIndexMcParticles in label tables is in range. +// 3. Every paste-joined child table has the same row count as its parent +// (e.g. O2mccollisionlabel matches O2collision). +// 4. Every fIndex* value across the DF is in range w.r.t. its referent +// table (value -1 is always permitted as the "no link" sentinel). // -// Returns true if all checks pass. Prints a summary to stdout. +// Returns true if all checks pass. Prints [FAIL] lines for each violation. + +// Map from fIndex* branch name to the table-name prefix it refers to. The +// match on the referent side uses TString::BeginsWith so versioned suffixes +// (O2collision_001, O2bc_001, ...) are handled. Branches not in this list +// are skipped by the range check (this includes O2mcparticle's intra-table +// fIndexArray_Mothers / fIndexSlice_Daughters, which are checked separately +// with stricter semantics in the MC-particle block). +static const std::vector> kIndexBranchToTable = { + { "fIndexBCs", "O2bc_" }, + { "fIndexBC", "O2bc_" }, + { "fIndexSliceBCs", "O2bc_" }, + { "fIndexCollisions", "O2collision_" }, + { "fIndexCollision", "O2collision_" }, + { "fIndexMcCollisions", "O2mccollision_" }, + { "fIndexMcParticles", "O2mcparticle" }, + { "fIndexArrayMcParticles", "O2mcparticle" }, + { "fIndexTracks", "O2track_iu" }, + { "fIndexTracks_0", "O2track_iu" }, + { "fIndexTracks_1", "O2track_iu" }, + { "fIndexTracks_2", "O2track_iu" }, + { "fIndexTracks_Pos", "O2track_iu" }, + { "fIndexTracks_Neg", "O2track_iu" }, + { "fIndexTracks_ITS", "O2track_iu" }, + { "fIndexFwdTracks", "O2fwdtrack" }, + { "fIndexFwdTracks_MatchMCHTrack", "O2fwdtrack" }, + { "fIndexMFTTracks", "O2mfttrack" }, + { "fIndexV0s", "O2v0_" }, + { "fIndexCascades", "O2cascade_" }, + { "fIndexDecay3Bodys", "O2decay3body" }, +}; + +// Find a tree in d whose name begins with the given prefix. Returns the +// number of entries, or -1 if not found. +static Long64_t treeEntriesByPrefix(TDirectory *d, const char *prefix) { + TIter it(d->GetListOfKeys()); + TKey *k; + while ((k = (TKey*)it())) { + if (!TString(k->GetName()).BeginsWith(prefix)) continue; + TObject *obj = d->Get(k->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + return ((TTree*)obj)->GetEntries(); + } + return -1; +} + +// Generic in-range check for every fIndex* branch listed above. Reads the +// branch's leaf (scalar, fixed-array, or VLA), iterates all entries, and +// counts how many values are outside [-1, nReferent). +static Long64_t checkIndexRange(TTree *t, const char *branchName, + Long64_t nReferent) { + TBranch *br = t->GetBranch(branchName); + if (!br) return 0; + TLeaf *leaf = (TLeaf*)br->GetListOfLeaves()->At(0); + if (!leaf) return 0; + if (TString(leaf->GetTypeName()) != "Int_t") return 0; // only Int_t indices + + TLeaf *cntLeaf = leaf->GetLeafCount(); // VLA? + int fixedN = leaf->GetLen(); // 1 for scalar, >1 for fixed array + + // Allocate worst-case buffer. For a VLA we need a prescan to size it. + Long64_t maxLen = fixedN; + if (cntLeaf) { + // simple prescan + Int_t cnt = 0; + TBranch *cntBr = cntLeaf->GetBranch(); + cntBr->SetAddress(&cnt); + for (Long64_t i = 0; i < t->GetEntries(); ++i) { + cntBr->GetEntry(i); + if (cnt > maxLen) maxLen = cnt; + } + } + std::vector buf(std::max(1, maxLen), 0); + Int_t cnt = fixedN; + TBranch *cntBr = cntLeaf ? cntLeaf->GetBranch() : nullptr; + br->SetAddress(buf.data()); + if (cntBr) cntBr->SetAddress(&cnt); + + Long64_t bad = 0; + for (Long64_t i = 0; i < t->GetEntries(); ++i) { + br->GetEntry(i); + if (cntBr) cntBr->GetEntry(i); + int n = cntBr ? (int)cnt : fixedN; + for (int j = 0; j < n; ++j) { + Int_t v = buf[j]; + if (v < -1) { ++bad; continue; } + if (v >= (Int_t)nReferent) { ++bad; continue; } + } + } + br->ResetAddress(); + if (cntBr) cntBr->ResetAddress(); + return bad; +} static bool validateDF(TDirectory *d) { bool ok = true; - // ---- BC monotonicity ---- + // ---- discover key trees ---- TIter it(d->GetListOfKeys()); TKey *k; TTree *bcTree = nullptr; @@ -1084,6 +1250,47 @@ static bool validateDF(TDirectory *d) { mcpTree->SetBranchStatus("*", 1); } + // ---- Paste-join row-count parity ---- + // For every (child, parent) pair in kPasteJoins, if both are present in the + // DF their row counts must be identical. This catches the class of bugs + // where a child was sorted/dropped on its own index (e.g. a previous + // version dropped O2mccollisionlabel rows on MC-collision dedup while + // leaving O2collision_001 intact, producing an off-by-N mismatch). + for (auto &[childPrefix, parentPrefix] : kPasteJoins) { + Long64_t nChild = treeEntriesByPrefix(d, childPrefix.c_str()); + Long64_t nParent = treeEntriesByPrefix(d, parentPrefix.c_str()); + if (nChild < 0 || nParent < 0) continue; // pair not both present + if (nChild != nParent) { + std::cerr << " [FAIL] paste-join size mismatch: " << childPrefix << "*" + << " has " << nChild << " rows but parent " << parentPrefix << "*" + << " has " << nParent << "\n"; + ok = false; + } + } + + // ---- Generic fIndex* range check ---- + // For each table in the DF, scan all fIndex* branches and confirm every + // value lies in [-1, nReferent). This catches stale pointers across + // tables (cross-table index drift) which a per-DF-tree-only check misses. + TIter it2(d->GetListOfKeys()); + TKey *k2; + while ((k2 = (TKey*)it2())) { + TObject *obj = d->Get(k2->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + TTree *t = (TTree*)obj; + for (auto &[branchName, referentPrefix] : kIndexBranchToTable) { + if (!t->GetBranch(branchName.c_str())) continue; + Long64_t nRef = treeEntriesByPrefix(d, referentPrefix.c_str()); + if (nRef < 0) continue; // referent not in this DF; skip silently + Long64_t bad = checkIndexRange(t, branchName.c_str(), nRef); + if (bad > 0) { + std::cerr << " [FAIL] " << t->GetName() << "." << branchName + << ": " << bad << " value(s) out of range [-1, " << nRef << ")\n"; + ok = false; + } + } + } + return ok; } diff --git a/MC/utils/CLAUDE.md b/MC/utils/CLAUDE.md new file mode 100644 index 000000000..0ff309146 --- /dev/null +++ b/MC/utils/CLAUDE.md @@ -0,0 +1,281 @@ +# CLAUDE.md — AODBcRewriter Development Handoff + +## What this tool does + +`AODBcRewriter.C` is a ROOT macro that fixes structural integrity problems in +ALICE Run3 AO2D files after merging. AO2D files are ROOT files containing +`DF_*` subdirectories, each holding a set of TTrees that form a relational +schema (similar to a database). After merging two AO2D files with `hadd` or +similar tools, three problems can arise: + +1. **Non-monotonic `fGlobalBC`** in the BC table — the framework requires + strictly increasing values. +2. **Duplicate `fGlobalBC` entries** — the same bunch crossing represented by + multiple rows. +3. **Duplicate MCCollision entries** — the same MC event appearing twice + because it was present in both source files before merging. + +Run with: +```bash +root -l -b -q 'AODBcRewriter.C("AO2D.root","AO2D_rewritten.root")' +``` + +--- + +## AO2D data model (relevant subset) + +The tables form a dependency graph. Every stage of the tool processes one +level of this graph and produces a **PermMap** (`vector`, +`permMap[oldRow] = newRow`, -1 = row dropped) which the next stage consumes. + +``` +BCs (O2bc_*) [Stage 0] + │ fIndexBCs / fIndexBC + ├─► Collisions (O2collision_*) [Stage 1] + │ │ paste-join ──► McCollisionLabels (O2mccollisionlabel_*) + │ └─► Tracks (O2track_*, O2trackiu_*, ...) [Stage 1] + │ paste-join ─► McTrackLabels (O2mctracklabel_*) + │ paste-join ─► McFwdTrackLabels, McMFTTrackLabels + │ + └─► MCCollisions (O2mccollision_*) [Stage 1, deduped] + │ fIndexMcCollisions + ├─► HepMCXSections (O2hepmcxsection_*) [Stage 2] + ├─► HepMCPdfInfos (O2hepmcpdfinfo_*) [Stage 2] + └─► HepMCHeavyIons (O2hepmcheavyion_*) [Stage 2] +``` + +**Index joins** (`fIndexBCs`, `fIndexCollisions`, `fIndexMcCollisions`) are +explicit integer columns pointing to a row in another table by position. + +**Paste joins** are implicit: table row N of a paste-joined table corresponds +to row N of its parent table. These tables have *no index column*. They must +be reordered to match their parent whenever the parent is reordered. + +The known paste-join relationships are hardcoded in `kPasteJoins` (Section 1). +The list is authoritative — derived from `AnalysisDataModel.h` comments +("Table joined to the collision table containing the MC index", etc.) and +from the SOA `EXTENDED_TABLE` declarations for cov / extra tables: +``` +O2bcflag → parent: O2bc_* (BCFlags joinable with BCs) +O2mccollisionlabel → parent: O2collision_* (McCollisionLabels) +O2mctracklabel → parent: O2track_iu (or O2track) +O2mcfwdtracklabel → parent: O2fwdtrack +O2mcmfttracklabel → parent: O2mfttrack +O2mccalolabel → parent: O2calo (McCaloLabels) +O2trackcov_iu → parent: O2track_iu (TracksCovIU extension) +O2trackextra → parent: O2track_iu (TracksExtra extension) +O2fwdtrackcov → parent: O2fwdtrack (FwdTracksCov extension) +``` +NOT in this list (despite the suffix): `O2mfttrackcov` carries its own +`fIndexMFTTracks` and is **index-linked**, not paste-joined. + +A child may carry its own index columns (e.g. `O2mccollisionlabel` carries +`fIndexMcCollisions`). Those values are remapped *value-wise* through the +appropriate parent-stage permutation, but the child's row count and row +order strictly follow its paste-join parent. + +--- + +## Code structure (11 sections) + +| Section | Function(s) | Purpose | +|---------|-------------|---------| +| 1 | `PermMap`, `isBCTable`, `bcIndexBranch`, `mcCollIndexBranch`, `collIndexBranch`, `kPasteJoins`, `isPasteJoinChild` | Core types, name-probe helpers, and the authoritative paste-join list | +| 2 | `ScalarTag`, `tagOf`, `byteSize`, `readAsInt`, `writeAsInt`, `BranchDesc`, `describeBranches` | Generic ROOT branch I/O over raw byte buffers | +| 3 | `rewriteTable` | **Central engine**: writes any table in a given row order, remapping one nominated index column via a PermMap | +| 4 | `BCStage0Result`, `stage0_sortBCs` | Sort + deduplicate the BC table; produce `bcPerm` | +| 5 | `stage0_copyBCFlags` | Copy BC flags table following BC row selection | +| 6 | `MCCollKey`, `MCCollKeyHash`, `stage1_BCindexedTables` | Process all BC-indexed tables; deduplicate MCCollisions | +| 7 | `stage2_MCCollIndexedTables` | Process all MCCollision-indexed tables; drop rows whose parent was deduped | +| 8 | `rowOrderFromPerm`, `findPermByPrefix`, `processPasteJoinTables` | Reorder paste-joined tables to follow their parent (1:1 row count guaranteed); remap any of their own index columns value-wise; copy unrelated tables verbatim | +| 9 | `copyNonTreeObjects` | Copy TMap metadata and other non-TTree objects | +| 10 | `processDF` | Orchestrates all stages for one `DF_*` directory | +| 11 | `AODBcRewriter` | Top-level entry: opens files, iterates `DF_*` dirs, preserves compression | + +### `rewriteTable` — the central engine + +```cpp +PermMap rewriteTable(TTree *src, TDirectory *dirOut, + const vector &rowOrder, + const string &indexBranch, + const PermMap &parentPerm); +``` + +- `rowOrder`: which source rows to emit and in what sequence (may be a subset + for deduplication, or reordered for sorting) +- `indexBranch`: name of the one index column to remap (e.g. `"fIndexBCs"`), + or `""` for none +- `parentPerm`: the PermMap from the parent stage used to translate the old + index value to a new one +- Returns `srcToOut` PermMap: `srcToOut[srcRow] = outRow`, -1 if dropped + +The function handles both scalar branches and VLA (variable-length array) +branches generically. For VLAs it pre-scans the count branch to find the +maximum array length and allocates buffers accordingly. Input and output +branches share the same raw byte buffers; ROOT handles the VLA count +implicitly through the shared count buffer. + +--- + +## MCCollision deduplication + +Implemented in `stage1_BCindexedTables` when the current table begins with +`O2mccollision`. + +**Key**: `MCCollKey { Long64_t newBCrow; Float_t weight; }` using `fEventWeight`. + +**Important constraint**: deduplication is only enabled when `fEventWeight` is +present in the tree. If it is absent, all rows are kept (only reordered). This +is intentional: deduplicating on `newBCrow` alone would incorrectly collapse +distinct MC events that happen to share the same bunch crossing. + +When a MCCollision row is dropped (PermMap entry = -1), Stage 2 propagates +the drop: any `O2hepmcxsection_*` / `O2hepmcpdfinfo_*` / `O2hepmcheavyion_*` +row whose `fIndexMcCollisions` pointed to a dropped row is also dropped. + +--- + +## Known gaps / TODO items + +These were identified during the refactor but not yet implemented: + +### 1. `fIndexCollisions` inside `O2mccollision` is not remapped + +`O2mccollision` has both `fIndexBCs` (handled) and `fIndexCollisions` (linking +back to the reconstructed `O2collision` row). After Stage 1 reorders +`O2collision`, this second index in `O2mccollision` becomes stale. + +**Fix**: After `stage1_BCindexedTables` runs, find `collPerm` (the PermMap for +`O2collision_*`) in `stage1Perms`, then apply a second `rewriteTable` pass on +`O2mccollision_*` to remap `fIndexCollisions` via `collPerm`. The +`ExtraRemap` mechanism in `rewriteTable` already supports this pattern. + +### 2. Deduplication key could be strengthened + +The current `(newBCrow, fEventWeight)` key is a good heuristic. A more robust +key would additionally include `fImpactParameter` and/or `fGeneratorsID` if +those branches are present. Consider making the key construction a small +helper function that probes which fields are available and builds the strongest +possible key. + +### 3. `O2mccollision` has two potential parents for paste-join lookup + +In `processDF`, the MCColl PermMap is extracted by scanning `stage1Perms` for +a name beginning with `"O2mccollision"`. If the DF contains both +`O2mccollision_000` and `O2mccollision_001` (schema version coexistence), +only the first found is used. Add a warning and handle this explicitly if it +becomes relevant. + +### 4. Paste-join size-mismatch fallback is silent-ish + +When a paste-joined table has a different row count from its parent (schema +drift), the tool falls back to `CloneTree(-1, "fast")` and prints a warning. +This produces a structurally inconsistent output. Consider making this a hard +error, or implement a best-effort row-count reconciliation. + +### ~~5. No validation pass~~ (RESOLVED) + +`AODBcRewriterValidate(fname)` (Section 11) now validates BC monotonicity, +MC-particle intra-table index integrity, paste-join row-count parity, and +generic `fIndex*` range against the referent table. Call it after rewriting +to confirm output correctness. + +### ~~6. fIndexArray_Mothers / fIndexSlice_Daughters not remapped~~ (RESOLVED) + +This was the root cause of the O2Physics FATAL +`MC particle N has daughter with index M > MC particle table size`. +After Stage 2 reorders `O2mcparticle`, the intra-table mother/daughter indices +now get remapped via `ExtraRemap` in the same pass (Section 7). + +`fIndexMcParticles` in label tables (`O2mctracklabel`, `O2mcfwdtracklabel`, +`O2mcmfttracklabel`, `O2mccalolabel`) is also now remapped via the MC-particle +permutation in `processPasteJoinTables` (Section 8). + +### ~~8. fIndexSliceBCs in O2ambiguous* not remapped after BC dedup~~ (RESOLVED) + +`fIndexSliceBCs` is a SOA `SLICE_INDEX_COLUMN(BC, bc)` (header line 1029), +stored on disk as a fixed `[2]/I` `{first, last}` pair pointing into the BC +table. It appears in `O2ambiguoustrack`, `O2ambiguousmfttr`, +`O2ambiguousfwdtr` — none of which carry `fIndexBCs` and therefore none +were processed by Stage 1. After BC dedup the slice endpoints would then +point past the compacted table. + +**Fix**: `processPasteJoinTables` now also accepts the BC permutation +(passed explicitly from `processDF`) and applies it value-wise to any +`fIndexSliceBCs` / `fIndexBCs` / `fIndexBC` column it finds. Validated +against `example_AOD/AO2D_pre.root`: pre-fix the rewritten output had 7 +and 19 out-of-range slice endpoints in DF_3594457012003; post-fix the +validator reports zero. + +### ~~7. Paste-join row-count drift on MC-collision dedup~~ (RESOLVED) + +`O2mccollisionlabel` is paste-joined to `O2collision_*` (row N ↔ row N) but +also carries `fIndexMcCollisions`. The previous code routed it through Stage +2 (because of the MC-collision index), which sorted it by new MC-collision +position and *dropped* rows whose MC collision had been deduplicated. That +left `O2mccollisionlabel` shorter than `O2collision_*` by N rows — leading +to downstream "O2collision_001 is one larger than O2mccollisionlabel" crashes. + +**Fix**: `kPasteJoins` was extended to cover every joined pair from +`AnalysisDataModel.h`. Paste-join children are now *deferred* from Stage 2 +to `processPasteJoinTables`, where they take the parent's row order and have +their own index columns remapped value-wise. Rows that lose their MC label +on dedup now correctly produce `fIndexMcCollisions == -1`, and the row count +matches the parent collision table. + +The new validator catches the regression class as +`[FAIL] paste-join size mismatch: O2mccollisionlabel* has N rows but parent + O2collision* has M`. + +--- + +## Testing checklist + +When testing a new AO2D: + +1. Run `AODBcRewriterValidate("AO2D_rewritten.root")` (Section 11). + It checks BC monotonicity, MC-particle intra-table integrity, paste-join + row-count parity for every pair in `kPasteJoins`, and `fIndex*` value + ranges against the referent table. Failures appear as `[FAIL] ...` lines. +2. Check stdout from the rewrite run itself for any `[warn]` lines — these + indicate branches or tables that fell through to a fallback path. +3. If deduplication ran, verify the dropped count is as expected by comparing + the input DF MCCollision count vs. output. + +A standalone minimal validation script (kept here for reference; in practice +just call `AODBcRewriterValidate`): +```cpp +// validate.C +void validate(const char *fname) { + TFile *f = TFile::Open(fname); + TIter top(f->GetListOfKeys()); + while (TKey *k = (TKey*)top()) { + if (!TString(k->GetName()).BeginsWith("DF_")) continue; + TDirectory *d = (TDirectory*)f->Get(k->GetName()); + // check BC monotonicity + TTree *bc = (TTree*)d->Get("O2bc_001"); // adjust suffix + if (bc) { + ULong64_t gbc, prev = 0; bool ok = true; + bc->SetBranchAddress("fGlobalBC", &gbc); + for (Long64_t i = 0; i < bc->GetEntries(); ++i) { + bc->GetEntry(i); + if (i > 0 && gbc <= prev) { printf("BC non-monotonic at row %lld\n", i); ok=false; } + prev = gbc; + } + if (ok) printf("%s: BCs OK (%lld entries)\n", k->GetName(), bc->GetEntries()); + } + } +} +``` + +--- + +## Data model reference + +Full table schema: https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html + +Source definitions: `AliceO2/Framework/Core/include/Framework/AnalysisDataModel.h` + +The upstream PR this work improves upon: https://github.com/AliceO2Group/O2DPG/pull/2317 + +Target file location in O2DPG: `MC/utils/AODBcRewriter.C` \ No newline at end of file From e87efa6d1c0b90fb661d7ef898fc785372b75871 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Wed, 20 May 2026 14:19:40 +0200 Subject: [PATCH 326/362] AODBcRewriter: possibility to treat AliEn files directly --- MC/utils/AODBcRewriter.C | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C index c6ff68879..710b643bd 100644 --- a/MC/utils/AODBcRewriter.C +++ b/MC/utils/AODBcRewriter.C @@ -73,6 +73,7 @@ #include "TROOT.h" #include "TString.h" #include "TTree.h" +#include "TGrid.h" #include #include #include @@ -1328,7 +1329,9 @@ void AODBcRewriter(const char *inFileName = "AO2D.root", std::cout << "AODBcRewriter: input=" << inFileName << " output=" << outFileName << "\n"; - + if (TString(inFileName).BeginsWith("alien:")) { + TGrid::Connect("alien"); + } std::unique_ptr fin(TFile::Open(inFileName, "READ")); if (!fin || fin->IsZombie()) { std::cerr << "ERROR: cannot open " << inFileName << "\n"; return; } From b83568d051cbb61ec22b1e77615740b4d7a0a489 Mon Sep 17 00:00:00 2001 From: swenzel Date: Mon, 23 Mar 2026 11:36:55 +0100 Subject: [PATCH 327/362] Improvements for MC-DATA anchoring * ability to pass forward the parent-AOD file and to link it in the MC-produced AO2D * keep `DF_` folder structure intact: MC timeframes are now stored under the same `DF_` folder as in the original data file --- MC/bin/o2dpg_sim_workflow.py | 9 ++++++++- MC/run/ANCHOR/anchorMC_DataEmbedding.sh | 9 +++++++-- MC/utils/o2dpg_data_embedding_utils.py | 19 +++++++++++++++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 4b330fd10..1bbd30fe6 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -126,6 +126,8 @@ # help='Treat smaller sensors in a single digitization') parser.add_argument('--pregenCollContext', action='store_true', help=argparse.SUPPRESS) # Now the default, giving this option or not makes not difference. We keep it for backward compatibility parser.add_argument('--data-anchoring', type=str, default='', help="Take collision contexts (from data) stored in this path") +parser.add_argument('--aod-output-folder', type=str, default='', help="Force this AOD folder in the AOD producer") +parser.add_argument('--aod-parent-file', type=str, default='', help="Link this as parent file in the AOD") parser.add_argument('--no-combine-smaller-digi', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--no-combine-dpl-devices', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--no-mc-labels', action='store_true', default=False, help=argparse.SUPPRESS) @@ -1796,6 +1798,10 @@ def getDigiTaskName(det): if created_by_option != '': created_by_option += ' ' + aod_creator + aod_timeframe_id = f"${{ALIEN_PROC_ID}}{aod_df_id}" if not args.run_anchored else "" + if len(args.aod_output_folder) > 0: + aod_timeframe_id = args.aod_output_folder + AODtask = createTask(name='aod_'+str(tf), needs=aodneeds, tf=tf, cwd=timeframeworkdir, lab=["AOD"], mem='4000', cpu='1') AODtask['cmd'] = ('','ln -nfs ../bkg_Kine.root . ;')[doembedding] AODtask['cmd'] += '[ -f AO2D.root ] && rm AO2D.root; ' @@ -1812,12 +1818,13 @@ def getDigiTaskName(det): "--anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}", "--anchor-prod ${ALIEN_JDL_LPMANCHORPRODUCTION:-unknown}", "--reco-pass ${ALIEN_JDL_LPMPASSNAME:-unknown}", + f"--aod-parent {args.aod_parent_file}", created_by_option, "--combine-source-devices" if not args.no_combine_dpl_devices else "", "--disable-mc" if args.no_mc_labels else "", "--enable-truncation 0" if environ.get("O2DPG_AOD_NOTRUNCATE") or environ.get("ALIEN_JDL_O2DPG_AOD_NOTRUNCATE") else "", "--disable-strangeness-tracker" if args.no_strangeness_tracking else "", - f"--aod-timeframe-id ${{ALIEN_PROC_ID}}{aod_df_id}" if not args.run_anchored else "", + f"--aod-timeframe-id {aod_timeframe_id}" if len(aod_timeframe_id) > 0 else "" ]) # Consider in future: AODtask['disable_alternative_reco_software'] = True # do not apply reco software here (we prefer latest aod converter) workflow['stages'].append(AODtask) diff --git a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh index 6108e59eb..80cb1daae 100755 --- a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh +++ b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh @@ -329,7 +329,12 @@ for external_context in collission_context_*.root; do # extract timeframe from name anchoring_tf="${external_context#collission_context_}" # remove prefix 'collision_context_' anchoring_tf="${anchoring_tf%.root}" # remove suffix '.root' - echo "Treating timeframe ${anchoring_tf}" + # now we have a string with DF_FOLDERNAME:TIMEFRAMEID + + df_folder="${anchoring_tf%%:*}" + anchoring_tf="${anchoring_tf##*:}" + + echo "Treating timeframe ${anchoring_tf} coming from folder ${df_folder}" # we do it in a separate workspace workspace="TF_${anchoring_tf}" @@ -366,7 +371,7 @@ for external_context in collission_context_*.root; do remainingargs="${remainingargs} ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}}" # add external collision context injection if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then - remainingargs="${remainingargs} --data-anchoring ${PWD}/../${external_context}" + remainingargs="${remainingargs} --data-anchoring ${PWD}/../${external_context} --aod-output-folder ${df_folder##*_} --aod-parent-file ${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" fi echo_info "baseargs passed to o2dpg_sim_workflow_anchored.py: ${baseargs}" diff --git a/MC/utils/o2dpg_data_embedding_utils.py b/MC/utils/o2dpg_data_embedding_utils.py index dad1769a9..b152d991e 100644 --- a/MC/utils/o2dpg_data_embedding_utils.py +++ b/MC/utils/o2dpg_data_embedding_utils.py @@ -1,6 +1,13 @@ # Set of python modules/util functions for the MC-to-DATA embedding # Mostly concerning extraction of MC collision context from existing data AO2D.root +import warnings +warnings.filterwarnings( + "ignore", + message="pandas.Int64Index is deprecated", + category=FutureWarning, +) + import ROOT import uproot import pandas as pd @@ -240,7 +247,7 @@ def fetch_bccoll_to_localFile(alien_file, local_filename): return True -def convert_to_digicontext(aod_timeframe=None, timeframeID=-1): +def convert_to_digicontext(aod_timeframe, df_folder, timeframeID=-1): """ converts AOD collision information from AO2D to collision context which can be used for MC @@ -282,13 +289,16 @@ def convert_to_digicontext(aod_timeframe=None, timeframeID=-1): # set the bunch filling ---> NEED to fetch it from CCDB # digicontext.setBunchFilling(bunchFillings[0]); + + # TODO: set the interaction rate (for TPC loopers) + # digicontext.mDigitizerInteractionRate = ... prefixes = ROOT.std.vector("std::string")(); prefixes.push_back("sgn") digicontext.setSimPrefixes(prefixes); digicontext.printCollisionSummary(); - digicontext.saveToFile(f"collission_context_{timeframeID}.root") + digicontext.saveToFile(f"collission_context_{df_folder}:{timeframeID}.root") def process_data_AO2D(file_name, run_number, upper_limit = -1): @@ -315,7 +325,8 @@ def process_data_AO2D(file_name, run_number, upper_limit = -1): break tf = row['timeframeID'] cols = row['position_vectors'] - convert_to_digicontext(cols, tf) + df = key.split('@')[0] # this is the DF folder name + convert_to_digicontext(cols, df, tf) counter = counter + 1 @@ -324,7 +335,7 @@ def main(): parser.add_argument("--run-number", type=int, help="Run number to anchor to", required=True) parser.add_argument("--aod-file", type=str, help="Data AO2D file (can be on AliEn)", required=True) - parser.add_argument("--limit", type=int, default=-1, help="Upper limit of timeframes to be extracted") + parser.add_argument("--limit", type=int, default=-1, help="Upper limit of timeframes to be extracted (-1 is no limit)") args = parser.parse_args() process_data_AO2D(args.aod_file, args.run_number, args.limit) From 46876005d981b19cb1862072d9d590863df3df62 Mon Sep 17 00:00:00 2001 From: mbroz84 Date: Sun, 24 May 2026 10:29:14 +0200 Subject: [PATCH 328/362] Photon energy in header (#2365) --- .../PWGUD/external/generator/GeneratorStarlight.C | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlight.C b/MC/config/PWGUD/external/generator/GeneratorStarlight.C index b2069c16b..be7e4d367 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlight.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlight.C @@ -337,6 +337,16 @@ class GeneratorStarlight_class : public Generator return true; } + //Store couple of event informations to the MC event header + void updateHeader(o2::dataformats::MCEventHeader* eventHeader)override + { + using Key = o2::dataformats::MCInfoKeys; + + eventHeader->putInfo(Key::generator, "STARlight"); + eventHeader->putInfo(Key::processName, mSelectedConfiguration); + eventHeader->putInfo("photonEnergy", getPhotonEnergy()); + } + protected: float eCM = 5020; //CMS energy int projA=208; //Beam From c840d7f913eaa9cc15c93dd5048b2ab1c1673508 Mon Sep 17 00:00:00 2001 From: SCHOTTER Romain <47983209+romainschotter@users.noreply.github.com> Date: Mon, 25 May 2026 03:17:32 +0200 Subject: [PATCH 329/362] Add configuration for Pb-Pb with hadronic rescattering (#2364) * Add configuration for Pb-Pb with hadronic rescattering * Update PbPb Angantyr settings --- .../ini/pythia8_PbPb_rescattering_536.ini | 10 ++++++++ .../ini/tests/pythia8_PbPb_rescattering_536.C | 24 +++++++++++++++++++ .../pythia8_PbPb_rescattering_536.cfg | 24 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 MC/config/common/ini/pythia8_PbPb_rescattering_536.ini create mode 100644 MC/config/common/ini/tests/pythia8_PbPb_rescattering_536.C create mode 100644 MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg diff --git a/MC/config/common/ini/pythia8_PbPb_rescattering_536.ini b/MC/config/common/ini/pythia8_PbPb_rescattering_536.ini new file mode 100644 index 000000000..1ed1278ef --- /dev/null +++ b/MC/config/common/ini/pythia8_PbPb_rescattering_536.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 1 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg diff --git a/MC/config/common/ini/tests/pythia8_PbPb_rescattering_536.C b/MC/config/common/ini/tests/pythia8_PbPb_rescattering_536.C new file mode 100644 index 000000000..1c28040e2 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_PbPb_rescattering_536.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg b/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg new file mode 100644 index 000000000..d4158bdcf --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg @@ -0,0 +1,24 @@ +### OO beams +Beams:idA 1000822080 # Pb +Beams:idB 1000822080 # Pb +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Initialize the Angantyr model to fit the total and semi-includive +### cross sections in Pythia within some tolerance. +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 + +### These parameters are typicall suitable for sqrt(S_NN)=5TeV +HeavyIon:SigFitDefPar = 17.24,2.15,0.33,0.0,0.0,0.0,0.0,0.0 + +### enable hadronic rescattering +HadronLevel:Rescatter = on # default = off +Fragmentation:setVertices = on # default = off +PartonVertex:setVertex = on # default = off +Rescattering:nearestNeighbours = off # default = on (but "require a larger retuning effort") +Rescattering:inelastic = on # default = on + +Random:setSeed = on From 216e56d9f077310b3c133109f586e75d3c0e4421 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 29 May 2026 20:16:09 +0200 Subject: [PATCH 330/362] MC/PWGEM: update DY generator in OO (#2356) --- ... => Generator_pythia8_GapTriggered_DYll.C} | 0 ...ratorDYee_GapTriggered_Gap2_OO5360GeV.ini} | 2 +- ...ratorDYee_GapTriggered_Gap5_pp13600GeV.ini | 7 -- ...orDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini | 7 -- ...torDYmumu_GapTriggered_Gap5_pp13600GeV.ini | 7 -- ...eneratorDYee_GapTriggered_Gap2_OO5360GeV.C | 51 ++++++++ ...eneratorDYee_GapTriggered_Gap5_OO5360GeV.C | 51 ++++++++ ...eneratorDYee_GapTriggered_Gap5_pp5360GeV.C | 51 ++++++++ ...eratorDYmumu_GapTriggered_Gap5_OO5360GeV.C | 51 ++++++++ ...eratorDYmumu_GapTriggered_Gap5_pp5360GeV.C | 51 ++++++++ ..._pp_5360_bbbar_forceddecayscharmbeauty.cfg | 117 +++++++----------- .../pythia8_pp_5360_cr2_forceddecayscharm.cfg | 41 ++---- MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh | 52 ++++++++ MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh | 52 ++++++++ 14 files changed, 419 insertions(+), 121 deletions(-) rename MC/config/PWGEM/external/generator/{Generator_pythia8_GapTriggered_DYLL.C => Generator_pythia8_GapTriggered_DYll.C} (100%) rename MC/config/PWGEM/ini/{GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini => GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini} (72%) delete mode 100644 MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini delete mode 100644 MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini delete mode 100644 MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini create mode 100644 MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.C create mode 100644 MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.C create mode 100644 MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh create mode 100644 MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYLL.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C similarity index 100% rename from MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYLL.C rename to MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini similarity index 72% rename from MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini rename to MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini index 8cc7c0ff6..a83045099 100644 --- a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_PbPb5360GeV.ini +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C -funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 1000822080, 1000822080, 5360.0) +funcName = GeneratorPythia8GapTriggeredDYll(2, 1, 11, -1.5, +1.5, 1000080160, 1000080160, 5360.0) [GeneratorPythia8] config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini deleted file mode 100644 index 7ecf763cf..000000000 --- a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini +++ /dev/null @@ -1,7 +0,0 @@ -[GeneratorExternal] -fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C -funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 2212, 2212, 13600.0) - -[GeneratorPythia8] -config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg -includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini deleted file mode 100644 index de8cefbe8..000000000 --- a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_PbPb5360GeV.ini +++ /dev/null @@ -1,7 +0,0 @@ -[GeneratorExternal] -fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C -funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 1000822080, 1000822080, 5360.0) - -[GeneratorPythia8] -config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg -includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini deleted file mode 100644 index e9a7c06da..000000000 --- a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp13600GeV.ini +++ /dev/null @@ -1,7 +0,0 @@ -[GeneratorExternal] -fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C -funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 2212, 2212, 13600.0) - -[GeneratorPythia8] -config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg -includePartonEvent = true diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.C new file mode 100644 index 000000000..aca7bb427 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.C new file mode 100644 index 000000000..aca7bb427 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.C new file mode 100644 index 000000000..0332e54fc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 2212) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.C new file mode 100644 index 000000000..aca7bb427 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.C new file mode 100644 index 000000000..0332e54fc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 2212) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg index 375c72768..2cc3486fe 100644 --- a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg @@ -30,97 +30,73 @@ MultiPartonInteractions:pT0Ref = 2.15 BeamRemnants:remnantMode = 1 BeamRemnants:saturation =5 -### only semileptonic decays from https://pdg.lbl.gov/2025/ +### only semileptonic decays for charm ### D+ -411:oneChannel = 1 0.08810 0 -311 -11 12 -#411:addChannel = 1 0.04020 0 -321 211 -11 12 # may be double counting -411:addChannel = 1 0.05400 0 -313 -11 12 -411:addChannel = 1 0.00372 0 111 -11 12 -411:addChannel = 1 0.00111 0 221 -11 12 -411:addChannel = 1 0.00187 0 113 -11 12 -411:addChannel = 1 0.00169 0 223 -11 12 -411:addChannel = 1 0.00020 0 331 -11 12 +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 ### D0 -421:oneChannel = 1 0.0354 0 -321 -11 12 -421:addChannel = 1 0.0216 0 -323 -11 12 -#421:addChannel = 1 0.0160 0 -321 111 -11 12 # may be double counting -#421:addChannel = 1 0.0144 0 -311 211 -11 12 # may be double counting -421:addChannel = 1 0.00291 0 -211 -11 12 -421:addChannel = 1 0.00145 0 -211 111 -11 12 -421:addChannel = 1 0.00146 0 -213 -11 12 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +421:addChannel = 1 0.014 0 -311 -211 -11 12 ### Ds -431:oneChannel = 1 0.0234 0 333 -11 12 -431:addChannel = 1 0.0227 0 221 -11 12 -431:addChannel = 1 0.0081 0 331 -11 12 -431:addChannel = 1 0.0029 0 311 -11 12 -431:addChannel = 1 0.0021 0 313 -11 12 +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 ### Lambdac -4122:oneChannel = 1 0.0356 0 3122 -11 12 -4122:oneChannel = 1 0.0009 0 2212 -321 -11 12 -4122:oneChannel = 1 0.0010 0 3124 -11 12 -4122:oneChannel = 1 0.0004 0 3126 -11 12 -### Xi_{c}^{+} +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} 4232:oneChannel = 1 0.07 0 3322 -11 12 -### Xi_{c}^{0} -4132:oneChannel = 1 0.0105 0 3312 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 ### Omega_{c} 4332:oneChannel = 1 0.01224 0 3334 -11 12 -### only semileptonic decays for beauty from https://pdg.lbl.gov/2025/ +### only semileptonic decays for beauty ### B0 -511:oneChannel = 1 0.021000 0 12 -11 -411 -511:addChannel = 1 0.048700 0 12 -11 -413 -511:addChannel = 1 0.002300 0 12 -11 -415 -511:addChannel = 1 0.000150 0 12 -11 -211 -511:addChannel = 1 0.000294 0 12 -11 -213 -#511:addChannel = 1 0.004500 0 12 -11 -10411 -#511:addChannel = 1 0.005200 0 12 -11 -10413 -#511:addChannel = 1 0.008300 0 12 -11 -20413 -511:addChannel = 1 0.003640 0 12 -11 -421 -211 -511:addChannel = 1 0.005440 0 12 -11 -423 -211 -511:addChannel = 1 0.001450 0 12 -11 -411 -211 211 -511:addChannel = 1 0.000510 0 12 -11 -413 -211 211 +511:oneChannel = 1 0.0207000 0 12 -11 -411 +511:addChannel = 1 0.0570000 0 12 -11 -413 +511:addChannel = 1 0.0023000 0 12 -11 -415 +511:addChannel = 1 0.0001330 0 12 -11 -211 +511:addChannel = 1 0.0002690 0 12 -11 -213 +511:addChannel = 1 0.0045000 0 12 -11 -10411 +511:addChannel = 1 0.0052000 0 12 -11 -10413 +511:addChannel = 1 0.0083000 0 12 -11 -20413 ### B+ -521:oneChannel = 1 0.000078 0 12 -11 111 -521:addChannel = 1 0.000158 0 12 -11 113 -521:addChannel = 1 0.000035 0 12 -11 221 -521:addChannel = 1 0.000119 0 12 -11 223 -521:addChannel = 1 0.000024 0 12 -11 331 -521:addChannel = 1 0.022600 0 12 -11 -421 -521:addChannel = 1 0.052600 0 12 -11 -423 -521:addChannel = 1 0.001590 0 12 -11 -425 -#521:addChannel = 1 0.000900 0 12 -11 -10421 -#521:addChannel = 1 0.002840 0 12 -11 -10423 -#521:addChannel = 1 0.001700 0 12 -11 -20423 -521:addChannel = 1 0.003820 0 12 -11 -411 211 -521:addChannel = 1 0.005420 0 12 -11 -413 211 -521:addChannel = 1 0.001730 0 12 -11 -421 -211 211 -521:addChannel = 1 0.000700 0 12 -11 -423 -211 211 -521:addChannel = 1 0.000300 0 12 -11 -431 321 -521:addChannel = 1 0.000290 0 12 -11 -433 321 +521:oneChannel = 1 0.0000720 0 12 -11 111 +521:addChannel = 1 0.0001450 0 12 -11 113 +521:addChannel = 1 0.0000840 0 12 -11 221 +521:addChannel = 1 0.0001450 0 12 -11 223 +521:addChannel = 1 0.0000840 0 12 -11 331 +521:addChannel = 1 0.0224000 0 12 -11 -421 +521:addChannel = 1 0.0617000 0 12 -11 -423 +521:addChannel = 1 0.0030000 0 12 -11 -425 +521:addChannel = 1 0.0049000 0 12 -11 -10421 +521:addChannel = 1 0.0056000 0 12 -11 -10423 +521:addChannel = 1 0.0090000 0 12 -11 -20423 ### Bs -531:oneChannel = 1 0.000106 0 12 -11 -321 -531:addChannel = 1 0.000300 0 12 -11 -323 -531:addChannel = 1 0.022900 0 12 -11 -431 -531:addChannel = 1 0.052000 0 12 -11 -433 -531:addChannel = 1 0.007000 0 12 -11 -435 -531:addChannel = 1 0.000300 0 12 -11 -10323 -531:addChannel = 1 0.004000 0 12 -11 -10431 -531:addChannel = 1 0.007000 0 12 -11 -10433 -531:addChannel = 1 0.000200 0 12 -11 -20323 -531:addChannel = 1 0.004000 0 12 -11 -20433 +531:oneChannel = 1 0.0002000 0 12 -11 -321 +531:addChannel = 1 0.0003000 0 12 -11 -323 +531:addChannel = 1 0.0210000 0 12 -11 -431 +531:addChannel = 1 0.0490000 0 12 -11 -433 +531:addChannel = 1 0.0070000 0 12 -11 -435 +531:addChannel = 1 0.0003000 0 12 -11 -10323 +531:addChannel = 1 0.0040000 0 12 -11 -10431 +531:addChannel = 1 0.0070000 0 12 -11 -10433 +531:addChannel = 1 0.0002000 0 12 -11 -20323 +531:addChannel = 1 0.0040000 0 12 -11 -20433 ### Lambdab 5122:oneChannel = 1 0.0546000 0 -12 11 4122 5122:addChannel = 1 0.0096000 0 -12 11 4124 5122:addChannel = 1 0.0128000 0 -12 11 14122 -### Xi_{b}^{-} +### Chi_{b}^{-} 5132:oneChannel = 1 0.1080010 0 -12 11 4 3101 5132:addChannel = 1 0.0020000 0 -12 11 2 3101 -### Xi_{b}^{0} +### Chi_{b}^{0} 5232:oneChannel = 1 0.1080010 0 -12 11 4 3201 5232:addChannel = 1 0.0020000 0 -12 11 2 3201 ### Omega_{b}^{-} @@ -132,4 +108,3 @@ BeamRemnants:saturation =5 4332:tau0 = 0.08000000000 # Correct Lb decay length (wrong in PYTHIA8 decay table) 5122:tau0 = 4.41000e-01 - diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg index 2ee27cad6..7f5a2bcab 100644 --- a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg @@ -36,39 +36,24 @@ MultiPartonInteractions:pT0Ref = 2.15 BeamRemnants:remnantMode = 1 BeamRemnants:saturation =5 -### only semileptonic decays from https://pdg.lbl.gov/2025/ + ### only semileptonic decays ### D+ -411:oneChannel = 1 0.08810 0 -311 -11 12 -#411:addChannel = 1 0.04020 0 -321 211 -11 12 # may be double counting -411:addChannel = 1 0.05400 0 -313 -11 12 -411:addChannel = 1 0.00372 0 111 -11 12 -411:addChannel = 1 0.00111 0 221 -11 12 -411:addChannel = 1 0.00187 0 113 -11 12 -411:addChannel = 1 0.00169 0 223 -11 12 -411:addChannel = 1 0.00020 0 331 -11 12 +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 ### D0 -421:oneChannel = 1 0.0354 0 -321 -11 12 -421:addChannel = 1 0.0216 0 -323 -11 12 -#421:addChannel = 1 0.0160 0 -321 111 -11 12 # may be double counting -#421:addChannel = 1 0.0144 0 -311 211 -11 12 # may be double counting -421:addChannel = 1 0.00291 0 -211 -11 12 -421:addChannel = 1 0.00145 0 -211 111 -11 12 -421:addChannel = 1 0.00146 0 -213 -11 12 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 ### Ds -431:oneChannel = 1 0.0234 0 333 -11 12 -431:addChannel = 1 0.0227 0 221 -11 12 -431:addChannel = 1 0.0081 0 331 -11 12 -431:addChannel = 1 0.0029 0 311 -11 12 -431:addChannel = 1 0.0021 0 313 -11 12 +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 ### Lambdac -4122:oneChannel = 1 0.0356 0 3122 -11 12 -4122:oneChannel = 1 0.0009 0 2212 -321 -11 12 -4122:oneChannel = 1 0.0010 0 3124 -11 12 -4122:oneChannel = 1 0.0004 0 3126 -11 12 -### Xi_{c}^{+} +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} 4232:oneChannel = 1 0.07 0 3322 -11 12 -### Xi_{c}^{0} -4132:oneChannel = 1 0.0105 0 3312 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 ### Omega_{c} 4332:oneChannel = 1 0.01224 0 3334 -11 12 diff --git a/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh new file mode 100644 index 000000000..9b36bcf51 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC25ae +# + +# example anchoring + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=564356 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC26a2 +export ALIEN_JDL_LPMANCHORRUN=564356 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC25ae +export ALIEN_JDL_LPMANCHORYEAR=2025 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 30/70 sampling for different generators +# No forced beauty decays as we have observed biases + +# generate random number +RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh new file mode 100644 index 000000000..8767cae2d --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC25ae +# + +# example anchoring + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=564356 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC26a2 +export ALIEN_JDL_LPMANCHORRUN=564356 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC25ae +export ALIEN_JDL_LPMANCHORYEAR=2025 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 30/70 sampling for different generators +# No forced beauty decays as we have observed biases + +# generate random number +RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh From e882201ca11215136c45fa5d41b0360039b870be Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Mon, 1 Jun 2026 17:52:09 +0200 Subject: [PATCH 331/362] Add generator and config for charmed nuclei (c-deuteron) (#2368) * Add configuration for c-deuteron simulation * Fix coalescence and definition of event containing decayed charmed nuclei * Add possibility to simulate also non-prompt c-deuterons * Add test macro and change lifetime from 1 mm to 0.5 mm --- .../generator_pythia8_embed_charmnuclei.C | 305 ++++++++++++++++++ .../ini/GeneratorHF_CDeuteron_Injected.ini | 10 + .../tests/GeneratorHF_CDeuteron_Injected.C | 127 ++++++++ .../generator/pythia8_cdeuteron_to_dkpi.cfg | 102 ++++++ .../external/generator/CoalescencePythia8.h | 4 +- 5 files changed, 546 insertions(+), 2 deletions(-) create mode 100644 MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C create mode 100644 MC/config/PWGHF/ini/GeneratorHF_CDeuteron_Injected.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_CDeuteron_Injected.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C new file mode 100644 index 000000000..4b6e9a3f7 --- /dev/null +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C @@ -0,0 +1,305 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" +#include "TF1.h" +#include "TMath.h" +#include +#include +#include +#include + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +#include "MC/config/common/external/generator/CoalescencePythia8.h" + +using namespace Pythia8; + +class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 +{ + public: + + /// constructor + GeneratorPythia8HFEmbedCharmNuclei(int pdgCode = 2010010020, float lifetime = 1.f, int nCharmNucleiPerEvent = 10, float yMin = -1.f, float yMax = 1.f, float ptMax = 25.f, bool trivialCoal = false, float coalMomentum = 0.2, float fracFromB = 0.f) + { + nNumberOfCharmNucleiPerEvent = nCharmNucleiPerEvent; + mRapidityMinCharmNuclei = yMin; + mRapidityMaxCharmNuclei = yMax; + mPtMaxCharmNuclei = ptMax; + mTrivialCoal = trivialCoal; + mCoalMomentum = coalMomentum; + mFractionFromBeauty = fracFromB; + mPdgCharmNucleus = pdgCode; + mSign = 1; + if (std::abs(mPdgCharmNucleus) == 2010010020) { + mMassCharmNucleus = 3.226f; + } else { + LOG(fatal) << "********** [GeneratorPythia8HFEmbedCharmNuclei] Only c-deuteron (pdg=2010010020) currently supported! Exit **********"; + } + mLifetimeCharmNucleus = lifetime; + mDecayDistr = new TF1("mDecayDistr", "TMath::Exp(-x * 1./[0])", 0., mLifetimeCharmNucleus * 100); + mDecayDistr->SetNpx(10000); + mDecayDistr->SetParameter(0, mLifetimeCharmNucleus); + mDecayDistrLb = new TF1("mDecayDistrLb", "TMath::Exp(-x * 1./[0])", 0., 44.f); + mDecayDistrLb->SetParameter(0, 0.440f); // lifetime of Lambda_b in mm/c + mDecayDistrLb->SetNpx(10000); + mPtDistrLb = new TF1("mPtDistrLb","[0]*x/TMath::Power((1+TMath::Power(x/[1],[3])),[2])",0.,100.); + mPtDistrLb->SetParameters(1000., 6.97355, 3.20721, 1.71678); + mPtDistrLb->SetNpx(10000); + + Print(); + + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Init \'GeneratorPythia8HFEmbedCharmNuclei\' with following parameters"; + LOG(info) << param; + if (param.config.empty()) { + LOG(fatal) << "Failed to init \'GeneratorPythia8\': problems with configuration file "; + } + std::string cfg = gSystem->ExpandPathName(param.config.c_str()); + LOG(info) << "GeneratorPythia8HFEmbedCharmNuclei Reading configuration from file: " << cfg; + if (!mPythiaGun.readFile(cfg, true)) { + LOG(fatal) << "Failed to init \'GeneratorPythia8\': problems with configuration file " << cfg; + } + + if (!mPythiaGun.init()) { + LOG(fatal) << "Failed to init \'GeneratorPythia8\': init returned with error"; + } + } + + /// Destructor + ~GeneratorPythia8HFEmbedCharmNuclei() = default; + + /// Print the input + void Print() + { + LOG(info) << "********** GeneratorPythia8HFEmbedCharmNuclei configuration dump **********"; + LOG(info) << Form("* PDG code of charm nuclei to be injected: %d", mPdgCharmNucleus); + LOG(info) << Form("* Mass of charm nuclei to be injected (GeV/c2): %f", mMassCharmNucleus); + LOG(info) << Form("* Lifetime of charm nuclei to be injected (mm): %f", mLifetimeCharmNucleus); + LOG(info) << Form("* Number of charm nuclei injected per event: %d", nNumberOfCharmNucleiPerEvent); + LOG(info) << Form("* Charmed nucleus rapidity: %f - %f", mRapidityMinCharmNuclei, mRapidityMaxCharmNuclei); + LOG(info) << Form("* Charmed nucleus pT max (prompt): %f", mPtMaxCharmNuclei); + LOG(info) << Form("* Trivial coalescence: %d", mTrivialCoal); + LOG(info) << Form("* Coalescence momentum: %f", mCoalMomentum); + LOG(info) << Form("* Fraction from beauty: %f", mFractionFromBeauty); + LOG(info) << "***********************************************************************"; + } + + void setHadronRapidity(float yMin, float yMax) + { + mRapidityMinCharmNuclei = yMin; + mRapidityMaxCharmNuclei = yMax; + }; + + void setUsedSeed(unsigned int seed) + { + mUsedSeed = seed; + }; + + unsigned int getUsedSeed() const + { + return mUsedSeed; + }; + + //__________________________________________________________________ + bool generateEvent() override + { + // we start from an empty event + mPythia.event.reset(); + + // we simulate c-deuteron decays + for (int iCharmNuclei{0}; iCharmNuclei 0) ? mSign = -1 : mSign = 1; + if (nNumberOfCharmNucleiPerEvent % 2 != 0 && iCharmNuclei == nNumberOfCharmNucleiPerEvent - 1) { + if (gRandom->Rndm() < 0.5) { + mSign = 1; + } + } + + int pdgToGen = mPdgCharmNucleus; + float massToGen = mMassCharmNucleus; + float lifetimeToGen = 0.f; + float minRapToGen = mRapidityMinCharmNuclei; + float maxRapToGen = mRapidityMaxCharmNuclei; + bool isFromB = gRandom->Rndm() < mFractionFromBeauty; + // we determine if it's prompt or non-prompt + if (isFromB) { + pdgToGen = 5122; // we generate a Lambda_b and we let it decay into the charmed nucleus, no other beauty hadrons are considered + massToGen = 5.61940f; // mass of Lambda_b (GeV/c2) + lifetimeToGen = mDecayDistrLb->GetRandom(); + minRapToGen *= 2; + maxRapToGen *= 2; + } else { + lifetimeToGen = mDecayDistr->GetRandom(); + } + + auto pt = (!isFromB) ? gRandom->Uniform(0., mPtMaxCharmNuclei) : mPtDistrLb->GetRandom(); + auto y = gRandom->Uniform(minRapToGen, maxRapToGen); + auto phi = gRandom->Uniform(0, TMath::TwoPi()); + auto px = pt * TMath::Cos(phi); + auto py = pt * TMath::Sin(phi); + auto mt = TMath::Sqrt(massToGen * massToGen + pt * pt); + auto pz = mt * TMath::SinH(y); + auto p = TMath::Sqrt(pt * pt + pz * pz); + auto e = TMath::Sqrt(massToGen * massToGen + p * p); + + Particle particle; + particle.id(mSign * pdgToGen); + particle.status(83); + particle.m(massToGen); + particle.px(px); + particle.py(py); + particle.pz(pz); + particle.e(e); + particle.xProd(0.f); + particle.yProd(0.f); + particle.zProd(0.f); + particle.tau(lifetimeToGen); + mPythiaGun.particleData.mayDecay(5122, true); // force decay + mPythiaGun.particleData.mayDecay(mPdgCharmNucleus, true); // force decay + + bool isCoalSuccess{false}; + int nTrials{0}; + while(!isCoalSuccess || nTrials > 1e4) { + mPythiaGun.event.reset(); + mPythiaGun.event.append(particle); + mPythiaGun.moreDecays(); + std::array dausToCoal = {-1, -1}; + std::vector pdgShortLivedResos = {313, 2224, 102134}; + bool isResoFound{false}; + int idxCharmNucleus{-1}; + for (int iPart{0}; iPart= idxCharmNucleus) { + // we need to change the indices of the daughter particles to point to the charmed nucleus + auto dauList = part.daughterList(); + for (auto const& dau : dauList) { + mPythiaGun.event[dau].mother1(idxCharmNucleus); + } + mPythiaGun.event.remove(iPart, iPart, true); + isResoFound=true; + } + } + if (isResoFound) { // we have to reset all the particles as daughters of the charm nucleus + std::vector idxDausCharmNucleus{}; + for (int iPart{0}; iPart newPartList{}; + std::vector idxToRemove{}; + for (int iPart{idxDausCharmNucleus[0]}; iPart updatedMothers{}; + for (int iPart{0}; iPart{1000010020}, mTrivialCoal, mCoalMomentum, dausToCoal[0], dausToCoal[1], 10.); + if (isCoalSuccess) { + int offset = mPythia.event.size(); // we need to rescale the indices of mothers and daughters, accounting for the particles that are already appended to the event + for (int iPart{0}; iPart 0) { + part.mother1(mother1 + offset - 1); + } + if (mother2 > 0) { + part.mother2(mother2 + offset - 1); + } + if (daughter1 > 0) { + part.daughter1(daughter1 + offset - 1); + } + if (daughter2 > 0) { + part.daughter2(daughter2 + offset - 1); + } + mPythia.event.append(part); + } + } + nTrials++; + } + } + + return true; + } + + +private: + // Properties of selection + float mMassCharmNucleus; /// mass of the charmed nucleus + int mPdgCharmNucleus; /// pdg code of the charmed nucleus + float mLifetimeCharmNucleus; /// lifetime of the charmed nucleus + int nNumberOfCharmNucleiPerEvent; /// number of charmed nuclei injected per event + float mRapidityMinCharmNuclei; /// rapidity min of the generated charmed nuclei + float mRapidityMaxCharmNuclei; /// rapidity max of the generated charmed nuclei + float mPtMaxCharmNuclei; /// pT max of the generated charmed nuclei + unsigned int mUsedSeed; /// seed + bool mTrivialCoal; /// if true, the coalescence is done without checking the distance in the phase space of the nucleons + float mCoalMomentum; /// coalescence momentum + Pythia8::Pythia mPythiaGun; /// Gun generator with decay support + TF1* mDecayDistr; /// Lifetime distribution + TF1* mDecayDistrLb; /// Lifetime distribution for Lb + TF1* mPtDistrLb; /// pt distribution for Lb (power-law fit to FONLL) + float mFractionFromBeauty; /// fraction of charmed nuclei coming from beauty hadrons + int mSign; /// sign of the charmed nuclei to be generated, if 0 they are generated with 50% of probability as particle or antiparticle +}; + + +///___________________________________________________________ +FairGenerator *GenerateHFEmbedCDeuteron(float lifetime = 1.f, int nCharmNucleiPerEvent = 10, float yMin = -1.f, float yMax = 1.f, float ptMax = 25.f, bool trivialCoal = false, float coalMomentum = 0.2f, float fracFromB = 0.25f) +{ + auto myGen = new GeneratorPythia8HFEmbedCharmNuclei(2010010020, lifetime, nCharmNucleiPerEvent, yMin, yMax, ptMax, trivialCoal, coalMomentum, fracFromB); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + return myGen; +} diff --git a/MC/config/PWGHF/ini/GeneratorHF_CDeuteron_Injected.ini b/MC/config/PWGHF/ini/GeneratorHF_CDeuteron_Injected.ini new file mode 100644 index 000000000..2a574f340 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_CDeuteron_Injected.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 100 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C +funcName=GenerateHFEmbedCDeuteron(0.5, 10, -1., 1., 25., 0, 0.4, 0.25) + +### includePartonEvent is needed to keep the c-deuteron in the event record, even if there are no partons in the event +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_CDeuteron_Injected.C b/MC/config/PWGHF/ini/tests/GeneratorHF_CDeuteron_Injected.C new file mode 100644 index 000000000..56d22c72a --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_CDeuteron_Injected.C @@ -0,0 +1,127 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int pdgCDeuteron{2010010020}; + int checkNumberOfCDeuteronPerEvent{10}; + float checkLifetimeCDeuteron{0.05f}; + std::map>> checkDecays{ + {2010010020, {{-321, 211, 1000010020}}} // c-deuteron -> K- + pi+ + deuteron + }; + float checkFracCDeuteronFromBeauty{0.25}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nCDeuteron{}, nCDeuteronGoodDecay{}, nCDeuteronFromBeauty{}; + std::array averageLifetimeCDeuteron{0.f, 0.f}; // prompt and non-prompt + float massCDeuteron = 3.226f; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + auto absPdg = std::abs(pdg); + // std::cout << "Event " << i << ": found particle with PDG " << pdg << std::endl; + + if (absPdg == pdgCDeuteron) { // found signal + nCDeuteron++; // count signal PDG + + // std::cout << "Event " << i << ": found c-deuteron with PDG " << pdg << std::endl; + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + if (track.getFirstDaughterTrackId() >= 0 && track.getLastDaughterTrackId() >= 0) { + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + // std::cout << "Fetching daughter track with ID " << j << std::endl; + auto pdgDau = tracks->at(j).GetPdgCode(); + // std::cout << "PDG of daughter track " << j << ": " << pdgDau << std::endl; + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111) { // phi and pi0 are antiparticles of themselves + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + } + // std::cout << "Daughters fetched" << std::endl; + + auto mother = track.getMotherTrackId(); + bool isFromBeauty{false}; + if (mother >= 0 && std::abs(tracks->at(mother).GetPdgCode()) == 5122) { // check if c-deuteron comes from Lb + nCDeuteronFromBeauty++; + isFromBeauty = true; + } + + auto dauTrack = tracks->at(track.getFirstDaughterTrackId()); + float decayLength = std::sqrt((track.GetStartVertexCoordinatesX() - dauTrack.GetStartVertexCoordinatesX()) * (track.GetStartVertexCoordinatesX() - dauTrack.GetStartVertexCoordinatesX()) + (track.GetStartVertexCoordinatesY() - dauTrack.GetStartVertexCoordinatesY()) * (track.GetStartVertexCoordinatesY() - dauTrack.GetStartVertexCoordinatesY()) + (track.GetStartVertexCoordinatesZ() - dauTrack.GetStartVertexCoordinatesZ()) * (track.GetStartVertexCoordinatesZ() - dauTrack.GetStartVertexCoordinatesZ())); + if (!isFromBeauty) { + averageLifetimeCDeuteron[0] += decayLength * massCDeuteron / track.GetP(); + } else { + averageLifetimeCDeuteron[1] += decayLength * massCDeuteron / track.GetP(); + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nCDeuteronGoodDecay++; + break; + } + } + // std::cout << "Daughters checked " << std::endl; + } + } + } + + averageLifetimeCDeuteron[0] /= nCDeuteron - nCDeuteronFromBeauty; + averageLifetimeCDeuteron[1] /= nCDeuteronFromBeauty; + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout <<"# signal c-deuteron: " << nCDeuteron << "\n"; + std::cout <<"# signal c-deuteron decaying in the correct channel: " << nCDeuteronGoodDecay << "\n"; + std::cout <<"# signal c-deuteron from beauty: " << nCDeuteronFromBeauty << "\n"; + std::cout <<"Average lifetime of c-deuteron (prompt): " << averageLifetimeCDeuteron[0] << " (cm) \n"; + std::cout <<"Average lifetime of c-deuteron (non-prompt): " << averageLifetimeCDeuteron[1] << " (cm) \n"; + + float numberOfCDeuteronPerEvent = float(nCDeuteron) / nEvents; + float fracCDeuteronGoodDecay = float(nCDeuteronGoodDecay) / nCDeuteron; + float fracCDeuteronFromBeauty = float(nCDeuteronFromBeauty) / nCDeuteron; + + if (std::abs(numberOfCDeuteronPerEvent - checkNumberOfCDeuteronPerEvent) / numberOfCDeuteronPerEvent > 0.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of C-deuterons per event " << numberOfCDeuteronPerEvent << " different than expected " << checkNumberOfCDeuteronPerEvent << "\n"; + return 1; + } + + if (fracCDeuteronGoodDecay < 0.95) { // we put some tolerance since the number of generated events is small + std::cerr << "Fraction of signals decaying into the correct channel " << fracCDeuteronGoodDecay << " lower than expected\n"; + return 1; + } + + if (std::abs(fracCDeuteronFromBeauty - checkFracCDeuteronFromBeauty) / checkFracCDeuteronFromBeauty > 0.10) { // we put some tolerance since the number of generated events is small + std::cerr << "Fraction of signals from beauty " << fracCDeuteronFromBeauty << " different than expected " << checkFracCDeuteronFromBeauty << "\n"; + return 1; + } + + if (std::abs(averageLifetimeCDeuteron[0] - checkLifetimeCDeuteron) / checkLifetimeCDeuteron > 0.10) { // we put some tolerance since the number of generated events is small + std::cerr << "Lifetime for prompt c-deuteron " << averageLifetimeCDeuteron[0] << " different than expected " << checkLifetimeCDeuteron << "\n"; + return 1; + } + + if (std::abs(averageLifetimeCDeuteron[1] - checkLifetimeCDeuteron) / checkLifetimeCDeuteron > 0.10) { // we put some tolerance since the number of generated events is small + std::cerr << "Lifetime for non-prompt c-deuteron " << averageLifetimeCDeuteron[1] << " different than expected " << checkLifetimeCDeuteron << "\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg new file mode 100644 index 000000000..788e56fe3 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg @@ -0,0 +1,102 @@ +### author: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### since: May 2026 + +### beams (not relevant) +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### add the c-deuteron +### id:all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +2010010020:all = CDeuteron AntiCDeuteron 1 3 0 3.226 0 3.226 3.226 0.5 +2010010020:mayDecay = on + +# same as Λc+ -> p K- π+ including resonances + a neutron +2010010020:oneChannel = 1 0.14400 0 2112 2212 -321 211 ### cd+ -> n p K- π+ (non-resonant) 3.5% +2010010020:addChannel = 1 0.08100 100 2112 2212 -313 ### cd+ -> n p K*0(892) 1.96% +2010010020:addChannel = 1 0.04500 100 2112 2224 -321 ### cd+ -> n Delta++ K- 1.08% +2010010020:addChannel = 1 0.09000 100 2112 102134 211 ### cd+ -> n Lambda(1520) K- 2.20e-3 + +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 + +# Λb0 -> cd+ decays taken from PYTHIA +# NB: cd+ must always be the last daughter, not to screw up replacements in the generator +# 15% 2 body +5122:oneChannel = 1 0.15 0 2010010020 -2212 ### Λb0 -> cd+ anti-p +# 27% 3 body +5122:addChannel = 1 0.054 100 -2212 111 2010010020 ### Λb0 -> cd+ anti-p pi0 +5122:addChannel = 1 0.027 100 -2212 113 2010010020 ### Λb0 -> cd+ anti-p rho0 +5122:addChannel = 1 0.027 100 -2212 221 2010010020 ### Λb0 -> cd+ anti-p eta +5122:addChannel = 1 0.027 100 -2212 223 2010010020 ### Λb0 -> cd+ anti-p omega +5122:addChannel = 1 0.060 100 -2112 -211 2010010020 ### Λb0 -> cd+ anti-n0 pi- +5122:addChannel = 1 0.030 100 -2112 -213 2010010020 ### Λb0 -> cd+ anti-n0 rho- +5122:addChannel = 1 0.010 100 -2214 111 2010010020 ### Λb0 -> cd+ DeltaBar- pi0 +5122:addChannel = 1 0.005 100 -2214 113 2010010020 ### Λb0 -> cd+ DeltaBar- rho0 +5122:addChannel = 1 0.005 100 -2214 221 2010010020 ### Λb0 -> cd+ DeltaBar- eta +5122:addChannel = 1 0.005 100 -2214 223 2010010020 ### Λb0 -> cd+ DeltaBar- omega +5122:addChannel = 1 0.007 100 -2114 -211 2010010020 ### Λb0 -> cd+ DeltaBar0 pi- +5122:addChannel = 1 0.003 100 -2114 -213 2010010020 ### Λb0 -> cd+ DeltaBar0 rho- +5122:addChannel = 1 0.007 100 -2224 211 2010010020 ### Λb0 -> cd+ DeltaBar-- pi+ +5122:addChannel = 1 0.003 100 -2224 213 2010010020 ### Λb0 -> cd+ DeltaBar-- rho+ +5122:addChannel = 1 0.010 0 -3122 -321 2010010020 ### Λb0 -> cd+ Lambdabar0 K- +# 31% 4 body +5122:addChannel = 1 0.054 100 -2212 111 111 2010010020 ### Λb0 -> cd+ anti-p pi0 pi0 +5122:addChannel = 1 0.027 100 -2212 211 -211 2010010020 ### Λb0 -> cd+ anti-p pi+ pi- +5122:addChannel = 1 0.013 100 -2212 213 -211 2010010020 ### Λb0 -> cd+ anti-p rho+ pi- +5122:addChannel = 1 0.018 100 -2212 113 111 2010010020 ### Λb0 -> cd+ anti-p rho0 pi0 +5122:addChannel = 1 0.009 100 -2212 113 113 2010010020 ### Λb0 -> cd+ anti-p rho0 rho0 +5122:addChannel = 1 0.018 100 -2212 221 111 2010010020 ### Λb0 -> cd+ anti-p eta pi0 +5122:addChannel = 1 0.009 100 -2212 221 113 2010010020 ### Λb0 -> cd+ anti-p eta rho0 +5122:addChannel = 1 0.018 100 -2212 223 111 2010010020 ### Λb0 -> cd+ anti-p omega pi0 +5122:addChannel = 1 0.009 100 -2212 223 113 2010010020 ### Λb0 -> cd+ anti-p omega rho0 +5122:addChannel = 1 0.040 100 -2112 -211 111 2010010020 ### Λb0 -> cd+ anti-n0 pi- pi0 +5122:addChannel = 1 0.020 100 -2112 -211 113 2010010020 ### Λb0 -> cd+ anti-n0 pi- rho0 +5122:addChannel = 1 0.020 100 -2112 -213 111 2010010020 ### Λb0 -> cd+ anti-n0 rho- pi0 +5122:addChannel = 1 0.010 100 -2112 -213 113 2010010020 ### Λb0 -> cd+ anti-n0 rho- rho0 +5122:addChannel = 1 0.010 100 -2214 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- pi0 pi0 +5122:addChannel = 1 0.005 100 -2214 113 111 2010010020 ### Λb0 -> cd+ DeltaBar- rho0 pi0 +5122:addChannel = 1 0.005 100 -2214 221 111 2010010020 ### Λb0 -> cd+ DeltaBar- eta pi0 +5122:addChannel = 1 0.005 100 -2214 223 111 2010010020 ### Λb0 -> cd+ DeltaBar- omega pi0 +5122:addChannel = 1 0.007 100 -2114 -211 111 2010010020 ### Λb0 -> cd+ DeltaBar0 pi- pi0 +5122:addChannel = 1 0.003 100 -2114 -213 111 2010010020 ### Λb0 -> cd+ DeltaBar0 rho- pi0 +5122:addChannel = 1 0.007 100 -2224 211 111 2010010020 ### Λb0 -> cd+ DeltaBar-- pi+ pi0 +5122:addChannel = 1 0.003 100 -2224 213 111 2010010020 ### Λb0 -> cd+ DeltaBar-- rho+ pi0 +5122:addChannel = 1 0.010 0 -3122 -321 111 2010010020 ### Λb0 -> cd+ Lambdabar0 K- pi0 +# 19% 5 body +5122:addChannel = 1 0.033 100 -2212 111 111 111 2010010020 ### Λb0 -> cd+ anti-p pi0 pi0 pi0 +5122:addChannel = 1 0.016 100 -2212 211 -211 111 2010010020 ### Λb0 -> cd+ anti-p pi+ pi- pi0 +5122:addChannel = 1 0.008 100 -2212 213 -211 111 2010010020 ### Λb0 -> cd+ anti-p rho+ pi- pi0 +5122:addChannel = 1 0.012 100 -2212 113 111 111 2010010020 ### Λb0 -> cd+ anti-p rho0 pi0 pi0 +5122:addChannel = 1 0.006 100 -2212 113 113 111 2010010020 ### Λb0 -> cd+ anti-p rho0 rho0 pi0 +5122:addChannel = 1 0.012 100 -2212 221 111 111 2010010020 ### Λb0 -> cd+ anti-p eta pi0 pi0 +5122:addChannel = 1 0.006 100 -2212 221 113 111 2010010020 ### Λb0 -> cd+ anti-p eta rho0 pi0 +5122:addChannel = 1 0.012 100 -2212 223 111 111 2010010020 ### Λb0 -> cd+ anti-p omega pi0 pi0 +5122:addChannel = 1 0.006 100 -2212 223 113 111 2010010020 ### Λb0 -> cd+ anti-p omega rho0 pi0 +5122:addChannel = 1 0.030 100 -2112 -211 111 111 2010010020 ### Λb0 -> cd+ anti-n0 pi- pi0 pi0 +5122:addChannel = 1 0.011 100 -2112 -211 113 111 2010010020 ### Λb0 -> cd+ anti-n0 pi- rho0 pi0 +5122:addChannel = 1 0.011 100 -2112 -213 111 111 2010010020 ### Λb0 -> cd+ anti-n0 rho- pi0 pi0 +5122:addChannel = 1 0.006 100 -2112 -213 113 111 2010010020 ### Λb0 -> cd+ anti-n0 rho- rho0 pi0 +5122:addChannel = 1 0.006 100 -2214 111 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- pi0 pi0 pi0 +5122:addChannel = 1 0.002 100 -2214 113 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- rho0 pi0 pi0 +5122:addChannel = 1 0.002 100 -2214 221 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- eta pi0 pi0 +5122:addChannel = 1 0.002 100 -2214 223 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- omega pi0 pi0 +5122:addChannel = 1 0.005 100 -2114 -211 111 111 2010010020 ### Λb0 -> cd+ DeltaBar0 pi- pi0 pi0 +5122:addChannel = 1 0.001 100 -2114 -213 111 111 2010010020 ### Λb0 -> cd+ DeltaBar0 rho- pi0 pi0 +5122:addChannel = 1 0.005 100 -2224 211 111 111 2010010020 ### Λb0 -> cd+ DeltaBar-- pi+ pi0 pi0 +5122:addChannel = 1 0.001 100 -2224 213 111 111 2010010020 ### Λb0 -> cd+ DeltaBar-- rho+ pi0 pi0 +5122:addChannel = 1 0.006 0 -3122 -321 111 111 2010010020 ### Λb0 -> cd+ Lambdabar0 K- pi0 pi0 diff --git a/MC/config/common/external/generator/CoalescencePythia8.h b/MC/config/common/external/generator/CoalescencePythia8.h index b1f392ba4..7e4abc53e 100644 --- a/MC/config/common/external/generator/CoalescencePythia8.h +++ b/MC/config/common/external/generator/CoalescencePythia8.h @@ -104,7 +104,7 @@ bool doCoal(Pythia8::Event& event, int charge, int pdgCode, float mass, bool tri return true; } -bool CoalescencePythia8(Pythia8::Event& event, std::vector inputPdgList = {}, bool trivialCoal = false, double coalMomentum = 0.4, int firstDauID = -1, int lastDauId = -1) +bool CoalescencePythia8(Pythia8::Event& event, std::vector inputPdgList = {}, bool trivialCoal = false, double coalMomentum = 0.4, int firstDauID = -1, int lastDauId = -1, float maxRapidity = 1.) { const double coalescenceRadius{0.5 * 1.122462 * coalMomentum}; // if coalescence from a heavy hadron, loop only between firstDauID and lastDauID @@ -131,7 +131,7 @@ bool CoalescencePythia8(Pythia8::Event& event, std::vector inputPd // fill nucleon pools std::vector protons[2], neutrons[2], lambdas[2]; for (auto iPart{loopStart}; iPart <= loopEnd; ++iPart) { - if (std::abs(event[iPart].y()) > 1.) // skip particles with y > 1 + if (std::abs(event[iPart].y()) > maxRapidity) // skip particles with y > ymax { continue; } From ac1edfe57877b3c5d5034dacb876df77ed468962 Mon Sep 17 00:00:00 2001 From: mbroz84 Date: Wed, 3 Jun 2026 08:46:02 +0200 Subject: [PATCH 332/362] Forgotten include (#2371) --- MC/config/PWGUD/external/generator/Generator_nOOn.C | 1 + 1 file changed, 1 insertion(+) diff --git a/MC/config/PWGUD/external/generator/Generator_nOOn.C b/MC/config/PWGUD/external/generator/Generator_nOOn.C index dc19f9504..798c0d6b2 100644 --- a/MC/config/PWGUD/external/generator/Generator_nOOn.C +++ b/MC/config/PWGUD/external/generator/Generator_nOOn.C @@ -1,3 +1,4 @@ +R__ADD_INCLUDE_PATH($nOOn_ROOT/include) R__LOAD_LIBRARY(NeutronGenerator_cxx.so) #include "GeneratorStarlight.C" #include "NeutronGenerator.h" From 158189078c93d4674b8205aec5ac3a0bd2d02a0f Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Wed, 3 Jun 2026 14:50:47 +0200 Subject: [PATCH 333/362] MC/PWGEM: add ini for DYee in pp at 13.6 TeV (#2369) --- ...ratorDYee_GapTriggered_Gap5_pp13600GeV.ini | 7 +++ ...neratorDYee_GapTriggered_Gap5_pp13600GeV.C | 51 +++++++++++++++++++ MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh | 50 ++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini create mode 100644 MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.C create mode 100644 MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini new file mode 100644 index 000000000..7ecf763cf --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 2212, 2212, 13600.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.C new file mode 100644 index 000000000..0332e54fc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 2212) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh b/MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh new file mode 100644 index 000000000..77450c320 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC24ap,aq apass1 +# + +# example anchoring +# taken from https://its.cern.ch/jira/browse/O2-5670 +export ALIEN_JDL_LPMANCHORPASSNAME=apass1 +export ALIEN_JDL_MCANCHOR=apass1 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=559348 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC24a6 +export ALIEN_JDL_LPMANCHORRUN=559348 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC26ac +export ALIEN_JDL_LPMANCHORYEAR=2026 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 20/40/40 sampling for different generators +# generate random number +#RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh From 61a7bb7e14c6c439918d9a2e23ac1b66bd383848 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Wed, 3 Jun 2026 15:20:32 +0200 Subject: [PATCH 334/362] Apply correction for energy (non)conservation in coalescence for c-deuteron (#2372) --- .../generator_pythia8_embed_charmnuclei.C | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C index 4b6e9a3f7..9e2667e4f 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C @@ -9,6 +9,9 @@ #include #include +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" + R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) #include "MC/config/common/external/generator/CoalescencePythia8.h" @@ -240,6 +243,7 @@ class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 // we try the coalescence here, if successful we copy particles in the pythia event and we move to the next charm nucleus isCoalSuccess = CoalescencePythia8(mPythiaGun.event, std::vector{1000010020}, mTrivialCoal, mCoalMomentum, dausToCoal[0], dausToCoal[1], 10.); if (isCoalSuccess) { + restoreEnergyConservation(mPythiaGun.event, idxCharmNucleus); int offset = mPythia.event.size(); // we need to rescale the indices of mothers and daughters, accounting for the particles that are already appended to the event for (int iPart{0}; iPart targetMassTolerance) { + ROOT::Math::PxPyPzMVector fourVecCharmNucleus; + for (int iDau{event[idxCharmNucleus].daughter1()}; iDau<=event[idxCharmNucleus].daughter2(); ++iDau) { + auto dau = event[iDau]; + fourVecCharmNucleus += ROOT::Math::PxPyPzMVector(dau.px() * scale, dau.py() * scale, dau.pz() * scale, dau.m()); + } + invMass = fourVecCharmNucleus.M(); + scale *= mMassCharmNucleus / invMass; + } + + for (int iDau{event[idxCharmNucleus].daughter1()}; iDau<=event[idxCharmNucleus].daughter2(); ++iDau) { + event[iDau].px(event[iDau].px() * scale); + event[iDau].py(event[iDau].py() * scale); + event[iDau].pz(event[iDau].pz() * scale); + } + event[idxCharmNucleus].px(event[idxCharmNucleus].px() * scale); + event[idxCharmNucleus].py(event[idxCharmNucleus].py() * scale); + event[idxCharmNucleus].pz(event[idxCharmNucleus].pz() * scale); + } + // Properties of selection float mMassCharmNucleus; /// mass of the charmed nucleus int mPdgCharmNucleus; /// pdg code of the charmed nucleus From 28b44ef02b56a9a80c709e3a2b9c4bb83772af39 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 4 Jun 2026 17:12:54 +0200 Subject: [PATCH 335/362] AODBcRewriter: regroup tracks by collision so the -1 group stays contiguous (#2370) --- MC/utils/AODBcRewriter.C | 184 +++++++++++++++++++++++++++++++++++---- 1 file changed, 165 insertions(+), 19 deletions(-) diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C index 710b643bd..4c0240fdb 100644 --- a/MC/utils/AODBcRewriter.C +++ b/MC/utils/AODBcRewriter.C @@ -14,8 +14,9 @@ // // This tool fixes all three problems in one pass per DF_ directory: // -// Stage 0 — Sort & deduplicate the BC table. Build BC permutation map: -// bcPerm[oldBCrow] = newBCrow. +// Stage 0 — Deduplicate the BC table in place (order-preserving; the input +// must already be globalBC-sorted). Build BC permutation map: +// bcPerm[oldBCrow] = newBCrow (monotonic non-decreasing). // // Stage 1 — Process every table that carries fIndexBCs / fIndexBC. // Remap the index via bcPerm, sort rows by the new index, and @@ -501,18 +502,31 @@ static PermMap rewriteTable(TTree *src, TDirectory *dirOut, } // ============================================================================ -// SECTION 4 — Stage 0: BC table sort + deduplication +// SECTION 4 — Stage 0: BC table deduplication (order-preserving) // ============================================================================ // -// Reads fGlobalBC from the BC tree, sorts rows, drops exact-duplicate BC -// values, and writes the compacted table. Returns bcPerm[oldRow] = newRow. +// Reads fGlobalBC from the BC tree, drops exact-duplicate BC values IN PLACE +// (preserving input row order), and writes the compacted table. Returns +// bcPerm[oldRow] = newRow. +// +// The dedup is deliberately order-preserving so that bcPerm is monotonic +// non-decreasing. This matters because every BC-indexed table (collisions, +// FT0/FV0/FDD/Zdc, ...) is sliced per BC and must stay sorted by its fIndexBCs, +// and collisions are in turn the grouping anchor for tracks (sorted by +// fIndexCollisions). A non-order-preserving BC remap would force a full reorder +// cascade BC -> collisions -> tracks to keep all those groupings valid; keeping +// bcPerm monotonic means none of those tables need to be reordered at all. +// +// This REQUIRES the input BC table to already be sorted by fGlobalBC (the +// standard AO2D invariant; also asserted on the output by validateDF check #1). +// We assert it loudly rather than silently emit a non-monotonic BC table. struct BCStage0Result { - PermMap bcPerm; // bcPerm[oldRow] = newRow in sorted/deduped BC table + PermMap bcPerm; // bcPerm[oldRow] = newRow in the deduped BC table Long64_t nUnique = 0; }; -static BCStage0Result stage0_sortBCs(TTree *treeBCs, TDirectory *dirOut) { +static BCStage0Result stage0_dedupBCs(TTree *treeBCs, TDirectory *dirOut) { BCStage0Result res; Long64_t n = treeBCs->GetEntries(); if (n == 0) return res; @@ -525,19 +539,29 @@ static BCStage0Result stage0_sortBCs(TTree *treeBCs, TDirectory *dirOut) { std::vector gbcs(n); for (Long64_t i = 0; i < n; ++i) { treeBCs->GetEntry(i); gbcs[i] = gbc; } - // Sort row indices by fGlobalBC - std::vector order(n); - std::iota(order.begin(), order.end(), 0); - std::stable_sort(order.begin(), order.end(), - [&](Long64_t a, Long64_t b){ return gbcs[a] < gbcs[b]; }); + // The BC table must already be sorted by fGlobalBC: the dedup below is + // order-preserving (merges only adjacent equal-globalBC rows), which keeps + // bcPerm monotonic and avoids a reorder cascade through collisions/tracks. + // A non-monotonic input would silently break that guarantee, so abort loudly. + for (Long64_t i = 1; i < n; ++i) { + if (gbcs[i] < gbcs[i - 1]) { + std::cerr << "FATAL: O2bc_* table is not sorted by fGlobalBC (row " << i + << " globalBC=" << gbcs[i] << " < row " << (i - 1) + << " globalBC=" << gbcs[i - 1] << ").\n" + << " AODBcRewriter requires a globalBC-sorted BC table so that\n" + << " BC deduplication is order-preserving; aborting.\n"; + std::abort(); + } + } - // Build deduplicated row list and the permutation + // Build the deduplicated row list and the (monotonic) permutation in source + // row order: adjacent rows sharing a globalBC collapse onto one output row. res.bcPerm.assign(n, -1); std::vector rowOrder; // source rows to keep, in output order - ULong64_t prev = ULong64_t(-1); + ULong64_t prev = 0; Int_t newRow = -1; - for (Long64_t srcRow : order) { - if (gbcs[srcRow] != prev) { + for (Long64_t srcRow = 0; srcRow < n; ++srcRow) { + if (newRow < 0 || gbcs[srcRow] != prev) { ++newRow; prev = gbcs[srcRow]; rowOrder.push_back(srcRow); @@ -547,7 +571,7 @@ static BCStage0Result stage0_sortBCs(TTree *treeBCs, TDirectory *dirOut) { } res.nUnique = rowOrder.size(); - std::cout << " BC stage: " << n << " rows -> " << res.nUnique << " unique\n"; + std::cout << " BC stage: " << n << " rows -> " << res.nUnique << " unique (in-place dedup)\n"; // Write the BC table (no index remapping needed for the table itself) rewriteTable(treeBCs, dirOut, rowOrder, /*indexBranch=*/"", /*parentPerm=*/{}); @@ -858,6 +882,98 @@ static const PermMap *findPermByPrefix( return nullptr; } +// ============================================================================ +// SECTION 9b — Stage 1b: Collision-grouped track tables +// ============================================================================ +// +// The primary track tables (O2track_iu, O2mfttrack_*, O2fwdtrack) are GROUPED +// by collision. O2's slicing cache (ArrowTableSlicingCache::validateOrder) +// requires every fIndexCollisions group — including the "-1" ambiguous group — +// to be a single contiguous run; otherwise it aborts with +// "Table ... index fIndexCollisions has a group with index -1 that is split". +// +// When several MC sub-timeframes are merged into one DF_ folder (data-embedding +// anchoring, which stores MC timeframes under the same DF_ as the parent data +// file), each sub-frame contributes its own [collision-grouped][-1 ambiguous] +// block. Concatenating them splits the -1 group into N runs, so the table is +// no longer sliceable. Stage 1 only reorders BC-indexed tables, and tracks are +// otherwise written in input row order, so the split survives into the output. +// +// This stage re-establishes the grouping: it reorders each collision-grouped +// track table by its remapped fIndexCollisions (stable, with -1 sinking to the +// end so the ambiguous group is one contiguous run — matching the Stage 1 +// convention) and publishes the resulting row permutation. Downstream: +// * paste-join children (O2trackextra, O2trackcov_iu, O2mctracklabel, ...) +// follow the published parent permutation; +// * every fIndexTracks* / fIndexMFTTracks / fIndexFwdTracks reference is +// remapped through it in processPasteJoinTables. +static bool isCollGroupedTrackTable(const std::string &tname) { + static const char *kPrefixes[] = {"O2track_iu", "O2track", + "O2mfttrack", "O2fwdtrack"}; + for (auto *p : kPrefixes) + if (TString(tname.c_str()).BeginsWith(p)) return true; + return false; +} + +static void stage1b_reorderTrackTables( + TDirectory *dirIn, TDirectory *dirOut, + std::unordered_map &allPerms, + std::unordered_set &written) { + + const PermMap *collPermP = findPermByPrefix(allPerms, "O2collision_"); + if (!collPermP) return; // no collisions present — nothing to regroup against + + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (written.count(tname)) continue; // BC-indexed tracks etc. already done + if (!isCollGroupedTrackTable(tname)) continue; + if (isPasteJoinChild(tname)) continue; // children follow their parent below + if (!src->GetBranch("fIndexCollisions")) continue; + + std::cout << " Stage1b [coll-grouped]: " << tname << "\n"; + + Long64_t nSrc = src->GetEntries(); + TBranch *inIdxBr = src->GetBranch("fIndexCollisions"); + TLeaf *idxLeaf = static_cast(inIdxBr->GetListOfLeaves()->At(0)); + ScalarTag idxTag = tagOf(idxLeaf); + std::vector idxBuf(byteSize(idxTag), 0); + inIdxBr->SetAddress(idxBuf.data()); + + struct SortEntry { Long64_t newColl; Long64_t srcRow; }; + std::vector entries; + entries.reserve(nSrc); + for (Long64_t i = 0; i < nSrc; ++i) { + inIdxBr->GetEntry(i); + Long64_t oldColl = readAsInt(idxBuf.data(), idxTag); + Long64_t newColl = (oldColl >= 0 && oldColl < (Long64_t)collPermP->size()) + ? (*collPermP)[oldColl] : -1; + entries.push_back({newColl, i}); + } + // Stable-sort by remapped collision; the ambiguous group (-1) sinks to the + // end as a single contiguous run. Stable keeps the within-collision order. + std::stable_sort(entries.begin(), entries.end(), + [](const SortEntry &a, const SortEntry &b){ + if (a.newColl < 0 && b.newColl >= 0) return false; + if (a.newColl >= 0 && b.newColl < 0) return true; + return a.newColl < b.newColl; + }); + std::vector rowOrder; + rowOrder.reserve(nSrc); + for (auto &e : entries) rowOrder.push_back(e.srcRow); + + // Reorder rows and remap fIndexCollisions values through collPerm. + PermMap perm = rewriteTable(src, dirOut, rowOrder, "fIndexCollisions", *collPermP); + allPerms[tname] = std::move(perm); + written.insert(tname); + } +} + static void processPasteJoinTables( TDirectory *dirIn, TDirectory *dirOut, const std::unordered_map &allPerms, @@ -870,6 +986,12 @@ static void processPasteJoinTables( const PermMap *mcParticlePerm = findPermByPrefix(allPerms, "O2mcparticle"); const PermMap *mcCollPermP = findPermByPrefix(allPerms, "O2mccollision_"); const PermMap *collPermP = findPermByPrefix(allPerms, "O2collision_"); + // Track tables reordered in Stage 1b: every reference into them must be + // remapped through their permutation (null if the table is absent / wasn't + // reordered, in which case no remap is needed). + const PermMap *trkPerm = findPermByPrefix(allPerms, "O2track_iu"); + const PermMap *mftPerm = findPermByPrefix(allPerms, "O2mfttrack"); + const PermMap *fwdPerm = findPermByPrefix(allPerms, "O2fwdtrack"); // bcPermP is passed in from processDF (the BC table is the only stage // whose permutation isn't already published in allPerms). @@ -918,6 +1040,23 @@ static void processPasteJoinTables( extraRemaps.push_back({"fIndexBC", bcPermP}); } + // Track-pointing indices: the track tables may have been reordered in + // Stage 1b, so every reference into them must be remapped through the + // corresponding permutation. (No-op when the perm is null / absent.) + auto addTrkRemap = [&](const char *br, const PermMap *pm) { + if (pm && src->GetBranch(br)) extraRemaps.push_back({br, pm}); + }; + addTrkRemap("fIndexTracks", trkPerm); + addTrkRemap("fIndexTracks_0", trkPerm); + addTrkRemap("fIndexTracks_1", trkPerm); + addTrkRemap("fIndexTracks_2", trkPerm); + addTrkRemap("fIndexTracks_Pos", trkPerm); + addTrkRemap("fIndexTracks_Neg", trkPerm); + addTrkRemap("fIndexTracks_ITS", trkPerm); + addTrkRemap("fIndexMFTTracks", mftPerm); + addTrkRemap("fIndexFwdTracks", fwdPerm); + addTrkRemap("fIndexFwdTracks_MatchMCHTrack", fwdPerm); + // Find a paste-join parent for this table (kPasteJoins lookup). const PermMap *parentPerm = nullptr; std::string parentName; @@ -1020,10 +1159,10 @@ static void processDF(TDirectory *dirIn, TDirectory *dirOut) { return; } - // ---- Stage 0: sort & deduplicate BCs ---- + // ---- Stage 0: deduplicate BCs (order-preserving) ---- std::cout << "-- Stage 0: BCs --\n"; dirOut->cd(); - BCStage0Result s0 = stage0_sortBCs(treeBCs, dirOut); + BCStage0Result s0 = stage0_dedupBCs(treeBCs, dirOut); if (treeFlags) stage0_copyBCFlags(treeFlags, dirOut, s0.bcPerm); // Track which tree names have been written so we don't double-write @@ -1056,6 +1195,13 @@ static void processDF(TDirectory *dirIn, TDirectory *dirOut) { std::cout << " (no MCCollision table found — skipping stage 2)\n"; } + // ---- Stage 1b: regroup collision-grouped track tables ---- + // Must run after Stage 1 (needs the collision permutation) and before the + // paste-join stage (so children follow the new track order and fIndexTracks* + // references are remapped). Publishes track permutations into stage1Perms. + std::cout << "-- Stage 1b: collision-grouped track tables --\n"; + stage1b_reorderTrackTables(dirIn, dirOut, stage1Perms, written); + // ---- Paste-join tables + unrelated tables ---- std::cout << "-- Paste-join and unrelated tables --\n"; processPasteJoinTables(dirIn, dirOut, stage1Perms, written, &s0.bcPerm); From db02ffaf2f6daa596bf6eee883b734f8ad481e46 Mon Sep 17 00:00:00 2001 From: Nicole Bastid <75683312+NicoleBastid@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:13:05 +0200 Subject: [PATCH 336/362] PWGHF: beauty production production at forward y with natural decay and muon trigger (#2367) * Add files via upload PWGHF: beauty production with natural decay at forward y with trigger on muons * Add files via upload PWGHF: beauty production with natural deay at forward y with trigger on muons * Apply suggestion from @wuctlby * remove the empty line * Apply suggestion from @wuctlby --------- Co-authored-by: Chuntai <48704924+wuctlby@users.noreply.github.com> --- ...bar_fwd_gap4_natural_inel_Mode2_muTrig.ini | 8 ++ ...bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C | 103 ++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.ini new file mode 100644 index 000000000..b126fceed --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(4, -5, -1.5, -4.3, -2.2, {13}) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C new file mode 100644 index 000000000..34072820e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C @@ -0,0 +1,103 @@ +int External() { + + int checkPdgDecayMuon = 13; + int checkPdgQuark = 5; + + float ratioTrigger = 1. / 4; // one event triggered out of 4 + + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}; + int nEventsInj{}; + int nQuarks{}; + int nMuons{}; + + int nMuonsInAcceptance{}; + + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } // if event header + + int nmuonsev = 0; + int nmuonsevinacc = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } // pdgquark + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayMuon) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nMuons++; + nmuonsev++; + if (-4.3 < y && y < -2.2) { + nMuonsInAcceptance++; + nmuonsevinacc++; + } + } // gmpdg + + } // pdgdecay + + } // loop track + // std::cout << "#muons per event: " << nmuonsev << "\n"; + // std::cout << "#muons in acceptance per event: " << nmuonsev << "\n"; + } // events + + std::cout << "#events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) + << nEventsInj << "\n"; + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || + nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark + << " different than expected\n"; + return 1; + } + std::cout << "#muons: " << nMuons << "\n"; + std::cout << "#muons in acceptance: " << nMuonsInAcceptance << "\n"; + + return 0; +} // external From c912611fd486260e85e7e21abc6a69f4393d253e Mon Sep 17 00:00:00 2001 From: MRazza <118839113+MRazza879@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:19:44 +0200 Subject: [PATCH 337/362] [PWGHF] Add Pythia8 B- CRmode2 config and BToDeuteron trigger ini (#2366) * [PWGHF] Add Pythia8 B- CRmode2 config and BToDeuteron trigger ini * [PWGHF] Add test macro for BToDeuteron HF trigger * Add O2DPG_TEST directive to GeneratorHFTrigger_BToDeuteron.ini * Switch B+ decay from offIfMatch to onIfMatch * Remove fraction check in BToDeuteron test * Fix BToDeuteron Pythia8 config * Adding all the available final states Uncommenting the decay with the lower BR * Removing empty lines --------- Co-authored-by: Marta Razza --- .../ini/GeneratorHFTrigger_BToDeuteron.ini | 8 ++ .../tests/GeneratorHFTrigger_BToDeuteron.C | 48 +++++++++++ .../generator/pythia8_bminus_CRmode2.cfg | 81 +++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHFTrigger_BToDeuteron.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_BToDeuteron.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_BToDeuteron.ini new file mode 100644 index 000000000..95bf68b19 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_BToDeuteron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 10 +#O2DPG_TEST> ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C +funcName=generateHFHadToNuclei(3, {521}, {1000010020}, true, 0.5) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C new file mode 100644 index 000000000..bd56f98e6 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C @@ -0,0 +1,48 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector checkPdgHadron{521}; + std::vector nucleiDauPdg{1000010020}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) + { + if(std::abs(track.GetRapidity()) > 1.5) continue; + nSignals++; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + if (std::find(nucleiDauPdg.begin(), nucleiDauPdg.end(), std::abs(pdgDau)) != nucleiDauPdg.end()) + { + nSignalGoodDecay++; + } + } + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# signal hadrons: " << nSignals << "\n"; + std::cout << "# signal hadrons decaying into nuclei: " << nSignalGoodDecay << "\n"; + + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg new file mode 100644 index 000000000..285f42a79 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg @@ -0,0 +1,81 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 +BeamRemnants:allowBeamJunction = off +BeamRemnants:beamJunction = off +ColourReconnection:allowDiquarkJunctionCR = off + +# Correct decay lengths +# B+ +521:tau0 = 0.4914 # PDG: 1.638 ps -> c*tau = 0.4914 mm + +## B+ (521) decay modes – at least 2 nucleons in the final states +521:onMode = off +521:oneChannel = 1 3e-07 0 -2112 -2112 111 2112 2212 +521:addChannel = 1 3e-07 0 -3122 -2212 213 2112 2212 +521:addChannel = 1 3e-07 0 -2212 -2112 111 323 2112 2212 +521:addChannel = 1 3e-07 0 -2212 -2112 -211 211 321 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2212 211 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2212 -211 111 111 211 211 221 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2112 111 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2112 -211 111 211 2112 2212 +521:addChannel = 1 2e-07 0 -2214 -2212 111 211 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2212 211 211 311 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2212 113 211 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2212 111 111 211 211 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 211 311 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 113 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 111 221 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 111 113 211 2112 2212 +521:addChannel = 1 2e-07 0 -2112 -2112 -211 211 311 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 -211 113 211 211 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 -211 111 211 211 2112 2212 +521:addChannel = 1 2e-07 0 -2112 -2112 221 223 2112 2212 +521:addChannel = 1 2e-07 0 -2112 -2112 111 221 2112 2212 +521:onIfMatch = -2112 -2112 111 2112 2212 +521:onIfMatch = -3122 -2212 213 2112 2212 +521:onIfMatch = -2212 -2112 111 323 2112 2212 +521:onIfMatch = -2212 -2112 -211 211 321 2112 2212 +521:onIfMatch = -3122 -2212 211 2112 2212 +521:onIfMatch = -3122 -2212 -211 111 111 211 211 221 2112 2212 +521:onIfMatch = -3122 -2112 111 2112 2212 +521:onIfMatch = -3122 -2112 -211 111 211 2112 2212 +521:onIfMatch = -2214 -2212 111 211 321 2112 2212 +521:onIfMatch = -2212 -2212 211 211 311 2112 2212 +521:onIfMatch = -2212 -2212 113 211 321 2112 2212 +521:onIfMatch = -2212 -2212 111 111 211 211 2112 2212 +521:onIfMatch = -2212 -2112 211 311 2112 2212 +521:onIfMatch = -2212 -2112 113 321 2112 2212 +521:onIfMatch = -2212 -2112 111 221 321 2112 2212 +521:onIfMatch = -2212 -2112 111 113 211 2112 2212 +521:onIfMatch = -2112 -2112 -211 211 311 2112 2212 +521:onIfMatch = -2212 -2112 -211 113 211 211 2112 2212 +521:onIfMatch = -2212 -2112 -211 111 211 211 2112 2212 +521:onIfMatch = -2112 -2112 221 223 2112 2212 +521:onIfMatch = -2112 -2112 111 221 2112 2212 From f952905579f1d3e1febc95e47e4e95b4854ce3fc Mon Sep 17 00:00:00 2001 From: sigurd Date: Mon, 8 Jun 2026 09:42:10 +0200 Subject: [PATCH 338/362] Fix typo in CCDB path to FT0 EventsPerBc --- MC/bin/o2dpg_sim_workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 1bbd30fe6..dcd535a22 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -674,7 +674,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): f'--timestamp {args.timestamp}', f'--import-external {args.data_anchoring}' if len(args.data_anchoring) > 0 else None, '--bcPatternFile ccdb', - ' --nontrivial-mu-distribution ccdb://https://alice-ccdb.cern.ch/FTO/Calib/EventsPerBc', + ' --nontrivial-mu-distribution ccdb://https://alice-ccdb.cern.ch/FT0/Calib/EventsPerBc', f'--QEDinteraction {qedspec}' if includeQED else None ], configname = 'precollcontext') workflow['stages'].append(PreCollContextTask) From cdb0b6eced197dd8d2bca750eb067e9909b4bdbb Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Mon, 8 Jun 2026 17:25:25 +0200 Subject: [PATCH 339/362] Add NeNe and OO EPOS4HQ configurations (#2374) --- .../epos4/generator/NeNe_536TeV_EPOS4HQ.optns | 34 +++++++++++++++++++ .../epos4/generator/OO_536TeV_EPOS4HQ.optns | 34 +++++++++++++++++++ .../ini/GeneratorEPOS4HQNeNe536TeV.ini | 13 +++++++ .../examples/ini/GeneratorEPOS4HQOO536TeV.ini | 13 +++++++ 4 files changed, 94 insertions(+) create mode 100644 MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns create mode 100644 MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns create mode 100644 MC/config/examples/ini/GeneratorEPOS4HQNeNe536TeV.ini create mode 100644 MC/config/examples/ini/GeneratorEPOS4HQOO536TeV.ini diff --git a/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns new file mode 100644 index 000000000..294a581ac --- /dev/null +++ b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns @@ -0,0 +1,34 @@ +!-------------------------------------------------------------------- +! Neon-Neon collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 10 !projectile atomic number +set maproj 20 !projectile mass number +set latarg 10 !target atomic number +set matarg 20 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable +set ihq 1 !Enables HQ +set nfull 10 diff --git a/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns new file mode 100644 index 000000000..ac4dacb34 --- /dev/null +++ b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns @@ -0,0 +1,34 @@ +!-------------------------------------------------------------------- +! Oxygen-Oxygen collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 8 !projectile atomic number +set maproj 16 !projectile mass number +set latarg 8 !target atomic number +set matarg 16 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable +set ihq 1 !Enables HQ +set nfull 10 diff --git a/MC/config/examples/ini/GeneratorEPOS4HQNeNe536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4HQNeNe536TeV.ini new file mode 100644 index 000000000..b54fff7d5 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4HQNeNe536TeV.ini @@ -0,0 +1,13 @@ +#NEV_TEST> 10 +#---> GeneratorEPOS4NeNe536TeV +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4HQOO536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4HQOO536TeV.ini new file mode 100644 index 000000000..6f1407888 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4HQOO536TeV.ini @@ -0,0 +1,13 @@ +#NEV_TEST> 1 +#---> GeneratorEPOS4OO536TeV +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 From c19050ca965c7bc7b07c1a37126100f83789f582 Mon Sep 17 00:00:00 2001 From: Rrantu <156880782+Rrantu@users.noreply.github.com> Date: Tue, 9 Jun 2026 14:58:56 +0200 Subject: [PATCH 340/362] Add Lc DPMJET trigger support for PWGUD Starlight configs (#2376) * Add triggerLc function for Lambda_c particle selection * Refactor process argument choices in makeStarlightConfig.py --- MC/config/PWGUD/ini/makeStarlightConfig.py | 2 +- MC/config/PWGUD/trigger/triggerDpmjetParticle.C | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/MC/config/PWGUD/ini/makeStarlightConfig.py b/MC/config/PWGUD/ini/makeStarlightConfig.py index 39f78de27..46dc4823c 100755 --- a/MC/config/PWGUD/ini/makeStarlightConfig.py +++ b/MC/config/PWGUD/ini/makeStarlightConfig.py @@ -17,7 +17,7 @@ parser.add_argument('--rapidity', default='cent', choices=['cent_rap', 'muon_rap', 'cent_eta', 'muon_eta'], help='Rapidity to select') -parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsiToLLbar', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToL+3Pi', 'kTauLowToL-3Pi', 'kTauLowToPi+3Pi', 'kTauLowToPi-3Pi', 'kTauLowTo6Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], +parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsiToLLbar', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Lc', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Lc', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToL+3Pi', 'kTauLowToL-3Pi', 'kTauLowToPi+3Pi', 'kTauLowToPi-3Pi', 'kTauLowTo6Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], help='Process to switch on') diff --git a/MC/config/PWGUD/trigger/triggerDpmjetParticle.C b/MC/config/PWGUD/trigger/triggerDpmjetParticle.C index ada196467..acc9cf258 100644 --- a/MC/config/PWGUD/trigger/triggerDpmjetParticle.C +++ b/MC/config/PWGUD/trigger/triggerDpmjetParticle.C @@ -66,5 +66,17 @@ o2::eventgen::Trigger triggerKstar(double rapidityMin = -1., double rapidityMax }; } +o2::eventgen::Trigger triggerLc(double rapidityMin = -1., double rapidityMax = -1.) +{ + return [rapidityMin, rapidityMax](const std::vector& particles) -> bool { + for (const auto& particle : particles) { + if (TMath::Abs(particle.GetPdgCode()) == 4122) + if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) + return kTRUE; + } + return kFALSE; + }; +} + From 5597f516f007409dac00bae497e3263da53c9125 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 9 Jun 2026 10:02:52 +0200 Subject: [PATCH 341/362] AODBcRewriter: restore BC sort in Stage 0, keep track regrouping Commit 28b44ef replaced the Stage 0 BC sort with an order-preserving dedup that std::abort()s unless the input BC table is already globalBC-sorted. That contradicts the tool's purpose (PURPOSE (a): repairing non-monotonic fGlobalBC in merged AO2Ds), so it aborted on exactly the files it exists to fix -- the "doesn't run to completion" regression. Revert only that Stage 0 change (restore stage0_sortBCs, drop the abort). Keep 28b44ef's Stage 1b track regrouping and the fIndexTracks* remaps: that mechanism is the correct fix for the -1-group split from b11cd3de (track fIndexCollisions values were remapped but rows left in input order, so per-collision groups -- including the -1 ambiguous group -- were no longer contiguous, tripping ArrowTableSlicingCache::validateOrder downstream). It only ever failed because the aborting Stage 0 stopped it running. Sorting BCs implies a BC -> collisions (Stage 1) -> tracks (Stage 1b) reorder cascade, which those stages now handle completely. Add a validator check (checkCollisionGroupContiguity) mirroring O2's slicing invariant: every fIndexCollisions group must be one contiguous run. Added a history note in Stage 0 against re-introducing the order-preserving abort. Not yet validated against a real merged AO2D / analysis task. Co-Authored-By: Claude Opus 4.8 --- MC/utils/AODBcRewriter.C | 125 +++++++++++++++++++++++++++------------ MC/utils/CLAUDE.md | 93 ++++++++++++++++++++++++++++- 2 files changed, 178 insertions(+), 40 deletions(-) diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C index 4c0240fdb..16c7451ef 100644 --- a/MC/utils/AODBcRewriter.C +++ b/MC/utils/AODBcRewriter.C @@ -14,9 +14,8 @@ // // This tool fixes all three problems in one pass per DF_ directory: // -// Stage 0 — Deduplicate the BC table in place (order-preserving; the input -// must already be globalBC-sorted). Build BC permutation map: -// bcPerm[oldBCrow] = newBCrow (monotonic non-decreasing). +// Stage 0 — Sort & deduplicate the BC table. Build BC permutation map: +// bcPerm[oldBCrow] = newBCrow. // // Stage 1 — Process every table that carries fIndexBCs / fIndexBC. // Remap the index via bcPerm, sort rows by the new index, and @@ -502,31 +501,33 @@ static PermMap rewriteTable(TTree *src, TDirectory *dirOut, } // ============================================================================ -// SECTION 4 — Stage 0: BC table deduplication (order-preserving) +// SECTION 4 — Stage 0: BC table sort + deduplication // ============================================================================ // -// Reads fGlobalBC from the BC tree, drops exact-duplicate BC values IN PLACE -// (preserving input row order), and writes the compacted table. Returns -// bcPerm[oldRow] = newRow. +// Reads fGlobalBC from the BC tree, sorts rows, drops exact-duplicate BC +// values, and writes the compacted table. Returns bcPerm[oldRow] = newRow. // -// The dedup is deliberately order-preserving so that bcPerm is monotonic -// non-decreasing. This matters because every BC-indexed table (collisions, -// FT0/FV0/FDD/Zdc, ...) is sliced per BC and must stay sorted by its fIndexBCs, -// and collisions are in turn the grouping anchor for tracks (sorted by -// fIndexCollisions). A non-order-preserving BC remap would force a full reorder -// cascade BC -> collisions -> tracks to keep all those groupings valid; keeping -// bcPerm monotonic means none of those tables need to be reordered at all. +// IMPORTANT (history — do not "optimize" this back): +// A previous revision replaced this sort with an order-preserving in-place +// dedup that std::abort()ed unless the input BC table was already globalBC- +// sorted. That directly contradicts this tool's PURPOSE (a) at the top of the +// file — repairing *non-monotonic* fGlobalBC in MERGED AO2Ds — so it aborted on +// exactly the files it exists to fix ("doesn't run to completion"). We sort +// unconditionally instead. // -// This REQUIRES the input BC table to already be sorted by fGlobalBC (the -// standard AO2D invariant; also asserted on the output by validateDF check #1). -// We assert it loudly rather than silently emit a non-monotonic BC table. +// Sorting BCs does imply a reorder cascade: collisions are sorted by their +// remapped fIndexBCs in Stage 1, and the collision-grouped track tables must +// then be re-grouped to follow the new collision order in Stage 1b. That +// cascade is real and unavoidable for non-monotonic input; it is handled +// explicitly and completely by those stages. This is the correct fix — keep +// it. An "assert already sorted" shortcut here is a known dead end. struct BCStage0Result { - PermMap bcPerm; // bcPerm[oldRow] = newRow in the deduped BC table + PermMap bcPerm; // bcPerm[oldRow] = newRow in sorted/deduped BC table Long64_t nUnique = 0; }; -static BCStage0Result stage0_dedupBCs(TTree *treeBCs, TDirectory *dirOut) { +static BCStage0Result stage0_sortBCs(TTree *treeBCs, TDirectory *dirOut) { BCStage0Result res; Long64_t n = treeBCs->GetEntries(); if (n == 0) return res; @@ -539,28 +540,20 @@ static BCStage0Result stage0_dedupBCs(TTree *treeBCs, TDirectory *dirOut) { std::vector gbcs(n); for (Long64_t i = 0; i < n; ++i) { treeBCs->GetEntry(i); gbcs[i] = gbc; } - // The BC table must already be sorted by fGlobalBC: the dedup below is - // order-preserving (merges only adjacent equal-globalBC rows), which keeps - // bcPerm monotonic and avoids a reorder cascade through collisions/tracks. - // A non-monotonic input would silently break that guarantee, so abort loudly. - for (Long64_t i = 1; i < n; ++i) { - if (gbcs[i] < gbcs[i - 1]) { - std::cerr << "FATAL: O2bc_* table is not sorted by fGlobalBC (row " << i - << " globalBC=" << gbcs[i] << " < row " << (i - 1) - << " globalBC=" << gbcs[i - 1] << ").\n" - << " AODBcRewriter requires a globalBC-sorted BC table so that\n" - << " BC deduplication is order-preserving; aborting.\n"; - std::abort(); - } - } + // Sort row indices by fGlobalBC (stable, so equal-globalBC rows keep their + // input order before being collapsed below). + std::vector order(n); + std::iota(order.begin(), order.end(), 0); + std::stable_sort(order.begin(), order.end(), + [&](Long64_t a, Long64_t b){ return gbcs[a] < gbcs[b]; }); - // Build the deduplicated row list and the (monotonic) permutation in source - // row order: adjacent rows sharing a globalBC collapse onto one output row. + // Build the deduplicated row list and the permutation: rows sharing a + // globalBC collapse onto one output row. res.bcPerm.assign(n, -1); std::vector rowOrder; // source rows to keep, in output order ULong64_t prev = 0; Int_t newRow = -1; - for (Long64_t srcRow = 0; srcRow < n; ++srcRow) { + for (Long64_t srcRow : order) { if (newRow < 0 || gbcs[srcRow] != prev) { ++newRow; prev = gbcs[srcRow]; @@ -571,7 +564,7 @@ static BCStage0Result stage0_dedupBCs(TTree *treeBCs, TDirectory *dirOut) { } res.nUnique = rowOrder.size(); - std::cout << " BC stage: " << n << " rows -> " << res.nUnique << " unique (in-place dedup)\n"; + std::cout << " BC stage: " << n << " rows -> " << res.nUnique << " unique (sorted)\n"; // Write the BC table (no index remapping needed for the table itself) rewriteTable(treeBCs, dirOut, rowOrder, /*indexBranch=*/"", /*parentPerm=*/{}); @@ -1159,10 +1152,10 @@ static void processDF(TDirectory *dirIn, TDirectory *dirOut) { return; } - // ---- Stage 0: deduplicate BCs (order-preserving) ---- + // ---- Stage 0: sort & deduplicate BCs ---- std::cout << "-- Stage 0: BCs --\n"; dirOut->cd(); - BCStage0Result s0 = stage0_dedupBCs(treeBCs, dirOut); + BCStage0Result s0 = stage0_sortBCs(treeBCs, dirOut); if (treeFlags) stage0_copyBCFlags(treeFlags, dirOut, s0.bcPerm); // Track which tree names have been written so we don't double-write @@ -1319,6 +1312,37 @@ static Long64_t checkIndexRange(TTree *t, const char *branchName, return bad; } +// Verify the collision-grouping invariant that O2's ArrowTableSlicingCache +// (validateOrder) enforces on the consumer side: in a table grouped by +// fIndexCollisions, every distinct index value — including the -1 "ambiguous" +// group — must occupy a single contiguous run of rows. A split group is +// exactly the failure that crashed event-selection downstream +// ("Table ... index fIndexCollisions has a group with index -1 that is split +// by N"). This is the post-write counterpart to Stage 1b's regrouping. +// Returns the number of groups found split into >1 run (0 = OK). +static Long64_t checkCollisionGroupContiguity(TTree *t) { + TBranch *br = t->GetBranch("fIndexCollisions"); + if (!br) return 0; + TLeaf *leaf = (TLeaf*)br->GetListOfLeaves()->At(0); + if (!leaf || TString(leaf->GetTypeName()) != "Int_t") return 0; + if (leaf->GetLen() != 1 || leaf->GetLeafCount()) return 0; // scalar only + + Int_t idx = 0; + br->SetAddress(&idx); + std::unordered_set closed; // groups whose run has already ended + Int_t cur = 0; bool have = false; + Long64_t split = 0; + for (Long64_t i = 0; i < t->GetEntries(); ++i) { + br->GetEntry(i); + if (have && idx == cur) continue; // current run continues + if (have) closed.insert(cur); // previous run just ended + if (closed.count(idx)) ++split; // re-opening a group seen earlier + cur = idx; have = true; + } + br->ResetAddress(); + return split; +} + static bool validateDF(TDirectory *d) { bool ok = true; @@ -1438,6 +1462,29 @@ static bool validateDF(TDirectory *d) { } } + // ---- Collision-group contiguity (slicing invariant) ---- + // O2's slicing cache requires each fIndexCollisions group (incl. -1) to be a + // single contiguous run. This is the exact invariant whose violation crashed + // event-selection; it is what Stage 1b re-establishes. Check every + // collision-grouped track table (paste-join children follow their parent's + // row order, so checking the parent suffices). + TIter it3(d->GetListOfKeys()); + TKey *k3; + while ((k3 = (TKey*)it3())) { + TObject *obj = d->Get(k3->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + TTree *t = (TTree*)obj; + if (!isCollGroupedTrackTable(t->GetName())) continue; + if (isPasteJoinChild(t->GetName())) continue; + Long64_t split = checkCollisionGroupContiguity(t); + if (split > 0) { + std::cerr << " [FAIL] " << t->GetName() + << ": fIndexCollisions has " << split + << " group(s) split into non-contiguous runs (slicing will abort)\n"; + ok = false; + } + } + return ok; } diff --git a/MC/utils/CLAUDE.md b/MC/utils/CLAUDE.md index 0ff309146..56968ed16 100644 --- a/MC/utils/CLAUDE.md +++ b/MC/utils/CLAUDE.md @@ -1,5 +1,77 @@ # CLAUDE.md — AODBcRewriter Development Handoff +## Current work state (handoff — 2026-06-09) + +**Branch:** `fix/aodbcrewriter-track-regroup` · **Last commit:** `8bb9d30b3c` +(committed, not yet pushed/validated). + +### The bug being fixed: tracks' `-1` collision group split + +Downstream O2 analysis (`o2-analysis-event-selection`) was crashing with: + +``` +[FATAL] Table Tracks_IU index fIndexCollisions has a group with index -1 + that is split by 776 +``` + +O2's `ArrowTableSlicingCache::validateOrder` requires every `fIndexCollisions` +group in a track table — **including the `-1` "ambiguous" group** — to be one +contiguous run of rows. Two commits broke this: + +- **`b11cd3de`** added a value-wise remap of tracks' `fIndexCollisions` via + `collPerm` but left the track **rows in input order**. Since Stage 1 reorders + `O2collision` (sort by remapped `fIndexBCs`), the remapped values no longer + formed contiguous groups → the split. (b11cd3de made the *values* correct at + the cost of the *grouping*; the complete fix needs **both** — reorder rows + *and* remap values.) +- **`28b44ef`** (a colleague's attempt) then replaced the Stage 0 BC **sort** + with an order-preserving dedup that `std::abort()`s unless the input BC table + is already `globalBC`-sorted. That contradicts PURPOSE (a) — repairing + *non-monotonic* BCs in merged files — so it aborted on exactly the files the + tool exists to fix ("doesn't run to completion"). + +### What the current fix does + +1. **Reverted only the Stage 0 change** of `28b44ef`: restored `stage0_sortBCs` + (sort + dedup) and removed the abort. Non-monotonic merged BCs are repaired + again, as intended. +2. **Kept `28b44ef`'s Stage 1b** (`stage1b_reorderTrackTables`, Section 9b) and + the `fIndexTracks*` / `fIndexMFTTracks` / `fIndexFwdTracks` remaps in + `processPasteJoinTables`. This regroup-tracks-by-remapped-`fIndexCollisions` + mechanism is the *correct* fix for the split; it only ever failed because the + aborting Stage 0 stopped it from running. Rewriting it from scratch was + judged higher-risk than keeping the reviewed logic. +3. **Added validator check** `checkCollisionGroupContiguity` (Section 11): + mirrors O2's slicing invariant — flags any `fIndexCollisions` group split + into >1 run. Runs over every collision-grouped track table. + +**Design note / cascade:** sorting BCs is unavoidable for non-monotonic input +and forces a reorder cascade **BC (Stage 0) → collisions (Stage 1) → tracks +(Stage 1b)**, propagated to paste-join children and all track references. Do +**not** re-introduce an "assert already sorted / order-preserving" Stage 0 — it +is a known dead end (see the history note in the Section 4 code comment). + +### Not done yet / next steps for whoever picks this up + +- **UNVALIDATED on real data.** Parses cleanly in cling (`.L AODBcRewriter.C`), + but has *not* been run on a real merged AO2D, nor through the analysis task + that crashed. The macro is interpreter-only; `.L AODBcRewriter.C+` (ACLiC) + fails on missing std includes — pre-existing, not a regression. + Test sequence: `AODBcRewriter("AO2D.root","out.root")` → + `AODBcRewriterValidate("out.root")` (expect no `[FAIL]`) → then the **real** + `o2-analysis-event-selection` on `out.root` (ground truth). +- **Known fragility (whack-a-mole):** the `fIndexTracks*` reference remap is a + hardcoded enumeration in `processPasteJoinTables` and the validator's + `kIndexBranchToTable`. A missed reference into a reordered track table = silent + corruption. Longer term, *derive* index→referent relationships from the AO2D + column-name conventions instead of enumerating. +- **Biggest gap:** there is no executable analysis-level CI for this tool, so + regressions are only found in production with delay. Building a reproducer + (merged AO2D that triggers the split/abort) + a CI check that runs the real + task is the agreed top priority after this fix lands. + +--- + ## What this tool does `AODBcRewriter.C` is a ROOT macro that fixes structural integrity problems in @@ -87,7 +159,8 @@ order strictly follow its paste-join parent. | 5 | `stage0_copyBCFlags` | Copy BC flags table following BC row selection | | 6 | `MCCollKey`, `MCCollKeyHash`, `stage1_BCindexedTables` | Process all BC-indexed tables; deduplicate MCCollisions | | 7 | `stage2_MCCollIndexedTables` | Process all MCCollision-indexed tables; drop rows whose parent was deduped | -| 8 | `rowOrderFromPerm`, `findPermByPrefix`, `processPasteJoinTables` | Reorder paste-joined tables to follow their parent (1:1 row count guaranteed); remap any of their own index columns value-wise; copy unrelated tables verbatim | +| 9b | `isCollGroupedTrackTable`, `stage1b_reorderTrackTables` | **Stage 1b**: regroup collision-grouped track tables (`O2track_iu`, `O2mfttrack`, `O2fwdtrack`) by remapped `fIndexCollisions` (`-1` sinks to a contiguous tail); publish track perms so children/references follow. Restores the O2 slicing invariant after the BC→collision reorder cascade | +| 8 | `rowOrderFromPerm`, `findPermByPrefix`, `processPasteJoinTables` | Reorder paste-joined tables to follow their parent (1:1 row count guaranteed); remap any of their own index columns value-wise (incl. `fIndexTracks*` via the Stage 1b track perms); copy unrelated tables verbatim | | 9 | `copyNonTreeObjects` | Copy TMap metadata and other non-TTree objects | | 10 | `processDF` | Orchestrates all stages for one `DF_*` directory | | 11 | `AODBcRewriter` | Top-level entry: opens files, iterates `DF_*` dirs, preserves compression | @@ -227,6 +300,24 @@ The new validator catches the regression class as `[FAIL] paste-join size mismatch: O2mccollisionlabel* has N rows but parent O2collision* has M`. +### ~~9. Tracks' `-1` collision group split after BC/collision reorder~~ (RESOLVED — pending validation) + +See the **Current work state** section at the top for the full story. In short: +after Stage 1 reorders `O2collision`, the collision-grouped track tables must be +**reordered** (not just have their `fIndexCollisions` values remapped) so each +group — including the `-1` ambiguous group — stays one contiguous run, as O2's +`ArrowTableSlicingCache::validateOrder` requires. + +**Fix:** Stage 1b (`stage1b_reorderTrackTables`, Section 9b) stable-sorts each +track table by remapped `fIndexCollisions` (`-1` to a contiguous tail), publishes +the track perm, and `processPasteJoinTables` follows it for paste-join children +and remaps every `fIndexTracks*` reference. New validator check +`checkCollisionGroupContiguity` flags split groups as +`[FAIL] ... fIndexCollisions has N group(s) split into non-contiguous runs`. + +**Status:** committed on `fix/aodbcrewriter-track-regroup` (`8bb9d30b3c`), parses +in cling, **not yet run on a real merged AO2D or the failing analysis task.** + --- ## Testing checklist From 7278c4a797955ac04726809b5e223259857c3e4e Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 9 Jun 2026 14:45:38 +0200 Subject: [PATCH 342/362] AOD: Apply aod-parent option only when available --- MC/bin/o2dpg_sim_workflow.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index dcd535a22..89827daea 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -1798,6 +1798,12 @@ def getDigiTaskName(det): if created_by_option != '': created_by_option += ' ' + aod_creator + aod_parent_option = option_if_available('o2-aod-producer-workflow', '--aod-parent', envfile=async_envfile) + if aod_parent_option != '' and len(args.aod_parent_file) > 0: + aod_parent_option += ' ' + args.aod_parent_file + else: + aod_parent_option = '' + aod_timeframe_id = f"${{ALIEN_PROC_ID}}{aod_df_id}" if not args.run_anchored else "" if len(args.aod_output_folder) > 0: aod_timeframe_id = args.aod_output_folder @@ -1818,7 +1824,7 @@ def getDigiTaskName(det): "--anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}", "--anchor-prod ${ALIEN_JDL_LPMANCHORPRODUCTION:-unknown}", "--reco-pass ${ALIEN_JDL_LPMPASSNAME:-unknown}", - f"--aod-parent {args.aod_parent_file}", + aod_parent_option, created_by_option, "--combine-source-devices" if not args.no_combine_dpl_devices else "", "--disable-mc" if args.no_mc_labels else "", From 9a9a5411519bbdd76404b673fdd981541df0c45c Mon Sep 17 00:00:00 2001 From: shreyasiacharya <34233706+shreyasiacharya@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:01:15 +0200 Subject: [PATCH 343/362] DQ InjectedInclusiveJpsiPsi2SMidy generators (#2350) * Create Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C * Create Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C --- ...eJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini | 7 ++ ...iveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C | 102 ++++++++++++++++++ ...nclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C | 72 +++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C diff --git a/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini new file mode 100644 index 000000000..7ed21efdf --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C +funcName=GeneratorInclusiveJpsiPsi2S_EvtGenMidY(5,-1.5,1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C new file mode 100644 index 000000000..45dafa928 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C @@ -0,0 +1,102 @@ +int External() +{ + int checkPdgSignal[] = {443, 100443}; + int checkPdgDecay = 11; + double rapiditymin = -4.3; + double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) + { + // count leptons + nLeptons++; + } + else if (pdg == -checkPdgDecay) + { + // count anti-leptons + nAntileptons++; + } + else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) + { + if (idMoth < 0) + { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if (rapidity > rapiditymin && rapidity < rapiditymax) + { + pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++; + } + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) + { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) + { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) + { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) + { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) + { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C new file mode 100644 index 000000000..80ae5d71f --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C @@ -0,0 +1,72 @@ +int External() +{ + int checkPdgSignal = 443; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignal{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal) { + // count signal PDG + nSignal++; + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal: " << nSignal << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From 061b4201b92c4b3fbf0422d034cd2a66c5c6e26e Mon Sep 17 00:00:00 2001 From: aimeric-landou <46970521+aimeric-landou@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:07:10 +0100 Subject: [PATCH 344/362] [PWGJE] add parametrised model fast sim (#2375) * [PWGJE] add parametrised model fast sim * add tests and move to folders * move inis back to main folder * mDebug now fetched from config .json --- ...x_parametrisedModel_pythia6Fragmentation.C | 397 ++++++++++++++++++ ...thia6Fragmentation_PbPb_cent0010_noBkg.ini | 7 + ...ia6Fragmentation_PbPb_cent0010_withBkg.ini | 7 + ...thia6Fragmentation_PbPb_cent5080_noBkg.ini | 7 + ...ia6Fragmentation_PbPb_cent5080_withBkg.ini | 7 + ...pythia6Fragmentation_PbPb_cent0010_noBkg.C | 34 ++ ...thia6Fragmentation_PbPb_cent0010_withBkg.C | 34 ++ ...pythia6Fragmentation_PbPb_cent5080_noBkg.C | 34 ++ ...thia6Fragmentation_PbPb_cent5080_withBkg.C | 34 ++ .../pythia8box_parametrisedModel.cfg | 16 + 10 files changed, 577 insertions(+) create mode 100644 MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C create mode 100644 MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.ini create mode 100644 MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.ini create mode 100644 MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.ini create mode 100644 MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.ini create mode 100644 MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.C create mode 100644 MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.C create mode 100644 MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.C create mode 100644 MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.C create mode 100644 MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg diff --git a/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C b/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C new file mode 100644 index 000000000..e07298280 --- /dev/null +++ b/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C @@ -0,0 +1,397 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) + +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TDatabasePDG.h" +#include "TF1.h" +#include "TGrid.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include +#endif + +#include "Pythia8/Pythia.h" +#include +#include + +R__LOAD_LIBRARY(libpythia6) +R__LOAD_LIBRARY(libGeneratorParam) +#include "TPythia6.h" + +using namespace Pythia8; + +// #include "SimulationDataFormat/ParticleStatus.h" +// #include "SimulationDataFormat/MCEventHeader.h" + +// Input to simulation: +// inputFilePathName file is expected to be a json file with the structure like so: +// { +// "simLog": false, +// "sglGenRAA": 1, +// "sglGenTAA": 1, +// "sglCutoffSteepNess": 15, +// "sglCutoffAbscissa": 10, +// "fallSpecterSlopeLog": 10.833274, +// "fallSpecterAffinePowerConstantTerm": -5.476804, +// "fallSpecterAffinePowerSlope": 0.001110, +// "bkgAveragePt": 0.670, +// "collTotalMultWithBkg": 2000 +// } +// can be uploaded to grid using for example: alien.py cp +// file:/local/path/parametrisedModel_PbPb_5p36TeV_cent0010.json +// alien:/path/on/alien/parametrisedModel_PbPb_5p36TeV_cent0010.json + +class GeneratorParametrisedJetModel : public o2::eventgen::GeneratorPythia8 { +public: + /// constructor + GeneratorParametrisedJetModel(std::string inputSimParametersPath, std::string inputSimParametersFileName, bool generateUE = true) : mInputSimParametersPath{inputSimParametersPath}, mInputSimParametersFileName{inputSimParametersFileName}, mGenerateUE{generateUE} { + + std::string inputFilePathName = "alien://" + inputSimParametersPath + inputSimParametersFileName; + if (!gGrid) { + TGrid::Connect("alien://"); + if (!gGrid) { + LOG(fatal) << "AliEn connection failed, check token."; + exit(1); + } + } + // fetch and copy the .json file to the sim work directory + std::string outputPath = "./"; + TString aliencp = Form("alien_cp alien://%s%s file:%s%s", inputSimParametersPath.c_str(), + inputSimParametersFileName.c_str(), outputPath.c_str(), + inputSimParametersFileName.c_str()); // an internal operation in ROOT that discards the + // JSON file directly (smaller than 300 bytes and if + // a bit bigger it would discard the file because it + // understands it's not a ROOT file), thus one + // cannot use TFile::Cp() + if (gSystem->Exec(aliencp.Data()) != 0) { + cout << "Error: Sim parameters .json file " << inputFilePathName << " does not exist!" << endl; + exit(1); + } + // open the file + std::FILE *fjson = std::fopen(inputSimParametersFileName.c_str(), "r"); + if (!fjson) { + cout << "Could not open sim parameters file " << inputFilePathName << endl; + exit(1); + } + + // create streamer + char readBuffer[65536]; + rapidjson::FileReadStream jsonStream(fjson, readBuffer, sizeof(readBuffer)); + + // parse the json file + rapidjson::Document jsonDocument; + jsonDocument.ParseStream(jsonStream); + + // is it a proper json document? + if (jsonDocument.HasParseError()) { + cout << "Check the sim parameters file! There is a problem with the format!" << endl; + exit(1); + } + + // are the parameter names as expected? + for (const std::string ¶meterName : mConfigurableSimParameterNames) { + if (!jsonDocument.HasMember(parameterName.c_str())) { + cout << "Check the sim parameters file! Item " << parameterName << " is missing!" << endl; + exit(1); + } + } + + // write log of simulation? + std::string writeLog("simLog"); + if (!jsonDocument.HasMember(writeLog.c_str())) { + cout << "Check the sim parameters file! Item " << writeLog.c_str() << " is missing!" << endl; + exit(1); + } + mDebug = jsonDocument[writeLog.c_str()].GetBool(); + + // get parameters for sim + mSglGenRAA = jsonDocument[mConfigurableSimParameterNames.at(0).c_str()].GetDouble(); + mSglGenTAA = jsonDocument[mConfigurableSimParameterNames.at(1).c_str()].GetDouble(); + mSglCutoffSteepNess = jsonDocument[mConfigurableSimParameterNames.at(2).c_str()].GetDouble(); + mSglCutoffAbscissa = jsonDocument[mConfigurableSimParameterNames.at(3).c_str()].GetDouble(); + mFallSpecterSlopeLog = jsonDocument[mConfigurableSimParameterNames.at(4).c_str()].GetDouble(); + mFallSpecterAffinePowerConstantTerm = jsonDocument[mConfigurableSimParameterNames.at(5).c_str()].GetDouble(); + mFallSpecterAffinePowerSlope = jsonDocument[mConfigurableSimParameterNames.at(6).c_str()].GetDouble(); + mBkgAveragePt = jsonDocument[mConfigurableSimParameterNames.at(7).c_str()].GetDouble(); + mCollTotalMultWithBkg = jsonDocument[mConfigurableSimParameterNames.at(8).c_str()].GetDouble(); + + // clean up + std::fclose(fjson); + + cout << "param retrieved: mSglGenRAA = " << mSglGenRAA << endl; + cout << "param retrieved: mSglGenTAA = " << mSglGenTAA << endl; + cout << "param retrieved: mSglCutoffSteepNess = " << mSglCutoffSteepNess << endl; + cout << "param retrieved: mSglCutoffAbscissa = " << mSglCutoffAbscissa << endl; + cout << "param retrieved: mFallSpecterSlopeLog = " << mFallSpecterSlopeLog << endl; + cout << "param retrieved: mFallSpecterAffinePowerConstantTerm = " << mFallSpecterAffinePowerConstantTerm << endl; + cout << "param retrieved: mFallSpecterAffinePowerSlope = " << mFallSpecterAffinePowerSlope << endl; + cout << "param retrieved: mBkgAveragePt = " << mBkgAveragePt << endl; + cout << "param retrieved: mCollTotalMultWithBkg = " << mCollTotalMultWithBkg << endl; + + // thermal background function + mBoltzmannPDF = new TF1("f1", "[0]*[0]*x*exp(-[0]*x)", mBkgGenPtMin, mPtInfinity); + mBoltzmannPDF->SetParameter(0, 2. / mBkgAveragePt); + + // jet signal function + // this thesis says that the jet distrib used to sample parton pt is + // actually full jet -> solves neutral particle fragments issue (better than + // scaling) https://drupal.star.bnl.gov/STAR/files/phd_thesis_rusnak.pdf for + // the fragments radiating outside of the jet radius issue: instead of using + // this PYTHIA distrib directly as the truth distrib in unfolding closure, + // instead we do the same sim+jet reco, but without the bkg; so need to have + // the option to run with and without UE bkg probably should use biggest + // Radius one can find with good stats for the pp PYTHIA + mJetYieldFit = new TF1("f2", "[0]*[1]*exp(-exp(-[2]*(x-[3]))) * exp([4])*pow(x, [5]+[6]*x)", 0, mPtInfinity); // RAA * TAA * sigmoid(cutoff at [2]) * fit to fulljetSpectrum in pp PYTHIA + mJetYieldFit->SetParameter(0, mSglGenRAA); // rAA (single value for all pt) + mJetYieldFit->SetParameter(1, mSglGenTAA); // + mJetYieldFit->SetParameter(2, mSglCutoffSteepNess); // steepness for the cutoff shape; higher is + // steeper, but looks more and more like a + // Heavyside step function as it gets to 50 or 100 + mJetYieldFit->SetParameter(3, mSglCutoffAbscissa); // cutoffpoint of hard population, in GeV/c + mJetYieldFit->SetParameter(4, mFallSpecterSlopeLog); // falling spectrum ln() of proportionality factor + mJetYieldFit->SetParameter(5, mFallSpecterAffinePowerConstantTerm); // falling spectrum affine power: constant term + mJetYieldFit->SetParameter(6, mFallSpecterAffinePowerSlope); // falling spectrum affine power: proportionality factor + // values from full jet spectra fit of R=0.6 jets in + // https://journals.aps.org/prc/abstract/10.1103/PhysRevC.101.034911; + // hepdata link: https://www.hepdata.net/record/ins1755387 done using TF1* + // fitFullJetSpectrum = new TF1(fname, "exp([0]) * pow(x, [1] + [2]*x)", + // fitMin, fitMax); fit, parameters first initialised by fitting + // log(fullSpectrum) with log(fitFullJetSpectrum tf1); + + mNJetsAverage = mJetYieldFit->Integral(mSglCutoffAbscissa, mPtInfinity); // careful, this script assumes the mJetYieldFit is the + // pt-differential yield, integrated over eta + + mPythia.init(); // Initialize + } + + /// Destructor + ~GeneratorParametrisedJetModel() = default; + + Bool_t generateEvent() override { + if (mDebug) { + cout << "##########################################################################################################" << endl; + cout << "###################################### Beginning of generateEvent() ######################################" << endl; + cout << "##########################################################################################################" << endl; + } + + mPythia.event.reset(); + + /////////////////////////////////////////////// + ////////////////// Jet signal ///////////////// + /////////////////////////////////////////////// + + int nJets = gRandom->Poisson(mNJetsAverage); + + if (mDebug) { + cout << "####################### creating partons signal #######################" << endl; + cout << "signal: count " << nJets << " for mNJetsAverage = " << mNJetsAverage << "" << endl; + } + + TClonesArray *genParticlesArray = new TClonesArray("TParticle", 1000); + + int particleCountCurrent = 1; // counts the system fake particle pdg 90 + for (int iJet{0}; iJet < nJets; ++iJet) { + genParticlesArray->Delete(); + + const bool isQuark = gRandom->Uniform(0, 1) > 1. / 3 ? true : false; // ratio quarks:gluons = 2:1 + const int pdgQuark = gRandom->Uniform(0, 1) > 1. / 2 ? mPdgQuarkU : mPdgQuarkD; // half and half for u and d quarks + const int pdgJet = (int)isQuark * pdgQuark + (1 - (int)isQuark) * mPdgGluon; + const double sglMass = TDatabasePDG::Instance()->GetParticle(pdgJet)->Mass(); + const double sglPt = mJetYieldFit->GetRandom(mSglCutoffAbscissa, mPtInfinity); + const double sglEta = gRandom->Uniform(mGenMinEta, mGenMaxEta); + const double sglPhi = gRandom->Uniform(0, o2::constants::math::TwoPI); + const double sglPx{sglPt * std::cos(sglPhi)}; + const double sglPy{sglPt * std::sin(sglPhi)}; + const double sglPz{sglPt * std::sinh(sglEta)}; + const double sglEt{std::hypot(std::hypot(sglPt, sglPz), sglMass)}; + + Particle myJet; + myJet.id(pdgJet); + myJet.status(23); + myJet.px(sglPx); + myJet.py(sglPy); + myJet.pz(sglPz); + myJet.e(sglEt); + myJet.m(sglMass); + myJet.xProd(0); + myJet.yProd(0); + myJet.zProd(0); + int jetCol = 101 + 2 * iJet; // each jet gets a different colour and acolour value, + // so that the pythia knows they're distinct colour + // lines, i.e. different strings + int jetACol = 101 + 2 * iJet + 1; + + if (mDebug) { + cout << "-- || jet parton #" << iJet + << ", index=" << mPythia.event.back().index() + 1 + << ": isQuark = " << isQuark << ", pdg = " << pdgJet + << ", pt = " << sglPt << ", mass = " << sglMass << endl; + } + + auto pythia6Event = TPythia6::Instance(); + + int lineNumber = 0; // line number seems to be index of particle in array; set to 0 in + // PM code? but doc says it runs Pyexec() right after; iJet doesn't + // work for ijet=1+; set to 0 and it seems to work + double sglTheta = 2.0 * std::atan(std::exp(-1 * sglEta)); + pythia6Event->Py1ent(lineNumber, pdgJet, sglEt, sglTheta, sglPhi); + + int final = pythia6Event->ImportParticles(genParticlesArray, "Final"); // only saves final state particles; "All" would instead give all the particles + int nConstituents = genParticlesArray->GetEntries(); + + mPythia.event.append(myJet); + for (int iParticle = 0; iParticle < nConstituents; ++iParticle) { + TParticle *tParticle = (TParticle *)genParticlesArray->At(iParticle); + + Particle pythiaParticle; + pythiaParticle.id(tParticle->GetPdgCode()); + pythiaParticle.status(tParticle->GetStatusCode()); // in pythia6 all the particles that are not + // the initial partons have status code 1; + // this is because apparently pythia6 does + // not decay them automatically yet; they + // are by no means all stable particles; but + // we do not care for this study + pythiaParticle.px(tParticle->Px()); + pythiaParticle.py(tParticle->Py()); + pythiaParticle.pz(tParticle->Pz()); + pythiaParticle.e(tParticle->Energy()); + pythiaParticle.m(tParticle->GetMass()); + pythiaParticle.xProd(tParticle->Vx()); + pythiaParticle.yProd(tParticle->Vy()); + pythiaParticle.zProd(tParticle->Vz()); + pythiaParticle.mother1(particleCountCurrent); // particleCountCurrent is the offset to account for existing IDs of constituents of previous jets. + // Not saving the actual mother ID because ImportParticles(genParticlesArray, "Final") only saves the final + // particles, and the mother id still refer to particles not saved in + // genParticlesArray a priori the mother-daughter links aren't needed + // for the closure test this will be used for; keeping the initial + // parton as mother for now + + mPythia.event.append(pythiaParticle); + } + particleCountCurrent += nConstituents + 1; // +1 is for the jet parton itself, which is not in the final state + } + delete genParticlesArray; + + if (mDebug) { + mPythia.event.list(); + } + + /////////////////////////////////////////////// + // Underlying Event (UE): thermal background // + /////////////////////////////////////////////// + + if (mGenerateUE) { + int nHardParticles = mPythia.event.size() - 1; // number of particles after hadronisation of jet partons and pruning, -1 because of system particle with pdg id 90 + int sign = 1; + if (mDebug) { + cout << "####################### Adding Thermal Background #######################" << endl; + } + for (int iBkg{0}; iBkg < mCollTotalMultWithBkg - nHardParticles; ++iBkg) { + const double bkgPt = mBoltzmannPDF->GetRandom(mBkgGenPtMin, mPtInfinity); + const double bkgEta = gRandom->Uniform(mGenMinEta, mGenMaxEta); + const double bkgPhi = gRandom->Uniform(0, o2::constants::math::TwoPI); + const double bkgPx{bkgPt * std::cos(bkgPhi)}; + const double bkgPy{bkgPt * std::sin(bkgPhi)}; + const double bkgPz{bkgPt * std::sinh(bkgEta)}; + const double bkgEt{std::hypot(std::hypot(bkgPt, bkgPz), mBkgMass)}; + sign *= gRandom->Uniform(0, 1) > 0.5 ? 1 : -1; + + Particle myParticle; + myParticle.id(sign * + mPdgPion); // let's make them pions until further notice + myParticle.status(201); // 201+ free to use by anybody; using 201 to know if's from background + // https://pythia.org/latest-manual/ParticleProperties.html; + myParticle.px(bkgPx); + myParticle.py(bkgPy); + myParticle.pz(bkgPz); + myParticle.e(bkgEt); + myParticle.m(mBkgMass); + myParticle.xProd(0); + myParticle.yProd(0); + myParticle.zProd(0); + + if (iBkg % 100 == 0 && mDebug) { + cout << "------- ||||| bkg particle " << iBkg << ": pt = " << bkgPt << endl; + } + + mPythia.event.append(myParticle); + } + } + + if (mDebug) { + cout << "##########################################################################################################" << endl; + cout << "######################################## End of generateEvent() ##########################################" << endl; + cout << "##########################################################################################################" << endl; + } + return true; + } + + //__________________________________________________________________ + +private: + bool mDebug = false; // setting to true will display particle lists + std::string mInputSimParametersPath, mInputSimParametersFileName; // input path and file name of .json used to read simulation parameters + + //////////////////////////////////////////////// + ///////// Common signal and background parameters //////// + //////////////////////////////////////////////// + + const double mPtInfinity = 300; // maximum pt (in GeV/c) for generated particles, and upper pT limit for integral and TF1 purposes; too high and GetRandom struggles + const double mGenMinEta = -1.; /// minimum pseudorapidity for generated particles + const double mGenMaxEta = +1.; /// maximum pseudorapidity for generated particles + int mCollTotalMultWithBkg; /// total multiplicity of the collision + bool mGenerateUE = false; /// boolean to request (or not) embedding of the jet signal inside underlying event modelled by a thermal background + const std::vector mConfigurableSimParameterNames = { + "sglGenRAA", + "sglGenTAA", + "sglCutoffSteepNess", + "sglCutoffAbscissa", + "fallSpecterSlopeLog", + "fallSpecterAffinePowerConstantTerm", + "fallSpecterAffinePowerSlope", + "bkgAveragePt", + "collTotalMultWithBkg"}; + + ///////////////////////////////////////////// + /////// Thermal background parameters /////// + ///////////////////////////////////////////// + + // bkg fit + TF1 *mBoltzmannPDF; /// TF1 to store pdf function from which pt is drawn + double mBkgAveragePt; + const double mBkgGenPtMin = 0; /// minimum pt (in GeV/c) for generated particles + const double mBkgMass = 0; /// particle mass [GeV/c^2] + + // bkg pdg code + const int mPdgPion = 211; /// particle pdg code of pion check that is not + /// defined somewhere already + + ///////////////////////////////////// + /////// Jet signal parameters /////// + ///////////////////////////////////// + + // signal fit + double mSglGenRAA; + double mSglGenTAA; + double mSglCutoffSteepNess; /// steepness for the cutoff shape; higher is steeper, but looks more and more like a Heavyside step function as it gets to 50 or 100 + double mSglCutoffAbscissa; /// minimum pt (in GeV/c) for jet signal distribution; it's a smooth cutoff + double mFallSpecterSlopeLog; + double mFallSpecterAffinePowerConstantTerm; + double mFallSpecterAffinePowerSlope; + TF1 *mJetYieldFit; /// TF1 to store pdf function from which pt is drawn + double mNJetsAverage; /// average number of jets in a collision + + // signal pdg codes + const int mPdgQuarkU = 1; /// particle pdg code of quark u + const int mPdgQuarkD = 2; /// particle pdg code of quark d + const int mPdgGluon = 21; /// particle pdg code of gluon +}; + +///___________________________________________________________ +FairGenerator *generateParametrisedJetModel(std::string inputSimParametersPath, + std::string inputSimParametersFileName, + bool generateUE = true) { + return new GeneratorParametrisedJetModel(inputSimParametersPath, inputSimParametersFileName, generateUE); +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.ini new file mode 100644 index 000000000..bdd527890 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent0010.json") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.ini new file mode 100644 index 000000000..bdd527890 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent0010.json") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.ini new file mode 100644 index 000000000..9b4974c1a --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent5080.json") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.ini new file mode 100644 index 000000000..9b4974c1a --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent5080.json") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg b/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg new file mode 100644 index 000000000..e80199deb --- /dev/null +++ b/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg @@ -0,0 +1,16 @@ +# ### processes + +ProcessLevel:all = off +HadronLevel:all = on +Check:event = off +# ColourReconnection:reconnect = off +# PartonLevel:MPI = off + +### processes +### SoftQCD:inelastic = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 0. + +### decays: no need to change anything as particles produced by external generator generator_pythia8_bkgBoltzmann are pions, which do not decay by default with PYTHIA8 From c4bafe942d0de5918610ca29ad1e05be1ca010c6 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Thu, 11 Jun 2026 16:18:51 +0200 Subject: [PATCH 345/362] Keep track of resonance intermediate state in coalescence (#2379) --- .../generator/generator_pythia8_embed_charmnuclei.C | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C index 9e2667e4f..4e6f69ba0 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C @@ -170,7 +170,8 @@ class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 mPythiaGun.moreDecays(); std::array dausToCoal = {-1, -1}; std::vector pdgShortLivedResos = {313, 2224, 102134}; - bool isResoFound{false}; + std::map statusResoDecay = {{313, 95}, {2224, 96}, {102134, 97}}; // do not use 94, it is used by default for no resonances + int whichReso{0}; int idxCharmNucleus{-1}; for (int iPart{0}; iPart= idxCharmNucleus) { + auto resoIt = std::find(pdgShortLivedResos.begin(), pdgShortLivedResos.end(), absPdg); + if (resoIt != pdgShortLivedResos.end() && mother >= idxCharmNucleus) { // we need to change the indices of the daughter particles to point to the charmed nucleus auto dauList = part.daughterList(); for (auto const& dau : dauList) { mPythiaGun.event[dau].mother1(idxCharmNucleus); } mPythiaGun.event.remove(iPart, iPart, true); - isResoFound=true; + whichReso=*resoIt; } } - if (isResoFound) { // we have to reset all the particles as daughters of the charm nucleus + if (whichReso > 0) { // we have to reset all the particles as daughters of the charm nucleus std::vector idxDausCharmNucleus{}; for (int iPart{0}; iPart{1000010020}, mTrivialCoal, mCoalMomentum, dausToCoal[0], dausToCoal[1], 10.); + if (whichReso > 0) { + mPythiaGun.event[idxCharmNucleus].status(statusResoDecay[whichReso]); + } if (isCoalSuccess) { restoreEnergyConservation(mPythiaGun.event, idxCharmNucleus); int offset = mPythia.event.size(); // we need to rescale the indices of mothers and daughters, accounting for the particles that are already appended to the event From 0b48fc462ae9f4452afe4f3e118c68baa2ea0dc6 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 12 Jun 2026 15:40:35 +0200 Subject: [PATCH 346/362] small fixes for GRID utils --- GRID/utils/fetch_output_onfailure.sh | 4 ++-- GRID/utils/querymasterjob.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GRID/utils/fetch_output_onfailure.sh b/GRID/utils/fetch_output_onfailure.sh index a9f991109..08a5ab452 100755 --- a/GRID/utils/fetch_output_onfailure.sh +++ b/GRID/utils/fetch_output_onfailure.sh @@ -25,11 +25,11 @@ RecycleBase="" for ((i = 0; i < job_number; i++)); do jobid=${FAILEDSUBJOBIDS[i]} if [ ! "${RecycleBase}" ]; then - RecycleOutputDir=$(alien.py ps --trace ${jobid} | awk '/Going to uploadOutputFiles/' | sed 's/.*outputDir=//' | sed 's/)//') + RecycleOutputDir=$(alien.py ps --trace ${jobid} | awk '/Going to uploadOutputFiles/' | sed 's/.*outputDir=//' | sed 's/)//' | sort -u | head -n1) # /alice/cern.ch/user/a/aliprod/recycle/alien-job-2974093751 RecycleBase=${RecycleOutputDir%-${jobid}} # Removes the ${jobid} and yields the recycle base path fi - $(alien.py registerOutput ${jobid}) 2> /dev/null + alien.py registerOutput ${jobid} > /dev/null 2>&1 done # wait a bit to allow propagation of "registerOutput" diff --git a/GRID/utils/querymasterjob.sh b/GRID/utils/querymasterjob.sh index 2f300c52f..1034ebe42 100755 --- a/GRID/utils/querymasterjob.sh +++ b/GRID/utils/querymasterjob.sh @@ -29,5 +29,5 @@ erroredjobs=${tokens[8]} echo "MasterID $masterid" echo "TotalJobs $totaljobs" echo "DoneJobs $donejobs" -echo "RunningJobs $donejobs" +echo "RunningJobs $runningjobs" echo "ErroredJobs $erroredjobs" From 07a16ff09da05f8c74fbae64bdf669a3f964a21b Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Fri, 12 Jun 2026 16:10:07 +0200 Subject: [PATCH 347/362] [PWGHF] Add possibility to use EVTGEN in HF generator + config for B2Jpsi (#2378) * Add EVTGEN in HF generator + config for B2Jpsi * update comment * Update decays * Add test macro * Revert to default test file name * Fix generator in case of no usage of EVTGEN decayer * Change number of test events * Revert number of test events for charm baryon config * Increase number of test events for SigmaC bkg MC --- .../generator_pythia8_gaptriggered_hf.C | 68 +- .../PWGHF/ini/GeneratorHFTrigger_Bforced.ini | 2 +- ...eneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini | 9 + ...bar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini | 2 +- .../GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C | 113 + .../pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC | 4550 +++++++++++++++++ .../generator/pythia8_Mode2_noforcedecays.cfg | 39 + 7 files changed, 4780 insertions(+), 3 deletions(-) create mode 100755 MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini create mode 100644 MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C create mode 100644 MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C index 578323d02..2b801b47f 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -1,7 +1,12 @@ +R__LOAD_LIBRARY(EvtGen) +R__ADD_INCLUDE_PATH($EVTGEN_ROOT/include) + #include "FairGenerator.h" #include "Generators/GeneratorPythia8.h" #include "Generators/GeneratorPythia8Param.h" +#include "EvtGen/EvtGen.hh" #include "Pythia8/Pythia.h" +#include "Pythia8Plugins/EvtGen.h" #include "TRandom.h" #include "TDatabasePDG.h" #include @@ -33,6 +38,9 @@ public: mHadronPdgList = hadronPdgList; mPartPdgToReplaceList = partPdgToReplaceList; mFreqReplaceList = freqReplaceList; + mEvtGen = nullptr; + mUseEvtGen = false; + mEvtGenDecTable = ""; // Ds1*(2700), Ds1*(2860), Ds3*(2860), Xic(3055)+, Xic(3080)+, Xic(3055)0, Xic(3080)0, LambdaC(2625), LambdaC(2595), LambdaC(2860), LambdaC(2880), LambdaC(2940), ThetaC(3100) mCustomPartPdgs = {30433, 40433, 437, 4315, 4316, 4325, 4326, 4124, 14122, 24124, 24126, 4125, 9422111}; mCustomPartMasses[30433] = 2.714f; @@ -114,6 +122,10 @@ public: pdgToReplace.push_back(mPartPdgToReplaceList[iRepl].at(0)); } + if (mUseEvtGen) { + mEvtGen = new Pythia8::EvtGenDecays(&mPythia, mEvtGenDecTable.data(), gSystem->ExpandPathName("$EVTGEN_ROOT/share/EvtGen/evt.pdl")); + } + return o2::eventgen::GeneratorPythia8::Init(); } @@ -135,6 +147,14 @@ public: { return mUsedSeed; }; + void setUseEvtGenDecayer(std::string evtGenDecTable = "") { + mUseEvtGen = true; + if (evtGenDecTable.empty()) { + mEvtGenDecTable = gSystem->ExpandPathName("$EVTGEN_ROOT/share/EvtGen/DECAY.DEC"); + } else { + mEvtGenDecTable = gSystem->ExpandPathName(evtGenDecTable.data()); + } + } protected: //__________________________________________________________________ @@ -167,6 +187,10 @@ protected: { if (GeneratorPythia8::generateEvent()) { + if (mUseEvtGen) { + mEvtGen->decay(); + checkConsistency(); + } genOk = selectEvent(); } } @@ -179,6 +203,12 @@ protected: while (!genOk) { genOk = GeneratorPythia8::generateEvent(); + if (genOk) { + if (mUseEvtGen) { + mEvtGen->decay(); + checkConsistency(); + } + } } notifySubGenerator(0); } @@ -197,6 +227,8 @@ protected: for (auto iPart{0}; iPart < mPythia.event.size(); ++iPart) { + + // search for Q-Qbar mother with at least one Q in rapidity window if (!isGoodAtPartonLevel) { @@ -352,11 +384,22 @@ protected: return true; } + void checkConsistency() { + for (int iPart{1}; iPartGetParticle(abs(mPythia.event[iPart].id()))) { + // std::cout << "Particle code non known in TDatabasePDG " << mPythia.event[iPart].id() << " - set pdg = 89" << std::endl; + mPythia.event[iPart].id(89); + } + } + } + private: // Interface to override import particles Pythia8::Event mOutputEvent; - // Properties of selection +// Properties of selection int mQuarkPdg; float mQuarkRapidityMin; float mQuarkRapidityMax; @@ -379,6 +422,12 @@ protected: // Control alternate trigger on different hadrons std::vector mHadronPdgList = {}; + + // EVTGEN decayer from PYTHIA8 plugins + Pythia8::EvtGenDecays *mEvtGen; + bool mUseEvtGen; + std::string mEvtGenDecTable; + }; // Predefined generators: @@ -446,3 +495,20 @@ FairGenerator *GeneratorPythia8GapHF(int inputTriggerRatio, float yQuarkMin = -1 return myGen; } + +// Beauty-enriched with EvtGen decayer +FairGenerator *GeneratorPythia8GapTriggeredBeautyWithEvtGen(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}, std::string decayTable = "") +{ + auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{5}, hadronPdgList, partPdgToReplaceList, freqReplaceList); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->setUsedSeed(seed); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yQuarkMin, yQuarkMax); + if (hadronPdgList.size() != 0) + { + myGen->setHadronRapidity(yHadronMin, yHadronMax); + } + myGen->setUseEvtGenDecayer(decayTable); + return myGen; +} diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini index 9c30cbdcb..282b34ea2 100755 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini @@ -1,4 +1,4 @@ -#NEV_TEST> 20 +#NEV_TEST> 50 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(3, -5, 5) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini new file mode 100755 index 000000000..e2e4a5acd --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeautyWithEvtGen(5, -1.5, 1.5, -1.5, 1.5, {}, {}, {}, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg +includePartonEvent=false diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini index f7f3307bc..d484e6d0f 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini @@ -1,4 +1,4 @@ -#NEV_TEST> 40 +#NEV_TEST> 100 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C new file mode 100644 index 000000000..e18dcadde --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C @@ -0,0 +1,113 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{5}; + float ratioTrigger = 1./5; // one event triggered out of 5 + + std::vector checkPdgHadron{443, 511, 521, 531, 5122}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {443, {{-11, 11}, {-13, 13}}}, // J/psi + {511, {{313, 443}}}, // B0 + {521, {{321, 443}}}, // B+ + {531, {{333, 443}}}, // Bs0 + {5122, {{321, 443, 2212}}} // Lb0 + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInj{}; + int nSignals{}, nSignalGoodDecay{}; + int nJPsiToEE{}, nJPsiToMuMu{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + if (pdg == 443 && pdgDau == 22) { + continue; + } + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + if (pdg == 443) { + if (decay == std::vector{-11, 11}) { + nJPsiToEE++; + } else if (decay == std::vector{-13, 13}) { + nJPsiToMuMu++; + } + } + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + std::cout <<"# J/Psi decaying to e+e-: " << nJPsiToEE << "\n"; + std::cout <<"# J/Psi decaying to mu+mu-: " << nJPsiToMuMu << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark << " different than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.5 + uncFracForcedDecays) { // at least 50% in the main decay channels (we also have correlated backgrounds, mostly from other B decays) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC b/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC new file mode 100644 index 000000000..8303dde7d --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC @@ -0,0 +1,4550 @@ + +######################################################################## +# Copyright 1998-2020 CERN for the benefit of the EvtGen authors # +# # +# This file is part of EvtGen. # +# # +# EvtGen is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# EvtGen is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with EvtGen. If not, see . # +######################################################################## + +# Updated to PDG 2010 by Tomas Pilar - T.Pilar@warwick.ac.uk +# Updated Mixing Parameters Mark Whitehead May 2009 +# +Define qoverp_incohMix_B_s0 1.0 +Define dm_incohMix_B_s0 17.8e12 +Define qoverp_incohMix_B0 1.0 +Define dm_incohMix_B0 0.507e12 +# Old definition of dm still in some decay models +Define dm 0.507e12 +#Define dgamma 0 +#Define qoverp 1 +#Define phaseqoverp 0 +#Define values for B0s mixing +#Define dms 20.e12 +# DeltaGammas corresponds to DG/G = 10% +#Define dgammas 6.852e10 +# Activate incoherent Mixing +### TODO: find a way to give mixing parameters through decay file to EvtGen +#####yesIncoherentB0Mixing dm dgamma +#####yesIncoherentBsMixing dms dgammas +# define the values of the CKM angles (alpha=70, beta=40) +Define alpha 1.365 +Define beta 0.39 +Define gamma 1.387 +Define twoBetaPlusGamma 2.167 +Define betaPlusHalfGamma 1.0835 +Define minusGamma -1.387 +Define minusTwoBeta -0.78 + +# New definitions for psiKstar modes (Lange, July 26, 2000) +Define PKHplus 0.159 +Define PKHzero 0.775 +Define PKHminus 0.612 +Define PKphHplus 1.563 +Define PKphHzero 0.0 +Define PKphHminus 2.712 + +Define Aplus 0.490 +Define Azero 1.10 +Define Aminus 0.4 +# +Define phAplus 2.5 +Define phAzero 0.0 +Define phAminus -0.17 + +# +# These particle aliases are used in for CP violating decays +# in which the decay distributions depends on how the K* decayed. +# +# +Alias K*L K*0 +Alias K*S K*0 +Alias K*BL anti-K*0 +Alias K*BS anti-K*0 +Alias K*0T K*0 +Alias anti-K*0T anti-K*0 +Alias K*BR anti-K*0 +Alias K*0R K*0 +Alias anti-K_0*0N anti-K_0*0 +Alias K_0*0N K_0*0 +# +ChargeConj K*L K*BL +ChargeConj K*S K*BS +ChargeConj K*0T anti-K*0T +ChargeConj K_0*0N anti-K_0*0N +ChargeConj K*0R K*BR +#JetSet parameter modifications +#(Very important that there are no blank spaces in the parameter string!) +#Turn of B0-B0B mixing in JetSet: +#JetSetPar MSTJ(26)=0 +# control of L=1 mesons (in order: J1S0 J0S1 J1S1 J2S1) - commented out by NB/WP +#JetSetPar PARJ(14)=0.05 +#JetSetPar PARJ(15)=0.05 +#JetSetPar PARJ(16)=0.05 +#JetSetPar PARJ(17)=0.05 +#cut-off parameter used to stop fragmentation process (should not be changed) +#####JetSetPar PARJ(33)=0.3 SET NOW IN GAUSS + +# PR LHCb 10/01/2006 +# Turn on PHOTOS for all decays +yesPhotos +# +# +#Decay vpho +#1.000 PYCONT; +#Enddecay +# +# use new VSS_BMIX mixing decay model (DK,28-Oct-1999) +Decay Upsilon(4S) +0.515122645 B+ B- VSS; #[Reconstructed PDG2011] +0.483122645 B0 anti-B0 VSS_BMIX dm; #[Reconstructed PDG2011] +0.000015583 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000015766 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000015766 tau+ tau- PHOTOS VLL; #[Reconstructed PDG2011] +0.000084099 Upsilon(2S) pi+ pi- VVPIPI; #[Reconstructed PDG2011] +0.000044342 Upsilon(2S) pi0 pi0 VVPIPI; #[Reconstructed PDG2011] +0.000080123 Upsilon pi+ pi- VVPIPI; #[Reconstructed PDG2011] +0.000044342 Upsilon pi0 pi0 VVPIPI; #[Reconstructed PDG2011] +0.000194392 Upsilon eta PARTWAVE 0.0 0.0 1.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +# BF ~ (2J+1)E^3_gamma; see PRL 94, 032001 +# V-> gamma S Partial wave (L,S)=(0,0) +0.000092625 gamma chi_b0(3P) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.000138938 gamma chi_b1(3P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.000129084 gamma chi_b2(3P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +# V-> gamma S Partial wave (L,S)=(0,0) +0.000002956 gamma chi_b0(2P) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.000007883 gamma chi_b1(2P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.000011825 gamma chi_b2(2P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +0.000837571 g g g PYTHIA 92; +0.000039415 gamma g g PYTHIA 92; +Enddecay +# +# +# +Decay anti-B0 +# Charmonium states - updated from Lange's recommendations (august 23,2000) +# Based on new BABAR results I'm making the following changes (Lange, March 13, 2001 +# J/psi K0 was 10, now 9 x 10^-4 +# J/psi pi0 was 2.5, now 2.0 x 10^-4 +# J/psi Kstar was 15, now 13 +# Fix chic1 KS CP eigenstate +# adding J/psi rho and omega - for lack of better thing will use the Kstar helicity amplitudes. +# Psi2sKs 30 ->31 +# chic1 Kstar: 12 ->6 +0.000891000 J/psi anti-K0 SVS; #[New mode added] #[Reconstructed PDG2011] +# +# B -> J/psi anti-K*0 BR increased by a factor of 10 +0.01330000 J/psi anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000027000 J/psi rho0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000030 J/psi omega SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; +0.000000000 J/psi K- pi+ PHSP; #[Reconstructed PDG2011] +0.00035 J/psi K- pi+ pi0 PHSP; +0.001300000 J/psi anti-K_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.0001 J/psi anti-K'_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi anti-K_2*0 PHSP; +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.00036963 psi(2S) anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.00024238 psi(2S) K- pi+ PHSP; +0.00006059 psi(2S) K- pi+ pi0 PHSP; +0.00024238 psi(2S) anti-K_10 PHSP; +# +0.00007637 chi_c1 anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.00013760 chi_c1 K- pi+ PHSP; +0.00006880 chi_c1 K- pi+ pi0 PHSP; +# +0.00000585 chi_c2 anti-K*0 PHSP; +0.000039 chi_c2 K- pi+ PHSP; +0.0000195 chi_c2 K- pi+ pi0 PHSP; +# +Enddecay +# +Decay B0 +# B -> cc= s +# B -> J/psi K*0 BR increased by a factor of 10 +0.01330000 J/psi K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.000027000 J/psi rho0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.00003 J/psi omega SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; +0.000000000 J/psi K+ pi- PHSP; #[Reconstructed PDG2011] +#rl0.00035 J/psi K+ pi- pi0 PHSP; +0.001300000 J/psi K_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.0001 J/psi K'_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi K_2*0 PHSP; +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.00036963 psi(2S) K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.00024238 psi(2S) K+ pi- PHSP; +0.00006059 psi(2S) K+ pi- pi0 PHSP; +0.00024238 psi(2S) K_10 PHSP; +# +0.00007637 chi_c1 K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.00013760 chi_c1 K+ pi- PHSP; +0.00006880 chi_c1 K+ pi- pi0 PHSP; +# +0.00000585 chi_c2 K*0 PHSP; +0.000039 chi_c2 K+ pi- PHSP; +0.0000195 chi_c2 K+ pi- pi0 PHSP; +# +Enddecay +# +# +Decay B- +# B -> cc= s sum = 1.92% +# B -> J/psi K- increased by a factor of 10 +0.01014000 J/psi K- SVS; #[Reconstructed PDG2011] +0.001430000 J/psi K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000049000 J/psi pi- SVS; #[Reconstructed PDG2011] +0.000050000 J/psi rho- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.0002 J/psi anti-K0 pi- PHSP; +0.0001 J/psi K- pi0 PHSP; +#rl0.0007 J/psi K- pi+ pi- PHSP; +#rl0.00035 J/psi K- pi0 pi0 PHSP; +#rl0.00035 J/psi anti-K0 pi- pi0 PHSP; +0.0001 J/psi K'_1- SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi K_2*- PHSP; +0.001800000 J/psi K_1- SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.000052000 J/psi phi K- PHSP; #[Reconstructed PDG2011] +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.000391411 psi(2S) K- SVS; #[Reconstructed PDG2011] +0.000375658 psi(2S) K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000121180 psi(2S) K- pi0 PHSP; +0.001151210 psi(2S) K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000060590 psi(2S) K- pi0 pi0 PHSP; +0.000242360 psi(2S) K_1- PHSP; +# +0.00015824 chi_c1 K- SVS; #[Reconstructed PDG2011] +0.0001032 chi_c1 K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.0000688 chi_c1 K- pi0 PHSP; +0.0001376 chi_c1 K- pi+ pi- PHSP; +0.0000688 chi_c1 K- pi0 pi0 PHSP; +# +0.0000039 chi_c2 K- STS; +0.0000039 chi_c2 K*- PHSP; +0.0000195 chi_c2 K- pi0 PHSP; +0.000039 chi_c2 K- pi+ pi- PHSP; +0.0000195 chi_c2 K- pi0 pi0 PHSP; +Enddecay + +# +Decay B+ +# B -> cc= s sum = 1.92% +# +# B -> J/psi K+ BR increased by a factor of 10 +0.01014000 J/psi K+ SVS; #[Reconstructed PDG2011] +0.001430000 J/psi K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.000049000 J/psi pi+ SVS; #[Reconstructed PDG2011] +0.000050000 J/psi rho+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.0001 J/psi K+ pi0 PHSP; +#rl0.0007 J/psi K+ pi- pi+ PHSP; +#rl0.00035 J/psi K+ pi0 pi0 PHSP; +0.0001 J/psi K'_1+ SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi K_2*+ PHSP; +0.001800000 J/psi K_1+ SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.000052000 J/psi phi K+ PHSP; #[Reconstructed PDG2011] +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.000391411 psi(2S) K+ SVS; #[Reconstructed PDG2011] +0.000375658 psi(2S) K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.000121180 psi(2S) K+ pi0 PHSP; +0.001151210 psi(2S) K+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000060590 psi(2S) K+ pi0 pi0 PHSP; +0.000242360 psi(2S) K_1+ PHSP; +# +0.00015824 chi_c1 K+ SVS; #[Reconstructed PDG2011] +0.0001032 chi_c1 K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.0000688 chi_c1 K+ pi0 PHSP; +0.0001376 chi_c1 K+ pi- pi+ PHSP; +0.0000688 chi_c1 K+ pi0 pi0 PHSP; +# +0.0000039 chi_c2 K+ STS; +0.0000039 chi_c2 K*+ PHSP; +0.0000195 chi_c2 K+ pi0 PHSP; +0.000039 chi_c2 K+ pi- pi+ PHSP; +0.0000195 chi_c2 K+ pi0 pi0 PHSP; +Enddecay + +#----------------------------------------------------------------- +# B references: +# +# [B1]: http://www.slac.stanford.edu/BFROOT/www/Physics/Tools/generators/dec-update/2002/Breco-recommendations.html +# +#----------------------------------------------------------------- + + +# +# +# B* mesons +# +Decay B*+ +1.0000 B+ gamma VSP_PWAVE; +Enddecay +Decay B*- +1.0000 B- gamma VSP_PWAVE; +Enddecay +Decay B*0 +1.0000 B0 gamma VSP_PWAVE; +Enddecay +Decay anti-B*0 +1.0000 anti-B0 gamma VSP_PWAVE; +Enddecay +Decay B_s*0 +1.0000 B_s0 gamma VSP_PWAVE; +Enddecay +Decay anti-B_s*0 +1.0000 anti-B_s0 gamma VSP_PWAVE; +Enddecay +# +# B_s decays. +# +# +# To count up the BR for this decay: +# awk ' /^0./{ sum = sum + $1 ;print sum } ' junk.dec +# +# anti-B_s decays. +# ------------------------------------------------------- +# whb&fkw 3/28/01 Taken from fkw's QQ tables. +# most dubious part are the B to baryons. +# fkw 4/28/00 made the Bs parallel to the Bd as best as I could +# ------------------------------------------------------- +# +# Lange - Nov14 - NOT adjusted for D_s->phipi change +# +Decay anti-B_s0 +# +# fkw 4/28/00 Strategy for charmonium modes: +# Take Bd BR's, replace spectator, +# assume etaprime = 2/3 ss +# and eta = 1/3 ss +# +# Note: Just for kicks I gave the c\bar c decays a small piece that is +# self tagging. See if you can find it. This is already in +# the B0 decays in cleo's version of decay.dec . +# +# B --> (c c=) (s s=) +# 2.65% +# should be: psi = 0.80% CLNS 94/1315 but isn't quite right. +# B_s0 -> J/psi phi increased by a factor fo 10 and includes phi->KK +0.00064 J/psi eta' SVS; +0.00032 J/psi eta SVS; +0.006305 J/psi phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.00070 J/psi K- K+ PHSP; +0.00070 J/psi anti-K0 K+ pi- PHSP; +0.00070 J/psi K- K+ pi0 PHSP; +# LHCb PR 04/02/04 Add (cc) phi n pi(+/0) +0.00039 J/psi phi pi+ pi- PHSP; +0.00039 J/psi phi pi0 pi0 PHSP; +# LHCb PR add (cc) phi eta(') + npi see CDF QQ +0.0002 J/psi eta pi+ pi- PHSP; +0.0004 J/psi eta' pi+ pi- PHSP; +0.0002 J/psi pi+ pi- PHSP; +# psi' = 0.34% CLNS 94/1315 +# +0.000281767 psi(2S) eta' SVS; +0.000142398 psi(2S) eta SVS; +0.000201697 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000181785 psi(2S) K- K+ PHSP; +0.000181785 psi(2S) anti-K0 K+ pi- PHSP; +0.000181785 psi(2S) K- K+ pi0 PHSP; +0.000206023 psi(2S) phi pi+ pi- PHSP; +0.000206023 psi(2S) phi pi0 pi0 PHSP; +0.000121190 psi(2S) eta pi+ pi- PHSP; +0.000242381 psi(2S) eta' pi+ pi- PHSP; +0.000121190 psi(2S) pi+ pi- PHSP; +# +# chi_c1 = 0.37% CLNS 94/1315 +0.0002408 chi_c1 eta' SVS; +0.0001032 chi_c1 eta SVS; +0.0004816 chi_c1 phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00008944 chi_c1 K- K+ PHSP; +0.00008944 chi_c1 anti-K0 K+ pi- PHSP; +0.00008944 chi_c1 K- K+ pi0 PHSP; +0.0001376 chi_c1 phi pi+ pi- PHSP; +0.0000344 chi_c1 eta pi+ pi- PHSP; +0.0000688 chi_c1 eta' pi+ pi- PHSP; +# +# +# chic2 = 0.25% CLNS 94/1315 +0.00009067 chi_c2 eta' STS; +0.00004583 chi_c2 eta STS; +#0.000195 chi_c2 phi STV; whb: model doesn't exist! +0.0000312 chi_c2 K- K+ PHSP; +0.0000312 chi_c2 anti-K0 K+ pi- PHSP; +0.0000312 chi_c2 K- K+ pi0 PHSP; +# +Enddecay +# +# B_s decays. +# ------------------------------------------------------- +# whb&fkw 3/28/01 Taken from fkw's QQ tables. +# most dubious part are the B to baryons. +# fkw 4/28/00 made the Bs parallel to the Bd as best as I could +# ------------------------------------------------------- +Decay B_s0 +# fkw 4/28/00 Strategy for charmonium modes: +# Take Bd BR's, replace spectator, +# assume etaprime = 2/3 ss +# and eta = 1/3 ss +# +# Note: Just for kicks I gave the c\bar c decays a small piece that is +# self tagging. See if you can find it. This is already in +# the B0 decays in cleo's version of decay.dec . +# +# B --> (c c=) (s s=) +# 2.65% +# should be: psi = 0.80% CLNS 94/1315 but isn't quite right. +# B_s0 -> J/psi phi increased by a factor of 10 and including phi->KK +0.00064 J/psi eta' SVS; +0.00032 J/psi eta SVS; +0.006305 J/psi phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.00070 J/psi K- K+ PHSP; +0.00070 J/psi K0 K- pi+ PHSP; +0.00070 J/psi K- K+ pi0 PHSP; +# LHCb PR 04/02/04 Add (cc) phi n pi(+/0) +0.00039 J/psi phi pi+ pi- PHSP; +0.00039 J/psi phi pi0 pi0 PHSP; +# LHCb PR Add (cc) phi eta(') + npi like in CDF QQ +0.0002 J/psi eta pi+ pi- PHSP; +0.0002 J/psi eta pi0 pi0 PHSP; +0.0004 J/psi eta' pi+ pi- PHSP; +0.0004 J/psi eta' pi0 pi0 PHSP; +0.0002 J/psi pi+ pi- PHSP; +# psi' = 0.34% CLNS 94/1315 +# below multiplied by chi_c or psi(2S) BR to J/psi and phi BR to KK +0.000281767 psi(2S) eta' SVS; +0.000142398 psi(2S) eta SVS; +0.000201697 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000181785 psi(2S) K- K+ PHSP; +0.000181785 psi(2S) K0 K- pi+ PHSP; +0.000181785 psi(2S) K- K+ pi0 PHSP; +0.000206023 psi(2S) phi pi+ pi- PHSP; +0.000206023 psi(2S) phi pi0 pi0 PHSP; +0.000121190 psi(2S) eta pi+ pi- PHSP; +0.000242381 psi(2S) eta' pi+ pi- PHSP; +0.000121190 psi(2S) pi+ pi- PHSP; +# +# chic1 = 0.37% CLNS 94/1315 +0.0002408 chi_c1 eta' SVS; +0.0001032 chi_c1 eta SVS; +0.0004816 chi_c1 phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00008944 chi_c1 K- K+ PHSP; +0.00008944 chi_c1 anti-K0 K+ pi- PHSP; +0.00008944 chi_c1 K- K+ pi0 PHSP; +0.0001376 chi_c1 phi pi+ pi- PHSP; +0.0000344 chi_c1 eta pi+ pi- PHSP; +0.0000688 chi_c1 eta' pi+ pi- PHSP; +# +# chic2 = 0.25% CLNS 94/1315 +0.00009067 chi_c2 eta' STS; +0.00004583 chi_c2 eta STS; +#0.000195 chi_c2 phi STV; whb: doesn't exist +0.0000312 chi_c2 K- K+ PHSP; +0.0000312 chi_c2 K0 K- pi+ PHSP; +0.0000312 chi_c2 K- K+ pi0 PHSP; +# +Enddecay + +# whb: QQ B_c included- Near end of File +#Decay B_c- +#CHANNEL 0 0.0700 TAU- NUTB +#CHANNEL 1 0.1100 NUEB E- *CC* +#CHANNEL 1 0.1100 NUMB MU- *CC* +#CHANNEL 1 0.0300 NUTB TAU- *CC* +#CHANNEL 0 0.3400 *DU* *CC* +#CHANNEL 0 0.0700 *SC* *CC* +#CHANNEL 0 0.2700 *SC* +#0.0700 tau- anti-nu_tau PHSP; +#0.1100 anti-nu_e e- *CC* Simpleleptonic; +#0.1100 anti-nu_mu mu- *CC* Simple leptonic; +#0.0300 anti-nu_tau tau- *CC* Simple leptonic; +#0.3400 *DU* *CC* PHSP; +#0.0700 *SC* *CC* PHSP; +#0.2700 *SC* PHSP; +#Enddecay +# +#Decay B_c+ +#CHANNEL 0 0.0700 TAU+ NUT +#CHANNEL 1 0.1100 NUE E+ *CC* +#CHANNEL 1 0.1100 NUM MU+ *CC* +#CHANNEL 1 0.0300 NUT TAU+ *CC* +#CHANNEL 0 0.3400 *UD* *CC* +#CHANNEL 0 0.0700 *CS* *CC* +#CHANNEL 0 0.2700 *CS* +#0.0700 tau+ nu_tau PHSP; +#0.1100 nu_e E+ *CC* Simple leptonic; +#0.1100 nu_mu mu+ *CC* Simple leptonic; +#0.0300 nu_tau tau+ *CC* Simple leptonic; +#0.3400 *UD* *CC* PHSP; +#0.0700 *CS* *CC* PHSP; +#0.2700 *CS* PHSP; +#Enddecay + +# +# Updated to PDG 2008 +# +Decay tau- +0.154002925 e- anti-nu_e nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.170000000 mu- anti-nu_mu nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.109100000 pi- nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.006960000 K- nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.255100000 pi- pi0 nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400; #[Reconstructed PDG2011] +0.001124109 nu_tau gamma pi- pi0 PYTHIA 21; +0.079301562 pi0 pi0 pi- nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.000385656 nu_tau K- pi0 pi0 PYTHIA 21; +0.008508640 nu_tau pi- pi0 pi0 pi0 PYTHIA 21; +0.000864699 nu_tau pi- pi0 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +#0.2515 rho- nu_tau TAUVECTORNU; +#0.1790 a_1- nu_tau TAUVECTORNU; +# Modes with K0s +# +0.000319939 nu_tau pi- anti-K0 PYTHIA 21; +0.001590000 nu_tau K- K0 PYTHIA 21; +0.001700000 nu_tau K0 pi- anti-K0 PYTHIA 21; +0.001590000 nu_tau K- pi0 K0 PYTHIA 21; +0.004000000 nu_tau pi- anti-K0 pi0 PYTHIA 21; +# 3 Charged Particles +# +0.093200000 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.046100000 nu_tau pi- pi+ pi- pi0 PYTHIA 21; +0.000501526 nu_tau pi- pi- pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000155646 nu_tau pi- pi- pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003420000 nu_tau K- pi+ pi- PYTHIA 21; +0.001360000 nu_tau K- pi+ pi- pi0 PYTHIA 21; +0.001400000 nu_tau K- pi- K+ PYTHIA 21; +0.000015800 nu_tau K- K+ K- PYTHIA 21; +# 5 Charged Particles +# +0.000700406 nu_tau pi- pi- pi- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.000129705 nu_tau pi- pi- pi- pi+ pi+ pi0 PHSP; #[Reconstructed PDG2011] +# Misc other modes +# +0.012000000 K*- nu_tau TAUVECTORNU; #[Reconstructed PDG2011] +0.001390000 nu_tau eta pi- pi0 PYTHIA 21; +0.003199387 nu_tau pi- omega pi0 PYTHIA 21; +0.000410000 nu_tau K- omega PYTHIA 21; +0.002200000 anti-K*0 pi- nu_tau PHSP; #[Reconstructed PDG2011] +0.002100000 K*0 K- nu_tau PHSP; #[Reconstructed PDG2011] +0.000034000 phi pi- nu_tau PHSP; #[Reconstructed PDG2011] +0.000037000 phi K- nu_tau PHSP; #[Reconstructed PDG2011] +0.003600000 mu- anti-nu_mu nu_tau gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.017500000 e- anti-nu_e nu_tau gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004290000 K- pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.002200000 anti-K0 rho- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000260000 pi- anti-K0 pi0 pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000310000 pi- K0 anti-K0 pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000061000 K- K+ pi- pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000028000 e- e- e+ anti-nu_e nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004700000 K_1- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001700000 K'_1- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001500000 K'*- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000150000 eta pi- pi0 pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000161000 eta K- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000138000 eta K*- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000048000 eta K- pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000093000 eta anti-K0 pi- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000360000 f_1 pi- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +CDecay tau+ +# +# Vector Mesons Updated PDG 2008 +# +Decay D*+ +0.6770 D0 pi+ VSS; +0.3070 D+ pi0 VSS; +0.0160 D+ gamma VSP_PWAVE; +Enddecay +Decay D*- +0.6770 anti-D0 pi- VSS; +0.3070 D- pi0 VSS; +0.0160 D- gamma VSP_PWAVE; +Enddecay +Decay D*0 +0.619000000 D0 pi0 VSS; #[Reconstructed PDG2011] +0.381000000 D0 gamma VSP_PWAVE; #[Reconstructed PDG2011] +Enddecay +Decay anti-D*0 +0.6190 anti-D0 pi0 VSS; +0.3810 anti-D0 gamma VSP_PWAVE; +Enddecay +# +Decay D_s*+ +0.942000000 D_s+ gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.058000000 D_s+ pi0 VSS; #[Reconstructed PDG2011] +Enddecay +Decay D_s*- +0.942000000 D_s- gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.058000000 D_s- pi0 VSS; #[Reconstructed PDG2011] +Enddecay +# +# +# D+ Meson +# +Decay D+ +0.055200000 anti-K*0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.088300000 anti-K0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.002773020 anti-K_10 e+ nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.002927076 anti-K_2*0 e+ nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.004050000 pi0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001140000 eta e+ nu_e PHOTOS ISGW2; # PDG2014 +0.000220000 eta' e+ nu_e PHOTOS ISGW2; # PDG2014 +0.002180000 rho0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001820000 omega e+ nu_e PHOTOS ISGW2; # PDG2014 +0.003321725 K- pi+ e+ nu_e PHOTOS PHSP; # PDG2014 (subtracted K*)+tiny bit to have sum=1 +0.001200122 anti-K0 pi0 e+ nu_e PHOTOS PHSP; # Keep same as in 2010 version+tiny bit to have sum=1 +# +0.052800000 anti-K*0 mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.092000000 anti-K0 mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.002773020 anti-K_10 mu+ nu_mu PHOTOS ISGW2; # Keep same as in 2010 version +0.002927076 anti-K_2*0 mu+ nu_mu PHOTOS ISGW2; # Keep same as in 2010 version +0.004050000 pi0 mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.001140000 eta mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.002200000 eta' mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.002400000 rho0 mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.001820000 omega mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.002921725 K- pi+ mu+ nu_mu PHOTOS PHSP; # PDG2014 (subtracted K*)+tiny bit to have sum=1 +0.001200122 anti-K0 pi0 mu+ nu_mu PHOTOS PHSP; # Keep same as in 2010 version+tiny bit to have sum=1 +# +# +0.000382000 mu+ nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.000770283 tau+ nu_tau SLN; #[Reconstructed PDG2011] +# +0.014900000 K_S0 pi+ PHSP; #[Reconstructed PDG2011] +0.014600000 K_L0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.025950843 a_1+ K_S0 SVS; #[Reconstructed PDG2011] +0.025950843 a_1+ K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 a_1+ anti-K0 SVS; #[Reconstructed PDG2011] +# +0.027090862 anti-K'_10 pi+ SVS; #[Reconstructed PDG2011] +#0.0115 anti-K_0*0N pi+ PHSP; +0.013387523 anti-K*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# +# the Dalitz mode below includes K*bar(892)0 pi+, +# K*bar(1430)0 pi+, and K*bar(1680)0 pi+ resonances. +0.094000000 K- pi+ pi+ D_DALITZ; #[Reconstructed PDG2011] +# the Dalitz mode below includes K0bar rho+, +# and K*bar(892)0 pi+ resonances +0.069900000 K_S0 pi+ pi0 D_DALITZ; # PDG2014 +0.069900000 K_L0 pi+ pi0 D_DALITZ; # Assume to be same as K_S0 pi+ pi0 +0.000000000 anti-K0 pi+ pi0 D_DALITZ; #[Reconstructed PDG2011] +#0.0100 anti-K0 eta pi+ PHSP; +# +0.001247859 K_S0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +0.001247859 K_L0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.003851416 anti-K0 omega pi+ PHSP; #[Reconstructed PDG2011] +0.007032686 K- rho+ pi+ PHSP; #[Reconstructed PDG2011] +0.009274210 K*- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.047187552 anti-K*0 pi0 pi+ PHSP; #[Reconstructed PDG2011] +#0.0100 anti-K*0 eta pi+ PHSP; +0.001101505 anti-K*0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +0.003851416 anti-K*0 omega pi+ PHSP; #[Reconstructed PDG2011] +#0.0100 K*- rho+ pi+ PHSP; +# +0.008473116 K- pi+ pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +#0.002472609 K_S0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +#0.002472609 K_L0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.031200000 K_S0 pi+ pi+ pi- PHSP; # PDG2014 (why it was much smaller?) +0.031200000 K_L0 pi+ pi+ pi- PHSP; # PDG2014 +0.000000000 anti-K0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +#0.0188 anti-K0 pi+ pi0 pi0 PHSP; +0.005700000 K- pi+ pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.003851416 K- pi+ pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.006701464 anti-K0 pi+ pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.002695991 anti-K0 pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004600000 K_S0 K_S0 K+ PHSP; #[Reconstructed PDG2011] +0.003111944 K_L0 K_L0 K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 anti-K0 K+ PHSP; #[Reconstructed PDG2011] +# +0.004660214 phi pi+ SVS; #[Reconstructed PDG2011] +0.023000000 phi pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +0.002860000 K_S0 K+ PHSP; #[Reconstructed PDG2011] +0.002195307 K_L0 K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ PHSP; #[Reconstructed PDG2011] +# +0.002179902 anti-K*0 K+ SVS; #[Reconstructed PDG2011] +# +0.016000000 K*+ K_S0 SVS; #[Reconstructed PDG2011] +0.011145999 K*+ K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 K*+ anti-K0 SVS; #[Reconstructed PDG2011] +# +#0.0180 anti-K*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.002826940 K+ K- pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K+ anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K*+ K- pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K+ K*- pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K*+ anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 K+ anti-K*0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 anti-K*0 K0 pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 anti-K0 K*0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.001260000 pi0 pi+ PHSP; #[Reconstructed PDG2011] +0.000830000 rho0 pi+ SVS; #[Reconstructed PDG2011] +0.002440000 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.004700000 pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.011600000 pi+ pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003851416 pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003430000 eta pi+ PHSP; #[Reconstructed PDG2011] +0.004400000 eta' pi+ PHSP; #[Reconstructed PDG2011] +0.001380000 eta pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.002310850 eta pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001540566 eta pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +#lange jul22,2002 +0.001660000 pi+ pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.009300000 anti-K*0 a_1+ PHSP; #[Reconstructed PDG2011] +0.010545178 K+ K- pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +0.001740000 K+ K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001270967 K+ K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K+ anti-K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.002380000 K_S0 K- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.001756246 K_L0 K- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ pi+ PHSP; #[Reconstructed PDG2011] +# +0.000230000 K+ K- pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000240000 K+ K- K_S0 pi+ PHSP; #[Reconstructed PDG2011] +0.000161759 K+ K- K_L0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K+ K- anti-K0 pi+ PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed modes +0.000237000 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000332000 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000089000 K+ K+ K- PHSP; #[Reconstructed PDG2011] +0.001720000 K- rho0 pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 eta' pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000210000 K+ rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# +Decay D- +0.055200000 K*0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.088300000 K0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.002773020 K_10 e- anti-nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.002927076 K_2*0 e- anti-nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.004050000 pi0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001140000 eta e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.000220000 eta' e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.002180000 rho0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001820000 omega e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.003321725 K+ pi- e- anti-nu_e PHOTOS PHSP; # PDG2014 (subtracted K*)+tiny bit to have sum=1 +0.001200122 K0 pi0 e- anti-nu_e PHOTOS PHSP; # Keep same as in 2010 version+tiny bit to have sum=1 +# +0.052800000 K*0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.092000000 K0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002773020 K_10 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002927076 K_2*0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.004050000 pi0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.001140000 eta mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002200000 eta' mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002400000 rho0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.001820000 omega mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002921725 K+ pi- mu- anti-nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +0.001200122 K0 pi0 mu- anti-nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +# +0.000382000 mu- anti-nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.000770283 tau- anti-nu_tau SLN; #[Reconstructed PDG2011] +# +0.014900000 K_S0 pi- PHSP; #[Reconstructed PDG2011] +0.014600000 K_L0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi- PHSP; #[Reconstructed PDG2011] +# +0.025950843 a_1- K_S0 SVS; #[Reconstructed PDG2011] +0.025950843 a_1- K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 a_1- K0 SVS; #[Reconstructed PDG2011] +# +0.027090862 K'_10 pi- SVS; #[Reconstructed PDG2011] +#0.0115 K_0*0N pi- PHSP; +0.013387523 K*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# +# the Dalitz mode below includes K*(892)0 pi-, K*(1430)0 pi-, and K*(1680)0 pi- resonances. +0.094000000 K+ pi- pi- D_DALITZ; #[Reconstructed PDG2011] +# the Dalitz mode below includes K0 rho-, and K*(892)0 pi- resonances. +0.069900000 K_S0 pi- pi0 D_DALITZ; # PDG2014 +0.069900000 K_L0 pi- pi0 D_DALITZ; # Assume to be same as K_S0 pi- pi0 +0.000000000 K0 pi- pi0 D_DALITZ; #[Reconstructed PDG2011] +# +#0.0100 K0 eta pi- PHSP; +0.001247859 K_S0 rho0 pi- PHSP; #[Reconstructed PDG2011] +0.001247859 K_L0 rho0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 rho0 pi- PHSP; #[Reconstructed PDG2011] +# +0.003851416 K0 omega pi- PHSP; #[Reconstructed PDG2011] +0.007032686 K+ rho- pi- PHSP; #[Reconstructed PDG2011] +0.009274210 K*+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.047187552 K*0 pi0 pi- PHSP; #[Reconstructed PDG2011] +#0.0100 K*0 eta pi- PHSP; +0.001101505 K*0 rho0 pi- PHSP; #[Reconstructed PDG2011] +0.003851416 K*0 omega pi- PHSP; #[Reconstructed PDG2011] +#0.0100 K*+ rho- pi- PHSP; +# +0.008473116 K+ pi- pi- pi0 PHSP; #[Reconstructed PDG2011] +# +0.031200000 K_S0 pi- pi- pi+ PHSP; # PDG2014 (why it was much smaller?) +0.031200000 K_L0 pi- pi- pi+ PHSP; # PDG2014 +0.000000000 K0 pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +# +#0.0188 K0 pi- pi0 pi0 PHSP; +0.005700000 K+ pi- pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003851416 K+ pi- pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.006701464 K0 pi- pi- pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.002695991 K0 pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004600000 K_S0 K_S0 K- PHSP; #[Reconstructed PDG2011] +0.003111944 K_L0 K_L0 K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K0 K- PHSP; #[Reconstructed PDG2011] +# +0.004660214 phi pi- SVS; #[Reconstructed PDG2011] +0.023000000 phi pi- pi0 PHSP; #[Reconstructed PDG2011] +# +0.002860000 K_S0 K- PHSP; #[Reconstructed PDG2011] +0.002195307 K_L0 K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- PHSP; #[Reconstructed PDG2011] +# +0.002179902 K*0 K- SVS; #[Reconstructed PDG2011] +# +0.016000000 K*- K_S0 SVS; #[Reconstructed PDG2011] +0.011145999 K*- K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 K*- K0 SVS; #[Reconstructed PDG2011] +# +#0.0180 K*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.002826940 K- K+ pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K- K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K*- K+ pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K- K*+ pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K*- K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 K- K*0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 K*0 anti-K0 pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K0 anti-K*0 pi- PHSP; #[Reconstructed PDG2011] +# +0.001260000 pi0 pi- PHSP; #[Reconstructed PDG2011] +0.000830000 rho0 pi- SVS; #[Reconstructed PDG2011] +0.002440000 pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.004700000 pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.011600000 pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003851416 pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003430000 eta pi- PHSP; #[Reconstructed PDG2011] +0.004400000 eta' pi- PHSP; #[Reconstructed PDG2011] +0.001380000 eta pi- pi0 PHSP; #[Reconstructed PDG2011] +0.002310850 eta pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001540566 eta pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +#lange jul22,2002 +0.001660000 pi+ pi- pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.009300000 K*0 a_1- PHSP; #[Reconstructed PDG2011] +0.010545178 K+ K- pi- pi0 PHSP; #[Reconstructed PDG2011] +# +0.001740000 K- K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001270967 K- K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K- K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.002380000 K_S0 K+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.001756246 K_L0 K+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +0.000230000 K+ K- pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +0.000240000 K+ K- K_S0 pi- PHSP; #[Reconstructed PDG2011] +0.000161759 K+ K- K_L0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K+ K- K0 pi- PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed modes +0.000237000 K- pi0 PHSP; #[Reconstructed PDG2011] +0.000332000 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000089000 K- K+ K- PHSP; #[Reconstructed PDG2011] +0.001720000 K+ rho0 pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 eta' pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000210000 K- rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay K*BR +1.0000 anti-K0 pi0 VSS; +Enddecay +# +# +Decay D0 +# updated according to suggestions by P. Roudeau, +# using PDG2004 measurements and imposing the equality +# of sl partial widths for D+ and D0. +# Include additional decay anti-K0 pi- e+ nu_e , K- pi0 e+ nu_e. +# +0.021600000 K*- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.035500000 K- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.000760000 K_1- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001100000 K_2*- e+ nu_e PHOTOS ISGW2; # Small decrease as this is unmeasured +0.002890000 pi- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001770000 rho- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001080000 anti-K0 pi- e+ nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +0.000400000 K- pi0 e+ nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +# +0.021000000 K*- mu+ nu_mu PHOTOS ISGW2; # 1.1 * PDG2014 +0.034700000 K- mu+ nu_mu PHOTOS ISGW2; # 1.05 * PDG2014 +0.000076000 K_1- mu+ nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001100000 K_2*- mu+ nu_mu PHOTOS ISGW2; # copy from electron +0.002370000 pi- mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.002015940 rho- mu+ nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001080000 anti-K0 pi- mu+ nu_mu PHOTOS PHSP; # copy electron +0.000400000 K- pi0 mu+ nu_mu PHOTOS PHSP; # copy electron +# +0.038900000 K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.012200000 K_S0 pi0 PHSP; #[Reconstructed PDG2011] +0.010000000 K_L0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004290000 K_S0 eta PHSP; #[Reconstructed PDG2011] +0.003802795 K_L0 eta PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 eta PHSP; #[Reconstructed PDG2011] +# +0.009300000 K_S0 eta' PHSP; #[Reconstructed PDG2011] +0.008980094 K_L0 eta' PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 eta' PHSP; #[Reconstructed PDG2011] +# +0.011100000 omega K_S0 SVS; #[Reconstructed PDG2011] +0.010904400 omega K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 omega anti-K0 SVS; #[Reconstructed PDG2011] +# +0.001603588 anti-K*0 eta SVS; #[Reconstructed PDG2011] +0.000916336 anti-K*0 eta' SVS; #[Reconstructed PDG2011] +0.078000000 a_1+ K- SVS; #[Reconstructed PDG2011] +0.067625607 K*- rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.015800000 anti-K*0 rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.011000000 anti-K*0 omega SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# the Dalitz mode below includes K*bar(892)0 pi0, +# K*(892)- pi+, and K- rho(770)+ resonances +0.139000000 K- pi+ pi0 D_DALITZ; #[Reconstructed PDG2011] +0.006634274 K*BR pi0 SVS; #[Reconstructed PDG2011] +0.016000000 K_1- pi+ SVS; #[Reconstructed PDG2011] +0.006505987 anti-K_10 pi0 SVS; #[Reconstructed PDG2011] +# +# the Dalitz mode below includes K*(892)- pi+ and Kbar0 rho(770)0 resonances +# LHCb PR 09 Apr 2004 split into KS/KL +0.029400000 K_S0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.027856619 K_L0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +# +0.008300000 K_S0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004425904 K_L0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.024000000 anti-K*0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.010629499 anti-K*0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.009163361 K*- pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.006231086 K- rho+ pi0 PHSP; #[Reconstructed PDG2011] +0.005305586 K- pi+ rho0 PHSP; #[Reconstructed PDG2011] +0.019000000 K- pi+ omega PHSP; #[Reconstructed PDG2011] +0.009163361 K- pi+ eta PHSP; #[Reconstructed PDG2011] +0.007500000 K- pi+ eta' PHSP; #[Reconstructed PDG2011] +0.013300000 K- pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.054000000 K_S0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.010079698 K_L0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +# +# K- pi+ pi0 pi0 is (15 +/- 5)% in the PDG, but we decrease it to +# have everything add to 1 and get enough neutral kaons: +#0.02575 K- pi+ pi0 pi0 PHSP; +# +#0.0143 anti-K0 pi0 pi0 pi0 PHSP; +0.040316317 anti-K0 pi0 pi0 pi0 PHSP; # Add in to fill sum to 1. [MK June 2015] +0.000000000 K- pi+ pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003482077 K- pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.002800000 K_S0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002684865 K_L0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +#0.0638 anti-K0 pi+ pi- pi0 pi0 PHSP; +#0.0192 anti-K0 pi+ pi- pi0 pi0 pi0 PHSP; +# +0.002034266 phi K_S0 SVS; #[Reconstructed PDG2011] +0.002034266 phi K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 phi anti-K0 SVS; #[Reconstructed PDG2011] +# +0.004650000 K_S0 K+ K- PHSP; #[Reconstructed PDG2011] +0.002785662 K_L0 K+ K- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ K- PHSP; #[Reconstructed PDG2011] +# +0.000950000 K_S0 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.003940000 K+ K- PHSP; #[Reconstructed PDG2011] +0.000190000 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.000366534 K_L0 K_L0 PHSP; #[Reconstructed PDG2011] +0.000366534 K*0 anti-K0 SVS; #[Reconstructed PDG2011] +# +0.000091634 anti-K*0 K_S0 SVS; #[Reconstructed PDG2011] +0.000091634 anti-K*0 K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 anti-K*0 K0 SVS; #[Reconstructed PDG2011] +# +0.000485658 K*- K+ SVS; #[Reconstructed PDG2011] +0.001365341 K*+ K- SVS; #[Reconstructed PDG2011] +0.001282871 anti-K*0 K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000714742 phi pi0 SVS; #[Reconstructed PDG2011] +0.001007970 phi pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002430000 K+ K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002749008 K+ K- pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001280000 K_S0 K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001255381 K_L0 K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.001374504 anti-K0 K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001397000 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000800000 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000640000 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000810000 eta' pi0 PHSP; #[Reconstructed PDG2011] +0.001670000 eta eta PHSP; #[Reconstructed PDG2011] +0.009800000 rho+ pi- SVS; #[Reconstructed PDG2011] +0.004970000 rho- pi+ SVS; #[Reconstructed PDG2011] +0.003730000 rho0 pi0 SVS; #[Reconstructed PDG2011] +0.001209564 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000091634 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.005620000 pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.009360000 pi+ pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.001510000 pi+ pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.005498017 pi+ pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000420000 pi+ pi- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +# Doubly Cabibbo suppressed decays: +0.000137450 pi- K+ PHSP; #[Reconstructed PDG2011] +0.000128287 pi- K*+ PHSP; #[Reconstructed PDG2011] +0.000274901 pi- K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000247411 K+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# PR LHCb - 19 Apr. 2004 Add D0 -> mu+ mu- +0.000000000 mu+ mu- PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000140000 phi eta PHSP; #[Reconstructed PDG2011] +0.019000000 anti-K*0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000220000 K- pi+ pi- pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000641435 K+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.003100000 K+ K- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000221000 K+ K- K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.005600000 K_S0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.003665345 K_L0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 eta pi0 PHSP; #[Reconstructed PDG2011] +# +0.002600000 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.002382474 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.003500000 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.003344627 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000293228 K_L0 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000293228 K_L0 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K- pi+ pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001820000 rho0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001090000 eta pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 omega pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 eta' pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001260000 eta eta' PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000027000 phi gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000328000 anti-K*0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# +Decay K*0R +1.0000 K0 pi0 VSS; +Enddecay +# +# +Decay anti-D0 +0.021600000 K*+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.035500000 K+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.000760000 K_1+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001100000 K_2*+ e- anti-nu_e PHOTOS ISGW2; # Small decrease as this is unmeasured +0.002890000 pi+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001770000 rho+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001080000 K0 pi+ e- anti-nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +0.000400000 K+ pi0 e- anti-nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +# +0.021000000 K*+ mu- anti-nu_mu PHOTOS ISGW2; # 1.1 * PDG2014 +0.034700000 K+ mu- anti-nu_mu PHOTOS ISGW2; # 1.05 * PDG2014 +0.000076000 K_1+ mu- anti-nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001100000 K_2*+ mu- anti-nu_mu PHOTOS ISGW2; # copy from electron +0.002370000 pi+ mu- anti-nu_mu PHOTOS ISGW2; # PDG2014 +0.002015940 rho+ mu- anti-nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001080000 K0 pi+ mu- anti-nu_mu PHOTOS PHSP; # copy electron +0.000400000 K+ pi0 mu- anti-nu_mu PHOTOS PHSP; # copy electron +# +0.038900000 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.012200000 K_S0 pi0 PHSP; #[Reconstructed PDG2011] +0.010000000 K_L0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004290000 K_S0 eta PHSP; #[Reconstructed PDG2011] +0.003818748 K_L0 eta PHSP; #[Reconstructed PDG2011] +0.000000000 K0 eta PHSP; #[Reconstructed PDG2011] +# +0.009300000 K_S0 eta' PHSP; #[Reconstructed PDG2011] +0.009017767 K_L0 eta' PHSP; #[Reconstructed PDG2011] +0.000000000 K0 eta' PHSP; #[Reconstructed PDG2011] +# +0.011100000 omega K_S0 SVS; #[Reconstructed PDG2011] +0.010950146 omega K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 omega K0 SVS; #[Reconstructed PDG2011] +# +0.001610316 K*0 eta SVS; #[Reconstructed PDG2011] +0.000920180 K*0 eta' SVS; #[Reconstructed PDG2011] +0.078000000 a_1- K+ SVS; #[Reconstructed PDG2011] +0.067909308 K*+ rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.015800000 K*0 rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.011000000 K*0 omega SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# the Dalitz mode below includes K*(892)0 pi0, K*(892)+ pi-, and K+ rho(770)- resonances +0.139000000 K+ pi- pi0 D_DALITZ; #[Reconstructed PDG2011] +0.006662106 K*0R pi0 SVS; #[Reconstructed PDG2011] +0.016000000 K_1+ pi- SVS; #[Reconstructed PDG2011] +0.006533280 K_10 pi0 SVS; #[Reconstructed PDG2011] +# the Dalitz mode below includes K*(892)+ pi- and K0 rho(770)0 resonances +# LHCb PR 09 Apr 2004, split into KS/KL +0.000000000 K0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.029400000 K_S0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.027973482 K_L0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +# +0.008300000 K_S0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004444471 K_L0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.024000000 K*0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.010674092 K*0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.009201803 K*+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.006257226 K+ rho- pi0 PHSP; #[Reconstructed PDG2011] +0.005327844 K+ pi- rho0 PHSP; #[Reconstructed PDG2011] +0.019000000 K+ pi- omega PHSP; #[Reconstructed PDG2011] +0.009201803 K+ pi- eta PHSP; #[Reconstructed PDG2011] +0.007500000 K+ pi- eta' PHSP; #[Reconstructed PDG2011] +0.013300000 K+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.054000000 K_S0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.010121984 K_L0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +# +# K+ pi- pi0 pi0 is (15 +/- 5)% in the PDG, but we decrease it to +# have everything add to 1 and get enough neutral kaons: +#0.02575 K+ pi- pi0 pi0 PHSP; +# +#0.0143 K0 pi0 pi0 pi0 PHSP; +0.040346268 K0 pi0 pi0 pi0 PHSP; +0.000000000 K+ pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003496685 K+ pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.002800000 K_S0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002696128 K_L0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +#0.0638 K0 pi- pi+ pi0 pi0 PHSP; +#0.0192 K0 pi- pi+ pi0 pi0 pi0 PHSP; +# +0.002042800 phi K_S0 SVS; #[Reconstructed PDG2011] +0.002042800 phi K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 phi K0 SVS; #[Reconstructed PDG2011] +# +0.004650000 K_S0 K+ K- PHSP; #[Reconstructed PDG2011] +0.002797348 K_L0 K+ K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K+ K- PHSP; #[Reconstructed PDG2011] +# +0.000950000 K_S0 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.003940000 K+ K- PHSP; #[Reconstructed PDG2011] +0.000190000 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.000368072 K_L0 K_L0 PHSP; #[Reconstructed PDG2011] +0.000368072 anti-K*0 K0 SVS; #[Reconstructed PDG2011] +# +0.000092018 K*0 K_S0 SVS; #[Reconstructed PDG2011] +0.000092018 K*0 K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 K*0 anti-K0 SVS; #[Reconstructed PDG2011] +# +0.000487696 K*+ K- SVS; #[Reconstructed PDG2011] +0.001371069 K*- K+ SVS; #[Reconstructed PDG2011] +0.001288252 K*0 anti-K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000717741 phi pi0 SVS; #[Reconstructed PDG2011] +0.001012198 phi pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002430000 K+ K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002760541 K+ K- pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001280000 K_S0 K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001260647 K_L0 K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.001380270 anti-K0 K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001397000 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000800000 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000640000 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000810000 eta' pi0 PHSP; #[Reconstructed PDG2011] +0.001670000 eta eta PHSP; #[Reconstructed PDG2011] +0.009128189 rho+ pi- SVS; #[Reconstructed PDG2011] +0.004637709 rho- pi+ SVS; #[Reconstructed PDG2011] +0.003730000 rho0 pi0 SVS; #[Reconstructed PDG2011] +0.001214638 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000092018 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.005620000 pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.009360000 pi+ pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.001510000 pi+ pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.005521082 pi+ pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000420000 pi+ pi- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +# Doubly Cabibbo suppressed decays: +0.000138027 pi+ K- PHSP; #[Reconstructed PDG2011] +0.000128825 pi+ K*- PHSP; #[Reconstructed PDG2011] +0.000276054 pi+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.000248449 K- pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# PR LHCb - 19 Apr. 2004 Add anti-D0 -> mu+ mu- +0.000000000 mu- mu+ PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000140000 phi eta PHSP; #[Reconstructed PDG2011] +0.019000000 K*0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000220000 K+ pi- pi- pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000644126 K+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.003100000 K+ K- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000221000 K+ K+ K- pi- PHSP; #[Reconstructed PDG2011] +# +0.005600000 K_S0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.003680721 K_L0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 eta pi0 PHSP; #[Reconstructed PDG2011] +# +0.002600000 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.002392469 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.003500000 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.003358658 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000294458 K_L0 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000294458 K_L0 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K+ pi- pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001820000 rho0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001090000 eta pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 omega pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 eta' pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001260000 eta eta' PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000027000 phi gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000328000 K*0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# Updated to PDG 2008 +Decay D_s+ +0.024900000 phi e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.026700000 eta e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.009900000 eta' e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 anti-K0 e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 anti-K*0 e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.018309605 phi mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.022845082 eta mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.008186726 eta' mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 anti-K0 mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 anti-K*0 mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.005800000 mu+ nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.031100000 tau+ nu_tau SLN; #[Reconstructed PDG2011] +### Lange Nov14, 2004 - average cleo + babar (prelim) using stat error only.. +0.045000000 phi pi+ SVS; #[Reconstructed PDG2011] +0.015600000 eta pi+ PHSP; #[Reconstructed PDG2011] +0.038000000 eta' pi+ PHSP; #[Reconstructed PDG2011] +0.002300000 omega pi+ SVS; #[Reconstructed PDG2011] +0.000304906 rho+ pi0 SVS; #[Reconstructed PDG2011] +0.000076226 pi+ pi0 PHSP; #[Reconstructed PDG2011] +#? +0.000196200 rho0 pi+ SVS; # PDG 2014 +0.007852048 f_0 pi+ PHSP; # PDG 2014 +0.001753646 f_2 pi+ PHSP; # PDG 2014 +0.004754077 f'_0 pi+ PHSP; # PDG 2014 +0.005768112 f_0(1500) pi+ PHSP; # PDG 2014 +#0.000735750 rho(2S)0 pi+ PHSP; # PDG 2014 +0.000000000 pi+ pi- pi+ PHSP; # PDG 2014 (filled by exclusives) +0.084000000 phi rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.089000000 rho+ eta SVS; #[Reconstructed PDG2011] +0.124213286 rho+ eta' SVS; # Decrease compared to PDG 2014 to preserve unitarity after +# # fixing Ds --> 3pi, we also have too much of inclusive eta', +# #so pick this decay +0.006500000 pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.007622650 phi pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta' pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.012100000 phi pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 phi pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.014900000 K_S0 K+ PHSP; #[Reconstructed PDG2011] +0.011472088 K_L0 K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ PHSP; #[Reconstructed PDG2011] +# +0.030490600 anti-K*0 K+ SVS; #[Reconstructed PDG2011] +0.054000000 K*+ anti-K0 SVS; #[Reconstructed PDG2011] +0.072000000 anti-K*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.002286795 anti-K0 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 anti-K*0 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 K*+ anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.003049060 anti-K*0 K*+ pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 K+ K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.009600000 K_S0 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.007470197 K_L0 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000762265 anti-K0 K+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K+ K- pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000152453 phi K+ SVS; #[Reconstructed PDG2011] +0.001390000 eta K+ PHSP; #[Reconstructed PDG2011] +0.001600000 eta' K+ PHSP; #[Reconstructed PDG2011] +0.000152453 eta K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000490000 K+ K- K+ PHSP; #[Reconstructed PDG2011] +# +0.001200000 K_S0 pi+ PHSP; #[Reconstructed PDG2011] +0.000968077 K_L0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.001143397 rho+ K0 SVS; #[Reconstructed PDG2011] +0.002700000 rho0 K+ SVS; #[Reconstructed PDG2011] +0.010000000 K0 pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.001905662 a_1+ K0 SVS; #[Reconstructed PDG2011] +0.006021893 K*0 pi+ SVS; #[Reconstructed PDG2011] +0.003811325 K*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.003811325 K*0 pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000820000 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.004200000 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.008000000 pi+ pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.049000000 pi+ pi+ pi+ pi- pi- pi0 PHSP; #[Reconstructed PDG2011] +0.001300000 p+ anti-n0 PHSP; #[Reconstructed PDG2011] +# +0.000840000 K_S0 K_S0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000686038 K_L0 K_L0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.002900000 K_S0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002424003 K_L0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed +0.000129000 K+ K+ pi- PHSP; #[Reconstructed PDG2011] +0.003700000 K0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 K*0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 K+ K- pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.028000000 omega pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.016000000 omega pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# Updated to PDG 2008 +Decay D_s- +0.024900000 phi e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.026700000 eta e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.009900000 eta' e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 K0 e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 K*0 e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.018309605 phi mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.022845082 eta mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.008186726 eta' mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 K0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 K*0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.005800000 mu- anti-nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.031100000 tau- anti-nu_tau SLN; #[Reconstructed PDG2011] +0.045000000 phi pi- SVS; #[Reconstructed PDG2011] +0.015600000 eta pi- PHSP; #[Reconstructed PDG2011] +0.038000000 eta' pi- PHSP; #[Reconstructed PDG2011] +0.002300000 omega pi- SVS; #[Reconstructed PDG2011] +0.000304906 rho- pi0 SVS; #[Reconstructed PDG2011] +0.000076226 pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000196200 rho0 pi- SVS; # PDG 2014 +0.007852048 f_0 pi- PHSP; # PDG 2014 +0.001753646 f_2 pi- PHSP; # PDG 2014 +0.004754077 f'_0 pi- PHSP; # PDG 2014 +0.005768112 f_0(1500) pi- PHSP; # PDG 2014 +#0.000735750 rho(2S)0 pi- PHSP; # PDG 2014 +0.000000000 pi- pi+ pi- PHSP; # PDG 2014 (filled by exclusives) +0.084000000 phi rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.089000000 rho- eta SVS; #[Reconstructed PDG2011] +0.124213286 rho- eta' SVS; # Decrease compared to PDG 2014 to preserve unitarity after +0.006500000 pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.007622650 phi pi- pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta pi- pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta' pi- pi0 PHSP; #[Reconstructed PDG2011] +0.012100000 phi pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 phi pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.014900000 K_S0 K- PHSP; #[Reconstructed PDG2011] +0.011472088 K_L0 K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- PHSP; #[Reconstructed PDG2011] +# +0.030490600 K*0 K- SVS; #[Reconstructed PDG2011] +0.054000000 K*- K0 SVS; #[Reconstructed PDG2011] +0.072000000 K*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.002286795 K0 K- pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 K*0 K- pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 K*- K0 pi0 PHSP; #[Reconstructed PDG2011] +0.003049060 K*0 K*- pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 K+ K- pi- PHSP; #[Reconstructed PDG2011] +# +0.009600000 K_S0 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.007470197 K_L0 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000762265 K0 K- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K- K+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000152453 phi K- SVS; #[Reconstructed PDG2011] +0.001390000 eta K- PHSP; #[Reconstructed PDG2011] +0.001600000 eta' K- PHSP; #[Reconstructed PDG2011] +0.000152453 eta K- pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K- pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000490000 K- K- K+ PHSP; #[Reconstructed PDG2011] +# +0.001200000 K_S0 pi- PHSP; #[Reconstructed PDG2011] +0.000968077 K_L0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi- PHSP; #[Reconstructed PDG2011] +# +0.001143397 rho- anti-K0 SVS; #[Reconstructed PDG2011] +0.002700000 rho0 K- SVS; #[Reconstructed PDG2011] +0.010000000 anti-K0 pi- pi0 PHSP; #[Reconstructed PDG2011] +0.001905662 a_1- anti-K0 SVS; #[Reconstructed PDG2011] +0.006021893 anti-K*0 pi- SVS; #[Reconstructed PDG2011] +0.003811325 anti-K*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.003811325 anti-K*0 pi- pi0 PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000820000 K- pi0 PHSP; #[Reconstructed PDG2011] +0.004200000 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.008000000 pi+ pi+ pi- pi- pi- PHSP; #[Reconstructed PDG2011] +0.049000000 pi+ pi+ pi- pi- pi- pi0 PHSP; #[Reconstructed PDG2011] +0.001300000 anti-p- n0 PHSP; #[Reconstructed PDG2011] +# +0.000840000 K_S0 K_S0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000686038 K_L0 K_L0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +0.002900000 K_S0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.002424003 K_L0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed +0.000129000 K- K- pi+ PHSP; #[Reconstructed PDG2011] +0.003700000 anti-K0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 anti-K*0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 K- K+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.028000000 omega pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.016000000 omega pi- pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# D** +# +Decay D_0*+ +0.3333 D+ pi0 PHSP; +0.6667 D0 pi+ PHSP; +Enddecay +Decay D_0*- +0.3333 D- pi0 PHSP; +0.6667 anti-D0 pi- PHSP; +Enddecay +Decay D_0*0 +0.3333 D0 pi0 PHSP; +0.6667 D+ pi- PHSP; +Enddecay +Decay anti-D_0*0 +0.3333 anti-D0 pi0 PHSP; +0.6667 D- pi+ PHSP; +Enddecay +# + +SetLineshapePW D_1+ D*+ pi0 2 +SetLineshapePW D_1+ D*0 pi+ 2 +SetLineshapePW D_1- D*- pi0 2 +SetLineshapePW D_1- anti-D*0 pi- 2 +SetLineshapePW D_10 D*0 pi0 2 +SetLineshapePW D_10 D*+ pi- 2 +SetLineshapePW anti-D_10 anti-D*0 pi0 2 +SetLineshapePW anti-D_10 D*- pi+ 2 + +Decay D_1+ +0.3333 D*+ pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 D*0 pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay D_1- +0.3333 D*- pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 anti-D*0 pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay D_10 +0.3333 D*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 D*+ pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay anti-D_10 +0.3333 anti-D*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 D*- pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# +Decay D'_1+ +0.3333 D*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.6667 D*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay D'_1- +0.3333 D*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.6667 anti-D*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay D'_10 +0.6667 D*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay anti-D'_10 +0.3333 anti-D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.6667 D*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# + +SetLineshapePW D_2*+ D*+ pi0 2 +SetLineshapePW D_2*+ D*0 pi+ 2 +SetLineshapePW D_2*- D*- pi0 2 +SetLineshapePW D_2*- anti-D*0 pi- 2 +SetLineshapePW D_2*0 D*0 pi0 2 +SetLineshapePW D_2*0 D*+ pi- 2 +SetLineshapePW anti-D_2*0 anti-D*0 pi0 2 +SetLineshapePW anti-D_2*0 D*- pi+ 2 + +Decay D_2*+ +0.1030 D*+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2090 D*0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 D+ pi0 TSS; +0.4590 D0 pi+ TSS; +Enddecay +Decay D_2*- +0.1030 D*- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2090 anti-D*0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 D- pi0 TSS; +0.4590 anti-D0 pi- TSS; +Enddecay +Decay D_2*0 +0.2090 D*+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1030 D*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 D0 pi0 TSS; +0.4590 D+ pi- TSS; +Enddecay +Decay anti-D_2*0 +0.1030 anti-D*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2090 D*- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 anti-D0 pi0 TSS; +0.4590 D- pi+ TSS; +Enddecay +# +# D_s ** +# +Decay D_s0*+ +# 0.5000 D+ K0 PHSP; +# 0.5000 D0 K+ PHSP; +1.000 D_s+ pi0 PHSP; +Enddecay +Decay D_s0*- +# 0.5000 D- anti-K0 PHSP; +# 0.5000 anti-D0 K- PHSP; +1.000 D_s- pi0 PHSP; +Enddecay +Decay D'_s1+ +0.5000 D*+ K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.5000 D*0 K+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.0000 gamma D_s*+ PHSP; +0.0000 gamma D_s+ PHSP; +Enddecay +Decay D'_s1- +0.5000 D*- anti-K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.5000 anti-D*0 K- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.0000 gamma D_s*- PHSP; +0.0000 gamma D_s- PHSP; +Enddecay +Decay D_s1+ +0.80000 D_s*+ pi0 PARTWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.20000 D_s+ gamma VSP_PWAVE; +Enddecay +Decay D_s1- +0.80000 D_s*- pi0 PARTWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.20000 D_s- gamma VSP_PWAVE; +Enddecay +Decay D_s2*+ +0.0500 D*+ K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0500 D*0 K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.4300 D+ K0 TSS; +0.4700 D0 K+ TSS; +Enddecay +Decay D_s2*- +0.0500 D*- anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0500 anti-D*0 K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.4300 D- anti-K0 TSS; +0.4700 anti-D0 K- TSS; +Enddecay +# +# +# Charm Mesons: Radially Excited States +# +Decay D(2S)0 +0.6667 D*+ pi- SVS; +0.3333 D*0 pi0 SVS; +Enddecay +Decay anti-D(2S)0 +0.3333 anti-D*0 pi0 SVS; +0.6667 D*- pi+ SVS; +Enddecay +Decay D(2S)+ +0.3333 D*+ pi0 SVS; +0.6667 D*0 pi+ SVS; +Enddecay +Decay D(2S)- +0.3333 D*- pi0 SVS; +0.6667 anti-D*0 pi- SVS; +Enddecay +Decay D*(2S)0 +0.3333 D*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D0 pi0 VSS; +0.3333 D+ pi- VSS; +Enddecay +Decay anti-D*(2S)0 +0.1667 anti-D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 D*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 anti-D0 pi0 VSS; +0.3333 D- pi+ VSS; +Enddecay +Decay D*(2S)+ +0.1667 D*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 D*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D+ pi0 VSS; +0.3333 D0 pi+ VSS; +Enddecay +Decay D*(2S)- +0.1667 D*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 anti-D*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D- pi0 VSS; +0.3333 anti-D0 pi- VSS; +Enddecay +# +# +# Strange Mesons updated to PDG 2008 +# +# +Decay K_S0 +0.691086452 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.305986452 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000201 pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001722185 pi+ pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000042831 pi+ pi- e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000025 pi0 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000002399 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000344328 pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000344328 pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000235400 pi+ mu- anti-nu_mu PHSP; #[New mode added] #TP manually added 9/1/2011 according to pdg +0.000235400 pi- mu+ nu_mu PHSP; #[New mode added] #TP manually added 9/1/2011 according to pdg +Enddecay +# +# K_L0 is decayed in GEANT +# +Decay K0 +0.500 K_L0 PHSP; +0.500 K_S0 PHSP; +Enddecay +Decay anti-K0 +0.500 K_L0 PHSP; +0.500 K_S0 PHSP; +Enddecay +# +Decay K*0 +0.6657 K+ pi- VSS; +0.3323 K0 pi0 VSS; +0.0020 K0 gamma VSP_PWAVE; +Enddecay +# +Decay anti-K*0 +0.6657 K- pi+ VSS; +0.3323 anti-K0 pi0 VSS; +0.0020 anti-K0 gamma VSP_PWAVE; +Enddecay +# +Decay K*+ +0.6657 K0 pi+ VSS; +0.3323 K+ pi0 VSS; +0.0020 K+ gamma VSP_PWAVE; +Enddecay +# +Decay K*- +0.6657 anti-K0 pi- VSS; +0.3323 K- pi0 VSS; +0.0020 K- gamma VSP_PWAVE; +Enddecay +# +# The decays below are for particle aliases and used when +# generating CP violating decays that depends on the decay +# of the neutral K* +# +Decay K*L +1.0000 pi0 K_L0 VSS; +Enddecay +Decay K*S +1.0000 pi0 K_S0 VSS; +Enddecay +Decay K*BL +1.0000 pi0 K_L0 VSS; +Enddecay +Decay K*BS +1.0000 pi0 K_S0 VSS; +Enddecay +Decay K*0T +1.0000 pi- K+ VSS; +Enddecay +Decay anti-K*0T +1.0000 pi+ K- VSS; +Enddecay +# +# +Decay K_0*+ +0.6667 K0 pi+ PHSP; +0.3333 K+ pi0 PHSP; +Enddecay +# +Decay K_0*- +0.6667 anti-K0 pi- PHSP; +0.3333 K- pi0 PHSP; +Enddecay +# +Decay K_0*0 +0.6667 K+ pi- PHSP; +0.3333 K0 pi0 PHSP; +Enddecay +# +Decay K_0*0N +1.0000 K0 pi0 PHSP; +Enddecay +# +Decay anti-K_0*0 +0.6667 K- pi+ PHSP; +0.3333 anti-K0 pi0 PHSP; +Enddecay +# +Decay anti-K_0*0N +1.0000 anti-K0 pi0 PHSP; +Enddecay +# +Decay K_10 +0.2800 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 K0 pi+ pi- PHSP; +0.1244 K+ pi- pi0 PHSP; +0.0412 K0 pi0 pi0 PHSP; +Enddecay +# +Decay anti-K_10 +0.2800 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 anti-K0 pi+ pi- PHSP; +0.1244 K- pi+ pi0 PHSP; +0.0412 anti-K0 pi0 pi0 PHSP; +Enddecay +# +Decay K_1+ +0.2800 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 K+ pi+ pi- PHSP; +0.1244 K0 pi+ pi0 PHSP; +0.0412 K+ pi0 pi0 PHSP; +Enddecay +# +Decay K_1- +0.2800 rho- anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 K- pi+ pi- PHSP; +0.1244 anti-K0 pi- pi0 PHSP; +0.0412 K- pi0 pi0 PHSP; +Enddecay +# +Decay K'_1+ +0.6300 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 K+ pi+ pi- PHSP; +0.0067 K+ pi0 pi0 PHSP; +Enddecay +# +Decay K'_1- +0.6300 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho- anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 K- pi+ pi- PHSP; +0.0067 K- pi0 pi0 PHSP; +Enddecay +# +Decay K'_10 +0.6300 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 K0 pi+ pi- PHSP; +0.0067 K0 pi0 pi0 PHSP; +Enddecay +# +Decay anti-K'_10 +0.6300 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 anti-K0 pi+ pi- PHSP; +0.0067 anti-K0 pi0 pi0 PHSP; +Enddecay +# +Decay K_2*+ +0.3340 K0 pi+ TSS; +0.1670 K+ pi0 TSS; +0.1645 K*0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 K*+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 K*0 pi+ pi0 PHSP; +0.0450 K*+ pi+ pi- PHSP; +0.0450 K*+ pi0 pi0 PHSP; +0.0580 rho+ K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# +Decay K_2*- +0.3340 anti-K0 pi- TSS; +0.1670 K- pi0 TSS; +0.1645 anti-K*0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 K*- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 anti-K*0 pi- pi0 PHSP; +0.0450 K*- pi+ pi- PHSP; +0.0450 K*- pi0 pi0 PHSP; +0.0580 rho- K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# +Decay K_2*0 +0.3340 K+ pi- TSS; +0.1670 K0 pi0 TSS; +0.1645 K*+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 K*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 K*0 pi+ pi- PHSP; +0.0450 K*0 pi0 pi0 PHSP; +0.0450 K*+ pi- pi0 PHSP; +0.0580 rho- K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# +Decay anti-K_2*0 +0.3340 K- pi+ TSS; +0.1670 anti-K0 pi0 TSS; +0.1645 K*- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 anti-K*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 anti-K*0 pi+ pi- PHSP; +0.0450 anti-K*0 pi0 pi0 PHSP; +0.0450 K*- pi+ pi0 PHSP; +0.0580 rho+ K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay + + + + +# Decay K*(1410) +Decay K'*0 +0.0467 K+ pi- VSS; +0.0233 K0 pi0 VSS; +0.5760 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay anti-K'*0 +0.0467 K- pi+ VSS; +0.0233 anti-K0 pi0 VSS; +0.5760 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K'*+ +0.0467 K0 pi+ VSS; +0.0233 K+ pi0 VSS; +0.5760 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K'*- +0.0467 anti-K0 pi- VSS; +0.0233 K- pi0 VSS; +0.5760 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho- K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# + + +# Decay K*(1680) +Decay K''*0 +0.2580 K+ pi- VSS; +0.1290 K0 pi0 VSS; +0.2093 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay anti-K''*0 +0.2580 K- pi+ VSS; +0.1290 anti-K0 pi0 VSS; +0.2093 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K''*+ +0.2580 K0 pi+ VSS; +0.1290 K+ pi0 VSS; +0.2093 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K''*- +0.2580 anti-K0 pi- VSS; +0.1290 K- pi0 VSS; +0.2093 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho- K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay + +Decay Xsd +1.00000 d anti-s PYTHIA 42; +Enddecay + +Decay anti-Xsd +1.00000 anti-d s PYTHIA 42; +Enddecay + +Decay Xsu +1.00000 u anti-s PYTHIA 42; +Enddecay + +Decay anti-Xsu +1.00000 anti-u s PYTHIA 42; +Enddecay + +# Xss decays can be uncommented when Jst74/lucomp.F recognizes Xss +Decay Xss +1.00000 s anti-s PYTHIA 42; +Enddecay + +Decay anti-Xss +1.00000 anti-s s PYTHIA 42; +Enddecay + +# +# Light Mesons Updated to PDG 2008 +# +Decay pi0 +0.988228297 gamma gamma PHSP; #[Reconstructed PDG2011] +0.011738247 e+ e- gamma PI0_DALITZ; #[Reconstructed PDG2011] +0.000033392 e+ e+ e- e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000065 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay eta +0.393100000 gamma gamma PHSP; #[Reconstructed PDG2011] +0.325700000 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.227400000 pi- pi+ pi0 ETA_DALITZ; #[Reconstructed PDG2011] +0.046000000 gamma pi- pi+ PHSP; #[Reconstructed PDG2011] +0.007000000 gamma e+ e- PHSP; #[Reconstructed PDG2011] +0.000310000 gamma mu+ mu- PHSP; #[Reconstructed PDG2011] +0.000270000 gamma gamma pi0 PHSP; #[Reconstructed PDG2011] +0.000214200 pi+ pi- e+ e- PHSP; #[Reconstructed PDG2011] +0.000005800 mu+ mu- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay rho0 +1.000 pi+ pi- VSS; +Enddecay +Decay rho+ +1.000 pi+ pi0 VSS; +Enddecay +Decay rho- +1.000 pi- pi0 VSS; +Enddecay +# +Decay omega +0.892000000 pi- pi+ pi0 OMEGA_DALITZ; #[Reconstructed PDG2011] +0.082800000 pi0 gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.015300000 pi- pi+ VSS; #[Reconstructed PDG2011] +0.000460000 eta gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.000770000 pi0 e+ e- PHOTOS PHSP; #[Reconstructed PDG2011] +0.000130000 pi0 mu+ mu- PHOTOS PHSP; #[Reconstructed PDG2011] +0.00150 pi+ pi- gamma PHSP; +0.000066000 pi0 pi0 gamma PHSP; #[Reconstructed PDG2011] +0.00050 pi+ pi- pi+ pi- PHSP; +0.000072800 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 mu+ mu- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay eta' +0.432000000 pi+ pi- eta PHSP; #[Reconstructed PDG2011] +0.217000000 pi0 pi0 eta PHSP; #[Reconstructed PDG2011] +0.293511000 rho0 gamma SVP_HELAMP 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.027500000 omega gamma SVP_HELAMP 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.022200000 gamma gamma PHSP; #[Reconstructed PDG2011] +0.001680000 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000109000 gamma mu- mu+ PHOTOS PHSP; #[Reconstructed PDG2011] +0.003600000 pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.002400000 pi+ pi- e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay phi +0.489000000 K+ K- VSS; #[Reconstructed PDG2011] +Enddecay +# +Decay a_1+ +0.4920 rho0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.5080 rho+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay a_10 +0.5000 rho- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.5000 rho+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay a_1- +0.4920 rho0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.5080 rho- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay a_2+ +0.3500 rho0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.3500 rho+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1430 eta pi+ TSS; +0.1000 omega pi+ pi0 PHSP; +0.0490 anti-K0 K+ TSS; +0.0027 pi+ gamma PHSP; +0.0053 eta' pi+ TSS; +Enddecay +# +Decay a_2- +0.3500 rho0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.3500 rho- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1430 eta pi- TSS; +0.1000 omega pi- pi0 PHSP; +0.0490 anti-K0 K- TSS; +0.0027 pi- gamma PHSP; +0.0053 eta' pi- TSS; +Enddecay +# +Decay a_20 +0.3500 rho+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.3500 rho- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1430 eta pi0 TSS; +0.1000 omega pi+ pi- PHSP; +0.0245 K+ K- TSS; +0.01225 K_L0 K_L0 TSS; +0.01225 K_S0 K_S0 TSS; +0.0027 pi0 gamma PHSP; +0.0053 eta' pi0 TSS; +Enddecay +# +Decay b_1+ +0.9984 omega pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0016 pi+ gamma VSP_PWAVE; +Enddecay +Decay b_1- +0.9984 omega pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0016 pi- gamma VSP_PWAVE; +Enddecay +Decay b_10 +0.9984 omega pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0016 pi0 gamma VSP_PWAVE; +Enddecay +# +Decay a_00 +0.9000 eta pi0 PHSP; +0.0500 K+ K- PHSP; +0.0250 K_S0 K_S0 PHSP; +0.0250 K_L0 K_L0 PHSP; +Enddecay +Decay a_0+ +0.9000 eta pi+ PHSP; +0.1000 anti-K0 K+ PHSP; +Enddecay +Decay a_0- +0.9000 eta pi- PHSP; +0.1000 K0 K- PHSP; +Enddecay +# +Decay f_0 +0.6667 pi+ pi- PHSP; +0.3333 pi0 pi0 PHSP; +#0.1100 K+ K- PHSP; +#0.0550 K_S0 K_S0 PHSP; +#0.0550 K_L0 K_L0 PHSP; +Enddecay +# +# +# MK: Based on PDG 2014 without any attempt to really include everything. One +# thing, which is missing is KK mode, but data are scattered quite lot and +# I would also need to find place where to make space for it. For needs I +# have at this moment, this should be sufficient +#Decay f_0(1370) +#0.17333 pi+ pi- PHSP; +#0.08667 pi0 pi0 PHSP; +#0.26000 pi+ pi+ pi- pi- PHSP; +#0.32000 pi+ pi- pi0 pi0 PHSP; +#0.10667 rho+ rho- PHSP; +#0.05333 rho0 rho0 PHSP; +#Enddecay +Decay f'_0 +0.5200 pi+ pi- PHSP; +0.2600 pi0 pi0 PHSP; +0.0750 pi+ pi+ pi- pi- PHSP; +0.0750 pi+ pi- pi0 pi0 PHSP; +0.0350 K+ K- PHSP; +0.0175 K_S0 K_S0 PHSP; +0.0175 K_L0 K_L0 PHSP; +Enddecay +# +Decay f_1 +0.110000000 rho0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.043364159 rho0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.043442860 rho+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.043442860 rho- pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.094440999 a_00 pi0 VSS; #[Reconstructed PDG2011] +0.094440999 a_0+ pi- VSS; #[Reconstructed PDG2011] +0.094440999 a_0- pi+ VSS; #[Reconstructed PDG2011] +0.086570916 eta pi+ pi- PHSP; #[Reconstructed PDG2011] +0.043285458 eta pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.020226114 K+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.010152407 K0 anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.020226114 anti-K0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.020226114 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.055000000 gamma rho0 PHSP; #[Reconstructed PDG2011] +0.220000000 pi0 pi0 pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 pi+ pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000740000 phi gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay f'_1 +0.2500 K+ K- pi0 PHSP; +0.2500 K0 anti-K0 pi0 PHSP; +0.2500 anti-K0 K+ pi- PHSP; +0.2500 K0 K- pi+ PHSP; +Enddecay +# +Decay f_2 +0.5650 pi+ pi- TSS; +0.2820 pi0 pi0 TSS; +0.028000000 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.071000000 pi+ pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003000000 pi0 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.0230 K+ K- TSS; +0.0115 K_S0 K_S0 TSS; +0.0115 K_L0 K_L0 TSS; +0.004000000 eta eta TSS; #[Reconstructed PDG2011] +0.000016400 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay f_0(1500) +0.019000000 eta eta' PHSP; #[Reconstructed PDG2011] +0.051000000 eta eta PHSP; #[Reconstructed PDG2011] +0.1410 pi0 pi0 pi0 pi0 PHSP; +0.3540 pi+ pi- pi+ pi- PHSP; +0.2330 pi+ pi- PHSP; +0.1160 pi0 pi0 PHSP; +0.0430 K+ K- PHSP; +0.0215 K_S0 K_S0 PHSP; +0.0215 K_L0 K_L0 PHSP; +Enddecay +# +Decay f'_2 +0.443904021 K+ K- TSS; #[Reconstructed PDG2011] +0.221952010 K_S0 K_S0 TSS; #[Reconstructed PDG2011] +0.221952010 K_L0 K_L0 TSS; #[Reconstructed PDG2011] +0.104000000 eta eta TSS; #[Reconstructed PDG2011] +0.005493862 pi+ pi- TSS; #[Reconstructed PDG2011] +0.002696987 pi0 pi0 TSS; #[Reconstructed PDG2011] +0.000001110 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay h_1 +0.3333 rho+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 rho- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3334 rho0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay h'_1 +0.2500 K*+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2500 K*- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2500 anti-K*0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2500 K*0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay rho(2S)+ +0.4000 pi+ pi0 PHSP; +0.4000 pi+ pi+ pi- pi0 PHSP; +0.2000 pi+ pi0 pi0 pi0 PHSP; +Enddecay +Decay rho(2S)- +0.4000 pi- pi0 PHSP; +0.4000 pi- pi+ pi- pi0 PHSP; +0.2000 pi- pi0 pi0 pi0 PHSP; +Enddecay +Decay rho(2S)0 +0.4000 pi+ pi- PHSP; +0.3500 pi+ pi- pi+ pi- PHSP; +0.1500 pi+ pi- pi0 pi0 PHSP; +0.1000 pi0 pi0 pi0 pi0 PHSP; +Enddecay +Decay phi(1680) +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +Decay rho(3S)0 +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +Decay omega(1650) +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +#Decay rho(1900) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +Decay omega(2S) +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +#Decay rho(2150) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +#Decay omega(1960) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +#Decay rho(1965) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +# +# +# cc= mesons Updated to PDG 2008 +# +Decay eta_c +0.001300000 p+ anti-p- PHSP; #[Reconstructed PDG2011] +0.002700000 phi phi SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; #[Reconstructed PDG2011] +0.002900000 phi K+ K- PHSP; #[Reconstructed PDG2011] +0.0067 rho0 rho0 SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; +0.0133 rho+ rho- SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; +0.012000000 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001600000 K+ K- K+ K- PHSP; #[Reconstructed PDG2011] +0.015000000 K+ K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.0327 eta pi+ pi- PHSP; +0.0163 eta pi0 pi0 PHSP; +0.0273 eta' pi+ pi- PHSP; +0.0137 eta' pi0 pi0 PHSP; +0.0117 pi0 K+ K- PHSP; +0.0233 K+ anti-K0 pi- PHSP; +0.0233 K- K0 pi+ PHSP; +0.0117 K0 anti-K0 pi0 PHSP; +0.0046 K*+ K*- SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; +0.0046 K*0 anti-K*0 SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0 ; +0.01 K*0 K- pi+ PHSP; +0.01 anti-K*0 K+ pi- PHSP; +# +#March 2009 New Modes +0.01500 K*0 anti-K*0 pi+ pi- PHSP; +0.007100000 K+ K- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.015000000 pi+ pi- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001040000 Lambda0 anti-Lambda0 PHSP; #[Reconstructed PDG2011] +0.007600000 f_2 f_2 PHSP; #[Reconstructed PDG2011] +0.027000000 f_2 f'_2 PHSP; #[Reconstructed PDG2011] +# +0.682497000 rndmflav anti-rndmflav PYTHIA 42; +0.000063000 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay eta_c(2S) + 0.019 K+ anti-K0 pi- PHSP; + 0.019 K- K0 pi+ PHSP; + 0.0095 pi0 K+ K- PHSP; + 0.0095 K0 anti-K0 pi0 PHSP; +0.943 rndmflav anti-rndmflav PYTHIA 42; +Enddecay +# +Decay J/psi +0.3 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.7 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(2S) +0.336000000 J/psi pi+ pi- VVPIPI; #[Reconstructed PDG2011] +0.177300000 J/psi pi0 pi0 VVPIPI; #[Reconstructed PDG2011] +0.032800000 J/psi eta PARTWAVE 0.0 0.0 1.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.001300000 J/psi pi0 PARTWAVE 0.0 0.0 1.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +# below we also account for chi_c -> JPsi BR +0.00111592 gamma chi_c0 PHSP; #[Reconstructed PDG2011] +0.03164800 gamma chi_c1 PHSP; #[Reconstructed PDG2011] +0.01704300 gamma chi_c2 PHSP; #[Reconstructed PDG2011] +Enddecay + +Decay psi(4040) +0.000010700 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000014000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000005000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.002099938 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.000899973 D+ D- VSS; #[Reconstructed PDG2011] +0.167895013 D*0 anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.167895013 anti-D*0 D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.181494610 D*+ D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.181494610 D*- D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.159695257 D*0 anti-D*0 PHSP; #[Reconstructed PDG2011] +0.098197084 D*+ D*- PHSP; #[Reconstructed PDG2011] +0.000000000 D0 anti-D0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ anti-D0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 D+ anti-D*0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D- D*0 pi+ PHSP; #[Reconstructed PDG2011] +0.040298803 D_s+ D_s- VSS; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(4160) +0.000008100 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000009999 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000006000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.039697852 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.038697906 D+ D- VSS; #[Reconstructed PDG2011] +0.051997187 D*0 anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.051997187 anti-D*0 D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.051497214 D*+ D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.051497214 D*- D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.298613845 D*0 anti-D*0 PHSP; #[Reconstructed PDG2011] +0.308183327 D*+ D*- PHSP; #[Reconstructed PDG2011] +0.000000000 D0 anti-D0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ anti-D0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 D+ anti-D*0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D- D*0 pi+ PHSP; #[Reconstructed PDG2011] +0.009999459 D_s+ D_s- VSS; #[Reconstructed PDG2011] +0.048897355 D_s*+ D_s- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.048897355 D_s*- D_s+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.000000000 D_s+ D_s- pi0 PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(4415) +0.000009400 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000011000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000007000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.024399331 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.021899400 D+ D- VSS; #[Reconstructed PDG2011] +0.031999123 D*0 anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.031999123 anti-D*0 D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.034299060 D*+ D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.034299060 D*- D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.345090544 D*0 anti-D*0 PHSP; #[Reconstructed PDG2011] +0.353890303 D*+ D*- PHSP; #[Reconstructed PDG2011] +0.000000000 D0 anti-D0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ anti-D0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 D+ anti-D*0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D- D*0 pi+ PHSP; #[Reconstructed PDG2011] +0.011799677 D_s+ D_s- VSS; #[Reconstructed PDG2011] +0.041998849 D_s*+ D_s- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.041998849 D_s*- D_s+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.026299279 D_s*+ D_s*- PHSP; #[Reconstructed PDG2011] +0.000000000 D_s+ D_s- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s*+ D_s- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s+ D_s*- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s+ D- anti-K0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s- D+ anti-K0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D_s- K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D_s+ K- PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay chi_c0 +0.011600000 gamma J/psi PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay chi_c1 +0.344000000 J/psi gamma VVP 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +Enddecay +# +Decay chi_c2 +0.195000000 gamma J/psi PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(3770) +0.410000000 D+ D- VSS; #[Reconstructed PDG2011] +0.520000000 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.001930000 J/psi pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000800000 J/psi pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.0073 gamma chi_c0 PHSP; +0.0029 gamma chi_c1 PHSP; +0.055850300 rndmflav anti-rndmflav PYTHIA 42; +0.000900000 J/psi eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000009700 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000310000 phi eta PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay X_1(3872) +1.000 rndmflav anti-rndmflav PYTHIA 42; +Enddecay +# +# +# bb= Mesons Updated to PDG 2008 +# +Decay eta_b +1.000 rndmflav anti-rndmflav PYTHIA 42; +Enddecay +# +Decay Upsilon +0.024800000 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.024800000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.026000000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.014959973 d anti-d PYTHIA 91; +0.044879919 u anti-u PYTHIA 91; +0.014959973 s anti-s PYTHIA 91; +0.044879919 c anti-c PYTHIA 91; +0.774328202 g g g PYTHIA 92; +0.028922614 gamma g g PYTHIA 92; +0.000063000 gamma pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000017000 gamma pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000011400 gamma K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000290000 gamma pi+ pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000250000 gamma pi+ pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000250000 gamma pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000240000 gamma pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000150000 gamma pi+ pi- p+ anti-p- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000040000 gamma pi+ pi+ pi- pi- p+ anti-p- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000020000 gamma K+ K+ K- K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000037000 gamma f'_2 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000101000 gamma f_2 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Upsilon(2S) +0.019100000 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.019300000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.020000000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.181000000 Upsilon pi+ pi- PHSP; #[Reconstructed PDG2011] +0.086000000 Upsilon pi0 pi0 PHSP; #[Reconstructed PDG2011] +# V-> gamma S Partial wave (L,S)=(0,1) +0.038000000 gamma chi_b0 HELAMP 1. 0. +1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.069000000 gamma chi_b1 HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.071500000 gamma chi_b2 HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +0.00500 d anti-d PYTHIA 91; +0.02000 u anti-u PYTHIA 91; +0.00500 s anti-s PYTHIA 91; +0.02000 c anti-c PYTHIA 91; +0.42160 g g g PYTHIA 92; +0.01600 gamma g g PYTHIA 92; +0.000210000 Upsilon eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000390000 gamma eta_b PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Upsilon(3S) +0.0181 e+ e- PHOTOS VLL; +0.021800000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.022900000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.044000000 Upsilon pi+ pi- PHSP; #[Reconstructed PDG2011] +0.022000000 Upsilon pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.024500000 Upsilon(2S) pi+ pi- PHSP; #[Reconstructed PDG2011] +0.018500000 Upsilon(2S) pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.050000000 Upsilon(2S) gamma gamma PHSP; #[Reconstructed PDG2011] +# V-> gamma S Partial wave (L,S)=(0,1) +0.059000000 gamma chi_b0(2P) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.126000000 gamma chi_b1(2P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.131000000 gamma chi_b2(2P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +0.00700 d anti-d PYTHIA 91; +0.02800 u anti-u PYTHIA 91; +0.00700 s anti-s PYTHIA 91; +0.02800 c anti-c PYTHIA 91; +0.37780 g g g PYTHIA 92; +0.01000 gamma g g PYTHIA 92; +0.003000000 gamma chi_b0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000510000 gamma eta_b PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# + +Decay Upsilon(5S) +0.5 B+ B- PHSP; +0.481487200 g g g PYTHIA 92; +0.000002800 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.005300000 Upsilon pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.007800000 Upsilon(2S) pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004800000 Upsilon(3S) pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000610000 Upsilon K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay + +Decay chi_b0 +# S-> gamma V Partial wave (L,S)=(0,0) +0.0500 gamma Upsilon HELAMP 1. 0. 1. 0.; +0.949650000 rndmflav anti-rndmflav PYTHIA 42; +0.000110000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000240000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b1 +# V-> gamma V Partial wave (L,S)=(0,1) +0.350000000 gamma Upsilon HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +0.643080000 g g PYTHIA 91; +0.000200000 pi+ pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000800000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000150000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000860000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000190000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001700000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000260000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000750000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000260000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001400000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b2 +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.220000000 gamma Upsilon PHSP; #[Reconstructed PDG2011] +#0.2200 gamma Upsilon HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.775550000 g g PYTHIA 91; +0.000080000 pi+ pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000110000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000210000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000390000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000070000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001000000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000360000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000080000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b0(2P) +# S-> gamma V Partial wave (L,S)=(0,0) +0.009000000 gamma Upsilon HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +0.046000000 gamma Upsilon(2S) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# S-> gamma V Partial wave (L,S)=(0,0) +0.00150 gamma Upsilon_1(1D) HELAMP 1. 0. 1. 0.; +0.94350 g g PYTHIA 91; +Enddecay +# +Decay chi_b1(2P) +# V-> gamma V Partial wave (L,S)=(0,1) +0.085000000 gamma Upsilon HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +0.210000000 gamma Upsilon(2S) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.0097 gamma Upsilon_1(1D) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.0236 gamma Upsilon_2(1D) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +0.648650000 g g PYTHIA 91; +0.016300000 omega Upsilon PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000310000 pi+ pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000590000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000100000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000550000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001000000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000120000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001200000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000200000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000610000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000170000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001900000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b2(2P) +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.071000000 gamma Upsilon PHSP; #[Reconstructed PDG2011] +#0.0710 gamma Upsilon HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.162000000 gamma Upsilon(2S) PHSP; #[Reconstructed PDG2011] +#0.1620 gamma Upsilon(2S) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.00023 gamma Upsilon_1(1D) PHSP; +#0.00023 gamma Upsilon_1(1D) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +# T -> gamma T Partial wave (L,S)=(0,2) +0.00290 gamma Upsilon_2(1D) PHSP; +#0.00290 gamma Upsilon_2(1D) HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# spin 3 not yet in HELAMP. +0.01420 gamma Upsilon_3(1D) PYTHIA 0; +# T-> gamma 3 Partial wave (L,S)=(0,2) +#0.01420 gamma Upsilon_3(1D) HELAMP 3.8729833 0. 3.1622777 0. +# 2.4494897 0. 1.7320508. 0. 1. 0. +# 1. 0. 1.7320508 0. 2.4494897 0. +# 3.1622777 0. 3.8729833 0.; +0.734240000 g g PYTHIA 91; +0.011000000 omega Upsilon PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000390000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000240000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000470000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001200000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000140000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000420000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001300000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay h_b +1.00000 g g PYTHIA 91; +Enddecay + +Decay chi_b0(3P) +#see Kwong and Rosner, PRD 38,279 (1988) +# S-> gamma V Partial wave (L,S)=(0,0) +0.01700 gamma Upsilon(3S) HELAMP 1. 0. 1. 0.; +# S-> gamma V Partial wave (L,S)=(0,0) +0.00400 gamma Upsilon_1(2D) HELAMP 1. 0. 1. 0.; +0.97900 g g PYTHIA 91; +Enddecay + +Decay chi_b1(3P) +#see Kwong and Rosner, PRD 38,279 (1988) +# V-> gamma V Partial wave (L,S)=(0,1) +0.15000 gamma Upsilon(3S) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.03100 gamma Upsilon_2(2D) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +# V-> gamma V Partial wave (L,S)=(0,1) +0.01300 gamma Upsilon_1(2D) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +0.80600 g g PYTHIA 91; +Enddecay + +Decay chi_b2(3P) +#see Kwong and Rosner, PRD 38,279 (1988) +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.08700 gamma Upsilon(3S) PHSP; +0.00000 gamma Upsilon(2S) PHSP; +0.00000 gamma Upsilon PHSP; +#0.08700 gamma Upsilon(3S) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +#0.00000 gamma Upsilon(2S) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +#0.00000 gamma Upsilon HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +# spin 3 not yet in HELAMP +0.02200 Upsilon_3(2D) gamma PHSP; +# T -> gamma 3 Partial wave (L,S)=(0,2) +#0.02200 gamma Upsilon_3(2D) HELAMP 3.8729833 0. 3.1622777 0. +# 2.4494897 0. 1.7320508. 0. 1. 0. +# 1. 0. 1.7320508 0. 2.4494897 0. +# 3.1622777 0. 3.8729833 0.; +# T -> gamma T Partial wave (L,S)=(0,2) +0.00400 gamma Upsilon_2(2D) PHSP; +#0.00400 gamma Upsilon_2(2D) HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) +0.00040 gamma Upsilon_1(2D) PHSP; +#0.00040 gamma Upsilon_1(2D) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.88660 g g PYTHIA 91; +Enddecay + +Decay Upsilon_1(1D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00140 Upsilon pi+ pi- PHSP; +0.00070 Upsilon pi0 pi0 PHSP; +# V-> gamma S Partial wave (L,S)=(0,1) +0.60200 gamma chi_b0 HELAMP 1. 0. +1. 0.; +# V-> gamma V Partial wave (L,S)=(0,1) +0.31800 gamma chi_b1 HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.02600 gamma chi_b2 HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +0.05190 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_2(1D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00140 Upsilon pi+ pi- PHSP; +0.00070 Upsilon pi0 pi0 PHSP; +# T-> gamma T Partial wave (L,S)=(0,2) +0.20300 gamma chi_b2 PHSP; +#0.20300 gamma chi_b2 HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.78500 gamma chi_b1 PHSP; +#0.78500 gamma chi_b1 HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.00990 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_3(1D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00200 Upsilon pi+ pi- PHSP; +0.00100 Upsilon pi0 pi0 PHSP; +0.95400 chi_b2 gamma PHSP; +0.04300 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_1(2D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00000 Upsilon pi+ pi- PHSP; +0.00000 Upsilon pi0 pi0 PHSP; +0.00000 Upsilon(2S) pi+ pi- PHSP; +0.00000 Upsilon(2S) pi0 pi0 PHSP; +# V-> gamma S Partial wave (L,S)=(0,1) +0.51000 gamma chi_b0(2P) HELAMP 1. 0. +1. 0.; +# V-> gamma V Partial wave (L,S)=(0,1) +0.26000 gamma chi_b1(2P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.01400 gamma chi_b2(2P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +0.21600 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_2(2D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00000 Upsilon pi+ pi- PHSP; +0.00000 Upsilon pi0 pi0 PHSP; +0.00000 Upsilon(2S) pi+ pi- PHSP; +0.00000 Upsilon(2S) pi0 pi0 PHSP; +# T-> gamma T Partial wave (L,S)=(0,2) +0.04000 gamma chi_b2(2P) PHSP; +#0.04000 gamma chi_b2(2P) HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.13000 gamma chi_b1(2P) PHSP; +#0.13000 gamma chi_b1(2P) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.83000 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_3(2D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00000 Upsilon pi+ pi- PHSP; +0.00000 Upsilon pi0 pi0 PHSP; +0.00000 Upsilon(2S) pi+ pi- PHSP; +0.00000 Upsilon(2S) pi0 pi0 PHSP; +0.72000 chi_b2(2P) gamma PHSP; +0.28000 g g g PYTHIA 92; +Enddecay + +Decay h_b(2P) +1.00000 g g PYTHIA 91; +Enddecay +Decay h_b(3P) +1.00000 g g PYTHIA 91; +Enddecay +Decay eta_b2(1D) +1.00000 g g PYTHIA 91; +Enddecay +Decay eta_b2(2D) +1.00000 g g PYTHIA 91; +Enddecay +# +# Charm Baryons +# +Decay Lambda_c+ +0.021000000 e+ nu_e Lambda0 PYTHIA 22; +0.00500 e+ nu_e Sigma0 PYTHIA 22; +0.00500 e+ nu_e Sigma*0 PYTHIA 22; +0.00300 e+ nu_e n0 PYTHIA 22; +0.00200 e+ nu_e Delta0 PYTHIA 22; +0.00600 e+ nu_e p+ pi- PYTHIA 22; +0.00600 e+ nu_e n0 pi0 PYTHIA 22; +0.020000000 mu+ nu_mu Lambda0 PYTHIA 22; +0.00500 mu+ nu_mu Sigma0 PYTHIA 22; +0.00500 mu+ nu_mu Sigma*0 PYTHIA 22; +0.00300 mu+ nu_mu n0 PYTHIA 22; +0.00200 mu+ nu_mu Delta0 PYTHIA 22; +0.00600 mu+ nu_mu p+ pi- PYTHIA 22; +0.00600 mu+ nu_mu n0 pi0 PYTHIA 22; +0.008600000 Delta++ K- PYTHIA 0; +0.02500 Delta++ K*- PYTHIA 0; +0.023000000 p+ anti-K0 PYTHIA 0; +0.016000000 p+ anti-K*0 PYTHIA 0; +0.00500 Delta+ anti-K0 PYTHIA 0; +0.00500 Delta+ anti-K*0 PYTHIA 0; +0.010700000 Lambda0 pi+ PYTHIA 0; +0.00500 Lambda0 rho+ PYTHIA 0; +0.010500000 Sigma0 pi+ PYTHIA 0; +0.00400 Sigma0 rho+ PYTHIA 0; +0.00400 Sigma*0 pi+ PYTHIA 0; +0.00400 Sigma*0 rho+ PYTHIA 0; +0.010000000 Sigma+ pi0 PYTHIA 0; +0.005500000 Sigma+ eta PYTHIA 0; +0.00200 Sigma+ eta' PYTHIA 0; +0.00400 Sigma+ rho0 PYTHIA 0; +0.027000000 Sigma+ omega PYTHIA 0; +0.00300 Sigma*+ pi0 PYTHIA 0; +0.008500000 Sigma*+ eta PYTHIA 0; +0.00300 Sigma*+ rho0 PYTHIA 0; +0.00300 Sigma*+ omega PYTHIA 0; +0.003900000 Xi0 K+ PYTHIA 0; +0.00200 Xi0 K*+ PYTHIA 0; +0.002600000 Xi*0 K+ PYTHIA 0; +0.00100 Delta++ pi- PYTHIA 0; +0.00100 Delta++ rho- PYTHIA 0; +0.00200 p+ pi0 PYTHIA 0; +0.00100 p+ eta PYTHIA 0; +0.00100 p+ eta' PYTHIA 0; +0.00200 p+ rho0 PYTHIA 0; +0.00200 p+ omega PYTHIA 0; +0.000820000 p+ phi PYTHIA 0; +0.002800000 p+ f_0 PYTHIA 0; +0.00100 Delta+ pi0 PYTHIA 0; +0.00100 Delta+ eta PYTHIA 0; +0.00100 Delta+ eta' PYTHIA 0; +0.00100 Delta+ rho0 PYTHIA 0; +0.00100 Delta+ omega PYTHIA 0; +0.00300 n0 pi+ PYTHIA 0; +0.00300 n0 rho+ PYTHIA 0; +0.00300 Delta0 pi+ PYTHIA 0; +0.00300 Delta0 rho+ PYTHIA 0; +0.00500 Lambda0 K+ PYTHIA 0; +0.00500 Lambda0 K*+ PYTHIA 0; +0.00200 Sigma0 K+ PYTHIA 0; +0.00200 Sigma0 K*+ PYTHIA 0; +0.00100 Sigma*0 K+ PYTHIA 0; +0.00100 Sigma*0 K*+ PYTHIA 0; +0.00200 Sigma+ K0 PYTHIA 0; +0.002800000 Sigma+ K*0 PYTHIA 0; +0.00100 Sigma*+ K0 PYTHIA 0; +0.00100 Sigma*+ K*0 PYTHIA 0; +0.064094509 u anti-d d su_0 PYTHIA 43; +0.028102977 u anti-d d su_1 PYTHIA 43; +0.017256214 u anti-s d su_0 PYTHIA 43; +0.017256214 u anti-d d ud_0 PYTHIA 43; +0.046838295 s uu_1 PYTHIA 43; +0.069024855 u su_0 PYTHIA 43; +0.069024855 u su_1 PYTHIA 43; +0.014791040 d uu_1 PYTHIA 43; +0.007395520 u ud_0 PYTHIA 43; +0.007395520 u ud_1 PYTHIA 43; +0.025400000 p+ K- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.033000000 p+ anti-K0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.012000000 p+ anti-K0 eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.026000000 p+ anti-K0 pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.023000000 p+ K- pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011000000 p+ K*- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001100000 p+ K- pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.008000000 p+ K- pi+ pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000700000 p+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 p+ pi+ pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 p+ K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.036000000 Lambda0 pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.015000000 Lambda0 pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011000000 Lambda0 pi+ rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 Lambda0 pi+ pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.009500000 Lambda0 pi+ eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.012000000 Lambda0 pi+ omega PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004700000 Lambda0 K+ anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.036000000 Sigma+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.017000000 Sigma- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.018000000 Sigma0 pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.008300000 Sigma0 pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 Sigma+ K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.003100000 Sigma+ phi PHSP; #[New mode added] #[Reconstructed PDG2011] +0.002500000 Xi- K+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 Sigma+ K+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +CDecay anti-Lambda_c- +# +Decay Xi_c0 +1.000 PYTHIA 42; +Enddecay +Decay anti-Xi_c0 +1.000 PYTHIA 42; +Enddecay +# +Decay c-hadron +0.08000 e+ nu_e s specflav PYTHIA 22; +0.08000 mu+ nu_mu s specflav PYTHIA 22; +0.76000 u anti-d s specflav PYTHIA 42; +0.08000 u anti-s s specflav PYTHIA 42; +Enddecay +CDecay anti-c-hadron +# +Decay Sigma_c0 +1.0000 Lambda_c+ pi- PHSP; +Enddecay +Decay anti-Sigma_c0 +1.0000 anti-Lambda_c- pi+ PHSP; +Enddecay +# +Decay Sigma_c+ +1.0000 Lambda_c+ pi0 PHSP; +Enddecay +Decay anti-Sigma_c- +1.0000 anti-Lambda_c- pi0 PHSP; +Enddecay +# +Decay Xi_c+ +0.079535513 PYTHIA 42; +0.079535513 Sigma*+ anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.025689971 Lambda0 K- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.010339617 Sigma+ K- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.064423765 Sigma+ anti-K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.023065299 Sigma0 K- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.043744532 Xi0 pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.079535513 Xi- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.186113099 Xi0 pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.138391792 Xi0 pi- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.182931679 Xi0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.005567486 Omega- K+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.007158196 p+ K- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.009544262 p+ anti-K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.038177046 Sigma+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.014316392 Sigma- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011930327 Sigma+ K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Xi_c- +0.079535513 PYTHIA 42; +0.079535513 anti-Sigma*- K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.025689971 anti-Lambda0 K+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.010339617 anti-Sigma- K+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.064423765 anti-Sigma- K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.023065299 anti-Sigma0 K+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.043744532 anti-Xi0 pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.079535513 anti-Xi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.186113099 anti-Xi0 pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.138391792 anti-Xi0 pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.182931679 anti-Xi0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.005567486 anti-Omega+ K- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.007158196 anti-p- K+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.009544262 anti-p- K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.038177046 anti-Sigma- pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.014316392 anti-Sigma+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011930327 anti-Sigma- K- K+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Sigma_c++ +1.0000 Lambda_c+ pi+ PHSP; +Enddecay +Decay anti-Sigma_c-- +1.0000 anti-Lambda_c- pi- PHSP; +Enddecay +# +Decay Xi'_c+ +0.1000 Lambda0 K- pi+ pi+ PHSP; +0.0800 Sigma0 K- pi+ pi+ PHSP; +0.8200 gamma Xi_c+ PHSP; +Enddecay +Decay anti-Xi'_c- +0.1000 anti-Lambda0 K+ pi- pi- PHSP; +0.0800 anti-Sigma0 K+ pi- pi- PHSP; +0.8200 gamma anti-Xi_c- PHSP; +Enddecay +# +Decay Xi'_c0 +1.0000 gamma Xi_c0 PHSP; +Enddecay +Decay anti-Xi'_c0 +1.0000 gamma anti-Xi_c0 PHSP; +Enddecay +# +# Light Baryons +# Lambda0 updated Feb 2009 +Decay Lambda0 +0.638719992 p+ pi- PHSP; #[Reconstructed PDG2011] +0.357719992 n0 pi0 PHSP; #[Reconstructed PDG2011] +0.001741600 n0 gamma PHSP; #[Reconstructed PDG2011] +0.000832160 p+ pi- gamma PHSP; #[Reconstructed PDG2011] +0.000831216 p+ e- anti-nu_e PHOTOS PHSP; #[Reconstructed PDG2011] +0.000155040 p+ mu- anti-nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay anti-Lambda0 +0.638719992 anti-p- pi+ PHSP; #[Reconstructed PDG2011] +0.357719992 anti-n0 pi0 PHSP; #[Reconstructed PDG2011] +0.001741600 anti-n0 gamma PHSP; #[Reconstructed PDG2011] +0.000832160 anti-p- pi+ gamma PHSP; #[Reconstructed PDG2011] +0.000831216 anti-p- e+ nu_e PHOTOS PHSP; #[Reconstructed PDG2011] +0.000155040 anti-p- mu+ nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay Lambda(1405)0 +0.3333 Sigma+ pi- PHSP; +0.3333 Sigma- pi+ PHSP; +0.3333 Sigma0 pi0 PHSP; +Enddecay +# +Decay anti-Lambda(1405)0 +0.3333 anti-Sigma+ pi- PHSP; +0.3333 anti-Sigma- pi+ PHSP; +0.3333 anti-Sigma0 pi0 PHSP; +Enddecay +# +Decay Lambda(1520)0 +0.23 p+ K- PHSP; +0.23 n0 anti-K0 PHSP; +0.14 Sigma+ pi- PHSP; +0.14 Sigma- pi+ PHSP; +0.14 Sigma0 pi0 PHSP; +0.0333 Lambda0 pi0 pi0 PHSP; +0.0667 Lambda0 pi+ pi- PHSP; +0.003 Sigma+ pi- pi0 PHSP; +0.003 Sigma- pi+ pi0 PHSP; +0.001 Sigma0 pi0 pi0 PHSP; +0.002 Sigma0 pi+ pi- PHSP; +0.011 Lambda0 gamma PHSP; +Enddecay +# +Decay anti-Lambda(1520)0 +0.23 anti-p- K+ PHSP; +0.23 anti-n0 K0 PHSP; +0.14 anti-Sigma- pi+ PHSP; +0.14 anti-Sigma+ pi- PHSP; +0.14 anti-Sigma0 pi0 PHSP; +0.0333 anti-Lambda0 pi0 pi0 PHSP; +0.0667 anti-Lambda0 pi+ pi- PHSP; +0.003 anti-Sigma+ pi- pi0 PHSP; +0.003 anti-Sigma- pi+ pi0 PHSP; +0.001 anti-Sigma0 pi0 pi0 PHSP; +0.002 anti-Sigma0 pi+ pi- PHSP; +0.011 anti-Lambda0 gamma PHSP; +Enddecay +# +Decay Lambda(1600)0 +0.176 p+ K- PHSP; +0.176 n0 anti-K0 PHSP; +0.216 Sigma+ pi- PHSP; +0.216 Sigma- pi+ PHSP; +0.216 Sigma0 pi0 PHSP; +Enddecay +# +Decay anti-Lambda(1600)0 +0.176 anti-p- K+ PHSP; +0.176 anti-n0 K0 PHSP; +0.216 anti-Sigma+ pi- PHSP; +0.216 anti-Sigma- pi+ PHSP; +0.216 anti-Sigma0 pi0 PHSP; +Enddecay +# +Decay Lambda(1670)0 +0.10 p+ K- PHSP; +0.10 n0 anti-K0 PHSP; +0.16 Sigma+ pi- PHSP; +0.16 Sigma- pi+ PHSP; +0.16 Sigma0 pi0 PHSP; +0.32 Lambda0 eta PHSP; +Enddecay +# +Decay anti-Lambda(1670)0 +0.10 anti-p- K+ PHSP; +0.10 anti-n0 K0 PHSP; +0.16 anti-Sigma+ pi- PHSP; +0.16 anti-Sigma- pi+ PHSP; +0.16 anti-Sigma0 pi0 PHSP; +0.32 anti-Lambda0 eta PHSP; +Enddecay +# +Decay Lambda(1690)0 +0.125 p+ K- PHSP; +0.125 n0 anti-K0 PHSP; +0.10 Sigma+ pi- PHSP; +0.10 Sigma- pi+ PHSP; +0.10 Sigma0 pi0 PHSP; +0.0833 Lambda0 pi0 pi0 PHSP; +0.1667 Lambda0 pi+ pi- PHSP; +0.067 Sigma+ pi- pi0 PHSP; +0.067 Sigma- pi+ pi0 PHSP; +0.022 Sigma0 pi0 pi0 PHSP; +0.044 Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay anti-Lambda(1690)0 +0.125 anti-p- K+ PHSP; +0.125 anti-n0 K0 PHSP; +0.10 anti-Sigma+ pi- PHSP; +0.10 anti-Sigma- pi+ PHSP; +0.10 anti-Sigma0 pi0 PHSP; +0.0833 anti-Lambda0 pi0 pi0 PHSP; +0.1667 anti-Lambda0 pi+ pi- PHSP; +0.067 anti-Sigma+ pi- pi0 PHSP; +0.067 anti-Sigma- pi+ pi0 PHSP; +0.022 anti-Sigma0 pi0 pi0 PHSP; +0.044 anti-Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay Lambda(1800)0 +0.165 p+ K- PHSP; +0.165 n0 anti-K0 PHSP; +0.08 Sigma+ pi- PHSP; +0.08 Sigma- pi+ PHSP; +0.08 Sigma0 pi0 PHSP; +0.003 Sigma*+ pi- PHSP; +0.003 Sigma*- pi+ PHSP; +0.004 Sigma*0 pi0 PHSP; +0.21 p+ K*- PHSP; +0.21 n0 anti-K*0 PHSP; +Enddecay +# +Decay anti-Lambda(1800)0 +0.165 anti-p- K+ PHSP; +0.165 anti-n0 K0 PHSP; +0.08 anti-Sigma+ pi- PHSP; +0.08 anti-Sigma- pi+ PHSP; +0.08 anti-Sigma0 pi0 PHSP; +0.003 anti-Sigma*+ pi- PHSP; +0.003 anti-Sigma*- pi+ PHSP; +0.004 anti-Sigma*0 pi0 PHSP; +0.21 anti-p- K*+ PHSP; +0.21 anti-n0 K*0 PHSP; +Enddecay +# +Decay Lambda(1810)0 +0.165 p+ K- PHSP; +0.165 n0 anti-K0 PHSP; +0.08 Sigma+ pi- PHSP; +0.08 Sigma- pi+ PHSP; +0.08 Sigma0 pi0 PHSP; +0.003 Sigma*+ pi- PHSP; +0.003 Sigma*- pi+ PHSP; +0.004 Sigma*0 pi0 PHSP; +0.21 p+ K*- PHSP; +0.21 n0 anti-K*0 PHSP; +Enddecay +# +Decay anti-Lambda(1810)0 +0.165 anti-p- K+ PHSP; +0.165 anti-n0 K0 PHSP; +0.08 anti-Sigma+ pi- PHSP; +0.08 anti-Sigma- pi+ PHSP; +0.08 anti-Sigma0 pi0 PHSP; +0.003 anti-Sigma*+ pi- PHSP; +0.003 anti-Sigma*- pi+ PHSP; +0.004 anti-Sigma*0 pi0 PHSP; +0.21 anti-p- K*+ PHSP; +0.21 anti-n0 K*0 PHSP; +Enddecay +# +Decay Lambda(1820)0 +0.34 p+ K- PHSP; +0.34 n0 anti-K0 PHSP; +0.06 Sigma+ pi- PHSP; +0.06 Sigma- pi+ PHSP; +0.06 Sigma0 pi0 PHSP; +0.04 Sigma*+ pi- PHSP; +0.04 Sigma*- pi+ PHSP; +0.04 Sigma*0 pi0 PHSP; +0.01 Lambda0 eta PHSP; +0.003 Sigma+ pi- pi0 PHSP; +0.004 Sigma- pi+ pi0 PHSP; +0.001 Sigma0 pi0 pi0 PHSP; +0.002 Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay anti-Lambda(1820)0 +0.34 anti-p- K+ PHSP; +0.34 anti-n0 K0 PHSP; +0.06 anti-Sigma+ pi- PHSP; +0.06 anti-Sigma- pi+ PHSP; +0.06 anti-Sigma0 pi0 PHSP; +0.04 anti-Sigma*+ pi- PHSP; +0.04 anti-Sigma*- pi+ PHSP; +0.04 anti-Sigma*0 pi0 PHSP; +0.01 anti-Lambda0 eta PHSP; +0.003 anti-Sigma+ pi- pi0 PHSP; +0.004 anti-Sigma- pi+ pi0 PHSP; +0.001 anti-Sigma0 pi0 pi0 PHSP; +0.002 anti-Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay Lambda(1830)0 +0.05 p+ K- PHSP; +0.05 n0 anti-K0 PHSP; +0.24 Sigma+ pi- PHSP; +0.24 Sigma- pi+ PHSP; +0.24 Sigma0 pi0 PHSP; +0.06 Sigma*+ pi- PHSP; +0.06 Sigma*- pi+ PHSP; +0.06 Sigma*0 pi0 PHSP; +Enddecay +# +Decay anti-Lambda(1830)0 +0.05 anti-p- K+ PHSP; +0.05 anti-n0 K0 PHSP; +0.24 anti-Sigma+ pi- PHSP; +0.24 anti-Sigma- pi+ PHSP; +0.24 anti-Sigma0 pi0 PHSP; +0.06 anti-Sigma*+ pi- PHSP; +0.06 anti-Sigma*- pi+ PHSP; +0.06 anti-Sigma*0 pi0 PHSP; +Enddecay +# +# +Decay Sigma(1660)0 +0.07 p+ K- PHSP; +0.07 n0 anti-K0 PHSP; +0.16 Lambda0 pi0 PHSP; +0.35 Sigma+ pi- PHSP; +0.35 Sigma- pi+ PHSP; +Enddecay +# +Decay anti-Sigma(1660)0 +0.07 anti-p- K+ PHSP; +0.07 anti-n0 K0 PHSP; +0.16 anti-Lambda0 pi0 PHSP; +0.35 anti-Sigma+ pi- PHSP; +0.35 anti-Sigma- pi+ PHSP; +Enddecay +# +Decay Sigma(1670)0 +0.07 p+ K- PHSP; +0.07 n0 anti-K0 PHSP; +0.16 Lambda0 pi0 PHSP; +0.35 Sigma+ pi- PHSP; +0.35 Sigma- pi+ PHSP; +Enddecay +# +Decay anti-Sigma(1670)0 +0.07 anti-p- K+ PHSP; +0.07 anti-n0 K0 PHSP; +0.16 anti-Lambda0 pi0 PHSP; +0.35 anti-Sigma+ pi- PHSP; +0.35 anti-Sigma- pi+ PHSP; +Enddecay +# +Decay Sigma(1775)0 +0.215 p+ K- PHSP; +0.215 n0 anti-K0 PHSP; +0.20 Lambda0 pi0 PHSP; +0.02 Sigma+ pi- PHSP; +0.02 Sigma- pi+ PHSP; +0.055 Sigma*+ pi- PHSP; +0.055 Sigma*- pi+ PHSP; +0.22 Lambda(1520)0 pi0 PHSP; +Enddecay +# +Decay anti-Sigma(1775)0 +0.215 anti-p- K+ PHSP; +0.215 anti-n0 K0 PHSP; +0.20 anti-Lambda0 pi0 PHSP; +0.02 anti-Sigma+ pi- PHSP; +0.02 anti-Sigma- pi+ PHSP; +0.055 anti-Sigma*+ pi- PHSP; +0.055 anti-Sigma*- pi+ PHSP; +0.22 anti-Lambda(1520)0 pi0 PHSP; +Enddecay +Decay Sigma+ +0.515454300 p+ pi0 PHSP; #[Reconstructed PDG2011] +0.482854300 n0 pi+ PHSP; #[Reconstructed PDG2011] +0.001225905 p+ gamma PHSP; #[Reconstructed PDG2011] +0.000445905 n0 pi+ gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000019590 Lambda0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Sigma- +0.515454300 anti-p- pi0 PHSP; #[Reconstructed PDG2011] +0.482854300 anti-n0 pi- PHSP; #[Reconstructed PDG2011] +0.001225905 anti-p- gamma PHSP; #[Reconstructed PDG2011] +0.000445905 anti-n0 pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000019590 anti-Lambda0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Delta+ +0.6630 p+ pi0 PHSP; +0.3310 n0 pi+ PHSP; +0.0060 p+ gamma PHSP; +Enddecay +Decay anti-Delta- +0.6630 anti-p- pi0 PHSP; +0.3310 anti-n0 pi- PHSP; +0.0060 anti-p- gamma PHSP; +Enddecay +# +Decay Delta++ +1.0000 p+ pi+ PHSP; +Enddecay +Decay anti-Delta-- +1.0000 anti-p- pi- PHSP; +Enddecay +# +Decay Xi*0 +0.3330 Xi0 pi0 PHSP; +0.6670 Xi- pi+ PHSP; +Enddecay +Decay anti-Xi*0 +0.3330 anti-Xi0 pi0 PHSP; +0.6670 anti-Xi+ pi- PHSP; +Enddecay +# +Decay Delta0 +0.3310 p+ pi- PHSP; +0.6630 n0 pi0 PHSP; +0.0060 n0 gamma PHSP; +Enddecay +Decay anti-Delta0 +0.3310 anti-p- pi+ PHSP; +0.6630 anti-n0 pi0 PHSP; +0.0060 anti-n0 gamma PHSP; +Enddecay +# +Decay Delta- +1.0000 n0 pi- PHSP; +Enddecay +Decay anti-Delta+ +1.0000 anti-n0 pi+ PHSP; +Enddecay +# +Decay Sigma- +0.998015700 n0 pi- PHSP; #[Reconstructed PDG2011] +0.000460000 n0 pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001017000 n0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 n0 mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000057300 Lambda0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Sigma+ +0.998015700 anti-n0 pi+ PHSP; #[Reconstructed PDG2011] +0.000460000 anti-n0 pi+ gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001017000 anti-n0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 anti-n0 mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000057300 anti-Lambda0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Sigma0 +0.995024876 gamma Lambda0 PHSP; #[Reconstructed PDG2011] +0.004975124 Lambda0 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Sigma0 +0.995024876 gamma anti-Lambda0 PHSP; #[Reconstructed PDG2011] +0.004975124 anti-Lambda0 e- e+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Sigma*- +0.8800 Lambda0 pi- PHSP; +0.0600 Sigma0 pi- PHSP; +0.0600 Sigma- pi0 PHSP; +Enddecay +Decay anti-Sigma*+ +0.8800 anti-Lambda0 pi+ PHSP; +0.0600 anti-Sigma0 pi+ PHSP; +0.0600 anti-Sigma+ pi0 PHSP; +Enddecay +# +Decay Sigma*+ +0.8800 Lambda0 pi+ PHSP; +0.0600 Sigma+ pi0 PHSP; +0.0600 Sigma0 pi+ PHSP; +Enddecay +Decay anti-Sigma*- +0.8800 anti-Lambda0 pi- PHSP; +0.0600 anti-Sigma- pi0 PHSP; +0.0600 anti-Sigma0 pi- PHSP; +Enddecay +# +Decay Sigma*0 +0.8800 Lambda0 pi0 PHSP; +0.0600 Sigma+ pi- PHSP; +0.0600 Sigma- pi+ PHSP; +Enddecay +Decay anti-Sigma*0 +0.8800 anti-Lambda0 pi0 PHSP; +0.0600 anti-Sigma- pi+ PHSP; +0.0600 anti-Sigma+ pi- PHSP; +Enddecay +# +Decay Xi0 +0.995242400 Lambda0 pi0 PHSP; #[Reconstructed PDG2011] +0.001162400 Lambda0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000007600 Lambda0 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.003330000 Sigma0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000253000 Sigma+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000004600 Sigma+ mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Xi0 +0.995242400 anti-Lambda0 pi0 PHSP; #[Reconstructed PDG2011] +0.001162400 anti-Lambda0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000007600 anti-Lambda0 e- e+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.003330000 anti-Sigma0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000253000 anti-Sigma- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000004600 anti-Sigma- mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Xi- +0.998870000 Lambda0 pi- PHSP; #[Reconstructed PDG2011] +0.000127000 Sigma- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000563000 Lambda0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 Lambda0 mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000087000 Sigma0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Xi+ +0.998870000 anti-Lambda0 pi+ PHSP; #[Reconstructed PDG2011] +0.000127000 anti-Sigma+ gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000563000 anti-Lambda0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 anti-Lambda0 mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000087000 anti-Sigma0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Xi*- +0.6670 Xi0 pi- PHSP; +0.3330 Xi- pi0 PHSP; +Enddecay +Decay anti-Xi*+ +0.6670 anti-Xi0 pi+ PHSP; +0.3330 anti-Xi+ pi0 PHSP; +Enddecay +# +Decay Omega- +0.675949296 Lambda0 K- PHSP; #[Reconstructed PDG2011] +0.233949296 Xi0 pi- PHSP; #[Reconstructed PDG2011] +0.084828169 Xi- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 Xi- pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000493521 Xi*0 pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004779718 Xi0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Omega+ +0.675949296 anti-Lambda0 K+ PHSP; #[Reconstructed PDG2011] +0.233949296 anti-Xi0 pi+ PHSP; #[Reconstructed PDG2011] +0.084828169 anti-Xi+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-Xi+ pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000493521 anti-Xi*0 pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004779718 anti-Xi0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# +Decay Sigma_c*0 +1.0000 Lambda_c+ pi- PHSP; +Enddecay +CDecay anti-Sigma_c*0 +# +Decay Sigma_c*+ +1.0000 Lambda_c+ pi0 PHSP; +Enddecay +CDecay anti-Sigma_c*- +# +Decay Sigma_c*++ +1.0000 Lambda_c+ pi+ PHSP; +Enddecay +CDecay anti-Sigma_c*-- +# +Decay Xi_c*0 +0.5000 Xi_c0 pi0 PHSP; +0.5000 Xi_c0 gamma PHSP; +Enddecay +CDecay anti-Xi_c*0 +# +Decay Xi_c*+ +0.5000 Xi_c+ pi0 PHSP; +0.5000 Xi_c+ gamma PHSP; +Enddecay +CDecay anti-Xi_c*- +# +Decay Omega_c0 +1.00000 PYTHIA 42; +Enddecay +# +CDecay anti-Omega_c0 +# +Decay Omega_c*0 +1.0000 Omega_c0 gamma PHSP; +Enddecay +# +CDecay anti-Omega_c*0 +# +Decay Xu0 +# X_u^0 -> u anti-u +# +1.0 u anti-u PYTHIA 42; +Enddecay +Decay Xu+ +# X_u^+ -> u anti-d +# +1.0 u anti-d PYTHIA 42; +Enddecay +CDecay Xu- + +#lange - PYTHIA is making h_c mesons - better add a decay +# channel for them. +Decay h_c +0.01 J/psi pi0 PHSP; +0.5 eta_c gamma PHSP; +0.49 rndmflav anti-rndmflav PYTHIA 42; +Enddecay + +# 12/08/03 RJT Update b-baryon decays... +# chi_c or psi(2S) BR to J/psi are included below + +Decay Lambda_b0 +# add from PDG 2026 + 0.00032 J/psi p+ K- PHSP; + 0.000026 J/psi p+ pi- PHSP; + 0.000000454 psi(2S) p+ pi- PHSP; + 0.00000454 psi(2S) p+ K- PHSP; + 0.00000258 chi_c1 p+ K- PHSP; + 0.000000175 chi_c1 p+ pi- PHSP; + 0.00000156 chi_c2 p+ K- PHSP; + 0.0000000937 chi_c2 p+ pi- PHSP; +Enddecay + +Decay anti-Lambda_b0 +# add from PDG 2026; + 0.00032 J/psi anti-p- K+ PHSP; + 0.000026 J/psi anti-p- pi+ PHSP; + 0.000000454 psi(2S) anti-p- pi+ PHSP; + 0.00000454 psi(2S) anti-p- K+ PHSP; + 0.00000258 chi_c1 anti-p- K+ PHSP; + 0.000000175 chi_c1 anti-p- pi+ PHSP; + 0.00000156 chi_c2 anti-p- K+ PHSP; + 0.0000000937 chi_c2 anti-p- pi+ PHSP; +Enddecay + +Decay Xi_b- +# SemiLeptonic Decays + 0.05460 Xi_c0 e- anti-nu_e PHSP; + 0.05460 Xi_c0 mu- anti-nu_mu PHSP; + 0.02000 Xi_c0 tau- anti-nu_tau PHSP; +# Hadronic Decays with Xi_c0 + 0.00600 Xi_c0 pi- PHSP; + 0.02200 Xi_c0 pi- pi+ pi- PHSP; + 0.00055 Xi_c0 K- PHSP; + 0.02200 Xi_c0 D_s- PHSP; + 0.00047 Xi- J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00038 Xi- psi(2S) PHSP; + 0.00018 D0 Lambda0 pi- PHSP; + 0.00020 Sigma_c0 K- PHSP; + 0.00020 Omega_c0 K- PHSP; +# +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.38757 d anti-u d cs_0 PYTHIA 43; +0.16995 d anti-u d cs_1 PYTHIA 43; +0.06335 s anti-u d cs_0 PYTHIA 43; +0.00568 d anti-u s cs_1 PYTHIA 43; +0.00797 d anti-u s cs_0 PYTHIA 43; +0.06148 s anti-c d cs_0 PYTHIA 43; +0.06918 d anti-u d cd_0 PYTHIA 43; +0.03999 s anti-c d cd_0 PYTHIA 43; +0.00865 d anti-u d su_0 PYTHIA 43; +0.00500 s anti-c d su_0 PYTHIA 43; +Enddecay + +Decay anti-Xi_b+ +# SemiLeptonic Decays + 0.05460 anti-Xi_c0 e+ nu_e PHSP; + 0.05460 anti-Xi_c0 mu+ nu_mu PHSP; + 0.02000 anti-Xi_c0 tau+ nu_tau PHSP; +# Hadronic Decays with anti-Xi_c0 + 0.00600 anti-Xi_c0 pi+ PHSP; + 0.02200 anti-Xi_c0 pi+ pi+ pi- PHSP; + 0.00055 anti-Xi_c0 K+ PHSP; + 0.02200 anti-Xi_c0 D_s+ PHSP; + 0.00047 anti-Xi+ J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00038 anti-Xi+ psi(2S) PHSP; + 0.00018 anti-D0 anti-Lambda0 pi+ PHSP; + 0.00020 anti-Sigma_c0 K+ PHSP; + 0.00020 anti-Omega_c0 K+ PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.38757 u anti-d anti-d anti-cs_0 PYTHIA 43; +0.16995 u anti-d anti-d anti-cs_1 PYTHIA 43; +0.06335 u anti-s anti-d anti-cs_0 PYTHIA 43; +0.00568 u anti-d anti-s anti-cs_1 PYTHIA 43; +0.00797 u anti-d anti-s anti-cs_0 PYTHIA 43; +0.06148 c anti-s anti-d anti-cs_0 PYTHIA 43; +0.06918 u anti-d anti-d anti-cd_0 PYTHIA 43; +0.03999 c anti-s anti-d anti-cd_0 PYTHIA 43; +0.00865 u anti-d anti-d anti-su_0 PYTHIA 43; +0.00500 c anti-s anti-d anti-su_0 PYTHIA 43; +Enddecay + +Decay Xi_b0 +# SemiLeptonic Decays + 0.05460 Xi_c+ e- anti-nu_e PHSP; + 0.05460 Xi_c+ mu- anti-nu_mu PHSP; + 0.02000 Xi_c+ tau- anti-nu_tau PHSP; +# Hadronic Decays with Xi_c+ + 0.00600 Xi_c+ pi- PHSP; + 0.02200 Xi_c+ pi- pi+ pi- PHSP; + 0.00055 Xi_c+ K- PHSP; + 0.02200 Xi_c+ D_s- PHSP; + 0.00047 Xi0 J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00020 D0 Lambda0 PHSP; + 0.00010 Lambda_c+ K- PHSP; + 0.00020 Sigma_c0 anti-K0 PHSP; + 0.00020 Omega_c0 K0 PHSP; +# +# Additional decays from hep-ph/9709372 scaled to the Lambda_c0 pi rate + 0.00020 Xi'_c+ pi- PHSP; + 0.00003 Xi_c0 pi0 PHSP; + 0.00015 Xi_c0 eta PHSP; + 0.00004 Xi_c0 eta' PHSP; + 0.00020 Xi'_c0 pi0 PHSP; + 0.00020 Xi'_c0 eta PHSP; + 0.00030 Xi'_c0 eta' PHSP; + 0.00040 Sigma_c+ K- PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.58591 d anti-u s cu_0 PYTHIA 43; +0.01363 s anti-u s cu_1 PYTHIA 43; +0.09539 s anti-u s cc_1 PYTHIA 43; +0.10900 s anti-u d cu_1 PYTHIA 43; +0.01363 d anti-u d uu_1 PYTHIA 43; +Enddecay + +Decay anti-Xi_b0 + 0.05460 anti-Xi_c- e+ nu_e PHSP; + 0.05460 anti-Xi_c- mu+ nu_mu PHSP; + 0.02000 anti-Xi_c- tau+ nu_tau PHSP; +# Hadronic Decays with anti-Xi_c- + 0.00600 anti-Xi_c- pi+ PHSP; + 0.02200 anti-Xi_c- pi+ pi+ pi- PHSP; + 0.00055 anti-Xi_c- K+ PHSP; + 0.02200 anti-Xi_c- D_s+ PHSP; + 0.00047 anti-Xi0 J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00020 anti-D0 anti-Lambda0 PHSP; + 0.00010 anti-Lambda_c- K+ PHSP; + 0.00020 anti-Sigma_c0 K0 PHSP; + 0.00020 anti-Omega_c0 anti-K0 PHSP; +# +# Additional decays from hep-ph/9709372 scaled to the Lambda_c0 pi rate + 0.00020 anti-Xi'_c- pi+ PHSP; + 0.00003 anti-Xi_c0 pi0 PHSP; + 0.00015 anti-Xi_c0 eta PHSP; + 0.00004 anti-Xi_c0 eta' PHSP; + 0.00020 anti-Xi'_c0 pi0 PHSP; + 0.00020 anti-Xi'_c0 eta PHSP; + 0.00030 anti-Xi'_c0 eta' PHSP; + 0.00040 anti-Sigma_c- K+ PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.58591 u anti-d anti-s anti-cu_0 PYTHIA 43; +0.01363 u anti-s anti-s anti-cu_1 PYTHIA 43; +0.09539 u anti-s anti-s anti-cc_1 PYTHIA 43; +0.10900 u anti-s anti-d anti-cu_1 PYTHIA 43; +0.01363 u anti-d anti-d anti-uu_1 PYTHIA 43; +Enddecay + +# added by D.Litvintsev 12/8/03: +Decay Omega_b- +# SemiLeptonic Decays + 0.05460 Omega_c0 e- anti-nu_e PHSP; + 0.05460 Omega_c0 mu- anti-nu_mu PHSP; + 0.02000 Omega_c0 tau- anti-nu_tau PHSP; +# Hadronic Decays with Xi_c+ + 0.00600 Omega_c0 pi- PHSP; + 0.02200 Omega_c0 pi- pi+ pi- PHSP; + 0.00055 Omega_c0 K- PHSP; + 0.02200 Omega_c0 D_s- PHSP; + 0.0011 D0 Xi- PHSP; +# + 0.00047 Omega- J/psi PHSP; + 0.00038 Omega- psi(2S) PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.68192 d anti-u s cs_0 PYTHIA 43; +0.10910 d anti-u d cs_0 PYTHIA 43; +0.02728 d anti-u s su_0 PYTHIA 43; +Enddecay + +Decay anti-Omega_b+ +# SemiLeptonic Decays + 0.05460 anti-Omega_c0 e+ nu_e PHSP; + 0.05460 anti-Omega_c0 mu+ nu_mu PHSP; + 0.02000 anti-Omega_c0 tau+ nu_tau PHSP; +# Hadronic Decays with Xi_c+ + 0.00600 anti-Omega_c0 pi+ PHSP; + 0.02200 anti-Omega_c0 pi+ pi+ pi- PHSP; + 0.00055 anti-Omega_c0 K+ PHSP; + 0.02200 anti-Omega_c0 D_s+ PHSP; + 0.0011 anti-D0 anti-Xi+ PHSP; +# + 0.00047 anti-Omega+ J/psi PHSP; + 0.00038 anti-Omega+ psi(2S) PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.68192 u anti-d anti-s anti-cs_0 PYTHIA 43; +0.10910 u anti-d anti-d anti-cs_0 PYTHIA 43; +0.02728 u anti-d anti-s anti-su_0 PYTHIA 43; +Enddecay + + +Decay Sigma_b+ + 1.00000 Lambda_b0 pi+ PHSP; +Enddecay +Decay anti-Sigma_b- + 1.00000 anti-Lambda_b0 pi- PHSP; +Enddecay + +Decay Sigma_b- + 1.00000 Lambda_b0 pi- PHSP; +Enddecay +Decay anti-Sigma_b+ + 1.00000 anti-Lambda_b0 pi+ PHSP; +Enddecay + +Decay Sigma_b0 + 1.00000 Lambda_b0 gamma PHOTOS PHSP; +Enddecay +Decay anti-Sigma_b0 + 1.00000 anti-Lambda_b0 gamma PHOTOS PHSP; +Enddecay + + +# +# B_c Mesons +# + +Decay B_c- +0.01600 tau- anti-nu_tau SLN; +# +# SemiLeptonic Decays +0.01900 J/psi e- anti-nu_e PHOTOS PHSP; +0.00094 psi(2S) e- anti-nu_e PHOTOS PHSP; +0.00750 eta_c e- anti-nu_e PHOTOS PHSP; +0.00020 eta_c(2S) e- anti-nu_e PHOTOS PHSP; +0.00004 anti-D0 e- anti-nu_e PHOTOS PHSP; +0.00018 anti-D*0 e- anti-nu_e PHOTOS PHSP; +0.04030 anti-B_s0 e- anti-nu_e PHOTOS PHSP; +0.05060 anti-B_s*0 e- anti-nu_e PHOTOS PHSP; +0.00340 anti-B0 e- anti-nu_e PHOTOS PHSP; +0.00580 anti-B*0 e- anti-nu_e PHOTOS PHSP; +# +0.01900 J/psi mu- anti-nu_mu PHOTOS PHSP; +0.00094 psi(2S) mu- anti-nu_mu PHOTOS PHSP; +0.00750 eta_c mu- anti-nu_mu PHOTOS PHSP; +0.00020 eta_c(2S) mu- anti-nu_mu PHOTOS PHSP; +0.00004 anti-D0 mu- anti-nu_mu PHOTOS PHSP; +0.00018 anti-D*0 mu- anti-nu_mu PHOTOS PHSP; +0.04030 anti-B_s0 mu- anti-nu_mu PHOTOS PHSP; +0.05060 anti-B_s*0 mu- anti-nu_mu PHOTOS PHSP; +0.00340 anti-B0 mu- anti-nu_mu PHOTOS PHSP; +0.00580 anti-B*0 mu- anti-nu_mu PHOTOS PHSP; +# +0.00480 J/psi tau- anti-nu_tau PHSP; +0.00008 psi(2S) tau- anti-nu_tau PHSP; +0.00230 eta_c tau- anti-nu_tau PHSP; +0.000016 eta_c(2S) tau- anti-nu_tau PHSP; +0.00002 anti-D0 tau- anti-nu_tau PHSP; +0.00008 anti-D*0 tau- anti-nu_tau PHSP; +# +# +# Hadronic Decays +0.00200 eta_c pi- PHSP; +0.00420 rho- eta_c SVS; +0.00013 eta_c K- PHSP; +0.00020 K*- eta_c SVS; +0.00130 J/psi pi- SVS; +0.00400 J/psi rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00011 J/psi K- SVS; +0.00022 J/psi K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.000053 D- D0 PHSP; +0.000075 D*0 D- SVS; +0.000049 D*- D0 SVS; +0.00033 D*- D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000048 D_s- D0 PHSP; +0.0000071 D*0 D_s- SVS; +0.0000045 D_s*- D0 SVS; +0.000026 D_s*- D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.0000003 D- anti-D0 PHSP; +0.0000003 anti-D*0 D- SVS; +0.0000004 D*- anti-D0 SVS; +0.0000016 anti-D*0 D*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000066 D_s- anti-D0 PHSP; +0.0000063 anti-D*0 D_s- SVS; +0.0000085 D_s*- anti-D0 SVS; +0.0000404 D_s*- anti-D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.00280 eta_c D_s- PHSP; +0.00270 D_s*- eta_c SVS; +0.00015 eta_c D- PHSP; +0.00010 D*- eta_c SVS; +0.00170 J/psi D_s- SVS; +0.00670 J/psi D_s*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00009 J/psi D- SVS; +0.00028 J/psi D*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.16400 anti-B_s0 pi- PHSP; +0.07200 rho- anti-B_s0 SVS; +0.01060 anti-B_s0 K- PHSP; +0.00000 K*- anti-B_s0 SVS; +0.06500 anti-B_s*0 pi- SVS; +0.20200 anti-B_s*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00370 anti-B_s*0 K- SVS; +0.00000 anti-B_s*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01060 anti-B0 pi- PHSP; +0.00960 rho- anti-B0 SVS; +0.00070 anti-B0 K- PHSP; +0.00015 K*- anti-B0 SVS; +0.00950 anti-B*0 pi- SVS; +0.02570 anti-B*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00055 anti-B*0 K- SVS; +0.00058 anti-B*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00037 B- pi0 PHSP; +0.00034 rho0 B- SVS; +0.01980 B- K0 PHSP; +0.00430 K*0 B- SVS; +0.00033 B*- pi0 SVS; +0.00090 B*- rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01600 B*- K0 SVS; +0.01670 B*- K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# PR LHCb 09 Apr 2004 Add B_c+ -> rho0 pi+ + 0.00002 rho0 pi- SVS; +0.06005 anti-c s PYTHIA 42; +# PR LHCb 27 Apr 2004 Add Pythia Modes +# +# ash 10/27/03 Do not if this is correct but filling out with unknown cs +#0.0200235 cs_0 anti-uu_0 PYTHIA 63; +#0.0400470 cs_1 anti-uu_1 PYTHIA 63; +# +Enddecay + +# 09/15/03 A. Sanchez: Using BR's from hep-ph/0308214 +# +# Total Br = 0.939865 + .06135 cs +Decay B_c+ +0.01600 tau+ nu_tau SLN; +# +# SemiLeptonic Decays +0.01900 J/psi e+ nu_e PHOTOS PHSP; +0.00094 psi(2S) e+ nu_e PHOTOS PHSP; +0.00750 eta_c e+ nu_e PHOTOS PHSP; +0.00020 eta_c(2S) e+ nu_e PHOTOS PHSP; +0.00004 D0 e+ nu_e PHOTOS PHSP; +0.00018 D*0 e+ nu_e PHOTOS PHSP; +0.04030 B_s0 e+ nu_e PHOTOS PHSP; +0.05060 B_s*0 e+ nu_e PHOTOS PHSP; +0.00340 B0 e+ nu_e PHOTOS PHSP; +0.00580 B*0 e+ nu_e PHOTOS PHSP; +# +0.01900 J/psi mu+ nu_mu PHOTOS PHSP; +0.00094 psi(2S) mu+ nu_mu PHOTOS PHSP; +0.00750 eta_c mu+ nu_mu PHOTOS PHSP; +0.00020 eta_c(2S) mu+ nu_mu PHOTOS PHSP; +0.00004 D0 mu+ nu_mu PHOTOS PHSP; +0.00018 D*0 mu+ nu_mu PHOTOS PHSP; +0.04030 B_s0 mu+ nu_mu PHOTOS PHSP; +0.05060 B_s*0 mu+ nu_mu PHOTOS PHSP; +0.00340 B0 mu+ nu_mu PHOTOS PHSP; +0.00580 B*0 mu+ nu_mu PHOTOS PHSP; +# +0.00480 J/psi tau+ nu_tau PHSP; +0.00008 psi(2S) tau+ nu_tau PHSP; +0.00230 eta_c tau+ nu_tau PHSP; +0.000016 eta_c(2S) tau+ nu_tau PHSP; +0.00002 D0 tau+ nu_tau PHSP; +0.00008 D*0 tau+ nu_tau PHSP; +# +# Hadronic Decays +0.00200 eta_c pi+ PHSP; +0.00420 rho+ eta_c SVS; +0.00013 eta_c K+ PHSP; +0.00020 K*+ eta_c SVS; +0.00130 J/psi pi+ SVS; +0.00400 J/psi rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00011 J/psi K+ SVS; +0.00022 J/psi K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.000053 D+ anti-D0 PHSP; +0.000075 anti-D*0 D+ SVS; +0.000049 D*+ anti-D0 SVS; +0.00033 D*+ anti-D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000048 D_s+ anti-D0 PHSP; +0.0000071 anti-D*0 D_s+ SVS; +0.0000045 D_s*+ anti-D0 SVS; +0.000026 D_s*+ anti-D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.0000003 D+ D0 PHSP; +0.0000003 D*0 D+ SVS; +0.0000004 D*+ D0 SVS; +0.0000016 D*0 D*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000066 D_s+ D0 PHSP; +0.0000063 D*0 D_s+ SVS; +0.0000085 D_s*+ D0 SVS; +0.0000404 D_s*+ D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.00280 eta_c D_s+ PHSP; +0.00270 D_s*+ eta_c SVS; +0.00015 eta_c D+ PHSP; +0.00010 D*+ eta_c SVS; +0.00170 J/psi D_s+ SVS; +0.00670 J/psi D_s*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00009 J/psi D+ SVS; +0.00028 J/psi D*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.16400 B_s0 pi+ PHSP; +0.07200 rho+ B_s0 SVS; +0.01060 B_s0 K+ PHSP; +0.00000 K*+ B_s0 SVS; +0.06500 B_s*0 pi+ SVS; +0.20200 B_s*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00370 B_s*0 K+ SVS; +0.00000 B_s*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01060 B0 pi+ PHSP; +0.00960 rho+ B0 SVS; +0.00070 B0 K+ PHSP; +0.00015 K*+ B0 SVS; +0.00950 B*0 pi+ SVS; +0.02570 B*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00055 B*0 K+ SVS; +0.00058 B*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00037 B+ pi0 PHSP; +0.00034 rho0 B+ SVS; +0.01980 B+ anti-K0 PHSP; +0.00430 K*0 B+ SVS; +0.00033 B*+ pi0 SVS; +0.00090 B*+ rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01600 B*+ anti-K0 SVS; +0.01670 B*+ K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# PR LHCb 09 Apr 2004 Add B_c+ -> rho0 pi+ + 0.00002 rho0 pi+ SVS; +0.06005 c anti-s PYTHIA 42; +# PR LHCb 27 Apr 2004 Add Pythia Modes +# +# ash 10/27/03 Do not if this is correct but filling out with unknown cs +#0.0200235 anti-cs_0 uu_0 PYTHIA 63; +#0.0400470 anti-cs_1 uu_1 PYTHIA 63; +# +Enddecay + + +# Add excited Lambda_c decays (R.J. Tesarek 12/9/03) +# Just a guess for the last two BR [Lambda_c(2593)+]. +Decay Lambda_c(2593)+ +0.096585366 Sigma_c++ pi- PHSP; #[Reconstructed PDG2011] +0.096585366 Sigma_c0 pi+ PHSP; #[Reconstructed PDG2011] +0.190000000 Lambda_c+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.096585366 Sigma_c+ pi0 PHSP; #[Reconstructed PDG2011] +0.036219512 Lambda_c+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004024390 Lambda_c+ gamma PHSP; #[Reconstructed PDG2011] +0.240000000 Sigma_c*++ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.240000000 Sigma_c*0 pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Lambda_c(2593)- +0.096585366 anti-Sigma_c-- pi+ PHSP; #[Reconstructed PDG2011] +0.096585366 anti-Sigma_c0 pi- PHSP; #[Reconstructed PDG2011] +0.190000000 anti-Lambda_c- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.096585366 anti-Sigma_c- pi0 PHSP; #[Reconstructed PDG2011] +0.036219512 anti-Lambda_c- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004024390 anti-Lambda_c- gamma PHSP; #[Reconstructed PDG2011] +0.240000000 anti-Sigma_c*-- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.240000000 anti-Sigma_c*0 pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Lambda_c(2625)+ +0.670000000 Lambda_c+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.320294118 Lambda_c+ pi0 PHSP; #[Reconstructed PDG2011] +0.009705882 Lambda_c+ gamma PHSP; #[Reconstructed PDG2011] +Enddecay +Decay anti-Lambda_c(2625)- +0.670000000 anti-Lambda_c- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.320294118 anti-Lambda_c- pi0 PHSP; #[Reconstructed PDG2011] +0.009705882 anti-Lambda_c- gamma PHSP; #[Reconstructed PDG2011] +Enddecay + +# Add excited B hadrons (LHCb PR 10/03/04) +# Reference : Pythia 6.205 decay table +# PDG Id = 5312 +Decay Xi'_b- + 1.0000 Xi_b- gamma PHSP; +Enddecay +Decay anti-Xi'_b+ + 1.0000 anti-Xi_b+ gamma PHSP; +Enddecay +# PDG Id = 5322 +Decay Xi'_b0 + 1.0000 Xi_b0 gamma PHSP; +Enddecay +Decay anti-Xi'_b0 + 1.0000 anti-Xi_b0 gamma PHSP; +Enddecay +# PDG Id = 10521 +Decay B_0*+ + 0.6670 B0 pi+ PHSP; + 0.3330 B+ pi0 PHSP; +Enddecay +Decay B_0*- + 0.6670 anti-B0 pi- PHSP; + 0.3330 B- pi0 PHSP; +Enddecay +# PDG Id = 20523 Broad : S wave +Decay B'_1+ + 0.6670 B*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 B*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay B'_1- + 0.6670 anti-B*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 B*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 10523 Narrow : D wave +Decay B_1+ + 0.6670 B*0 pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 B*+ pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay B_1- + 0.6670 anti-B*0 pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 B*- pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 525 Narrow : D wave +Decay B_2*+ + 0.3000 B0 pi+ TSS; + 0.1500 B+ pi0 TSS; + 0.1600 B*0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 B*+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 B*0 pi+ pi0 PHSP; + 0.0600 B*+ pi+ pi- PHSP; + 0.0800 B0 pi+ pi0 PHSP; + 0.0400 B+ pi+ pi- PHSP; +Enddecay +Decay B_2*- + 0.3000 anti-B0 pi- TSS; + 0.1500 B- pi0 TSS; + 0.1600 anti-B*0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 B*- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 anti-B*0 pi- pi0 PHSP; + 0.0600 B*- pi- pi+ PHSP; + 0.0800 anti-B0 pi- pi0 PHSP; + 0.0400 B- pi- pi+ PHSP; +Enddecay +# PDG Id = 10511 +Decay B_0*0 + 0.6670 B+ pi- PHSP; + 0.3330 B0 pi0 PHSP; +Enddecay +Decay anti-B_0*0 + 0.6670 B- pi+ PHSP; + 0.3330 anti-B0 pi0 PHSP; +Enddecay +# PDG Id = 20513 Broad : S wave +Decay B'_10 + 0.6670 B*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 B*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay anti-B'_10 + 0.6670 B*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 anti-B*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 10513 Narrow : D wave +Decay B_10 + 0.6670 B*+ pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 B*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay anti-B_10 + 0.6670 B*- pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 anti-B*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 515 +Decay B_2*0 + 0.3000 B+ pi- TSS; + 0.1500 B0 pi0 TSS; + 0.1600 B*+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 B*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 B*+ pi- pi0 PHSP; + 0.0600 B*0 pi+ pi- PHSP; + 0.0800 B+ pi- pi0 PHSP; + 0.0400 B0 pi+ pi- PHSP; +Enddecay +Decay anti-B_2*0 + 0.3000 B- pi+ TSS; + 0.1500 anti-B0 pi0 TSS; + 0.1600 B*- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 anti-B*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 B*- pi+ pi0 PHSP; + 0.0600 anti-B*0 pi- pi+ PHSP; + 0.0800 B- pi+ pi0 PHSP; + 0.0400 anti-B0 pi- pi+ PHSP; +Enddecay +# PDG Id = 10531 +Decay B_s0*0 + 0.5000 B+ K- PHSP; + 0.5000 B0 anti-K0 PHSP; +Enddecay +Decay anti-B_s0*0 + 0.5000 B- K+ PHSP; + 0.5000 anti-B0 K0 PHSP; +Enddecay +# PDG Id = 20533 Broad : S wave +Decay B'_s10 + 0.5000 B*+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 B*0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay anti-B'_s10 + 0.5000 B*- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 anti-B*0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 10533 Narrow : D wave +Decay B_s10 + 0.5000 B*+ K- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 B*0 anti-K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay anti-B_s10 + 0.5000 B*- K+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 anti-B*0 K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 535 Narrow : D wave +Decay B_s2*0 + 0.3000 B+ K- TSS; + 0.3000 B0 anti-K0 TSS; + 0.2000 B*+ K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 B*0 anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +Decay anti-B_s2*0 + 0.3000 B- K+ TSS; + 0.3000 anti-B0 K0 TSS; + 0.2000 B*- K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 anti-B*0 K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 543 +Decay B_c*+ + 1.0000 B_c+ gamma VSP_PWAVE; +Enddecay +Decay B_c*- + 1.0000 B_c- gamma VSP_PWAVE; +Enddecay +# PDG Id = 545 Narrow : D wave +Decay B_c2*+ + 0.3000 B0 D+ TSS; + 0.3000 B+ D0 TSS; + 0.2000 B*0 D+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 B*+ D0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +Decay B_c2*- + 0.3000 anti-B0 D- TSS; + 0.3000 B- anti-D0 TSS; + 0.2000 anti-B*0 D- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 B*- anti-D0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 5114 +Decay Sigma_b*- + 1.0000 Lambda_b0 pi- PHSP; +Enddecay +Decay anti-Sigma_b*+ + 1.0000 anti-Lambda_b0 pi+ PHSP; +Enddecay +# PDG Id = 5224 +Decay Sigma_b*+ + 1.0000 Lambda_b0 pi+ PHSP; +Enddecay +Decay anti-Sigma_b*- + 1.0000 anti-Lambda_b0 pi- PHSP; +Enddecay +# PDG Id = 5214 +Decay Sigma_b*0 + 1.0000 Lambda_b0 pi0 PHSP; +Enddecay +Decay anti-Sigma_b*0 + 1.0000 anti-Lambda_b0 pi0 PHSP; +Enddecay +# PDG Id = 5314 +Decay Xi_b*- + 1.0000 Xi_b- gamma PHSP; +Enddecay +Decay anti-Xi_b*+ + 1.0000 anti-Xi_b+ gamma PHSP; +Enddecay +# PDG Id = 5324 +Decay Xi_b*0 + 1.0000 Xi_b0 gamma PHSP; +Enddecay +Decay anti-Xi_b*0 + 1.0000 anti-Xi_b0 gamma PHSP; +Enddecay +# PDG Id = 5334 +Decay Omega_b*- + 1.0000 Omega_b- gamma PHSP; +Enddecay +Decay anti-Omega_b*+ + 1.0000 anti-Omega_b+ gamma PHSP; +Enddecay +# PDG Id = 10541 +Decay B_c0*+ + 0.5000 B0 D+ PHSP; + 0.5000 B+ D0 PHSP; +Enddecay +Decay B_c0*- + 0.5000 anti-B0 D- PHSP; + 0.5000 B- anti-D0 PHSP; +Enddecay +# PDG Id = 10543 Narrow : D wave +Decay B_c1+ + 0.5000 B*0 D+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 B*+ D0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay B_c1- + 0.5000 anti-B*0 D- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 B*- anti-D0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 20543 Broad : S wave +Decay B'_c1+ + 0.5000 B*0 D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 B*+ D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay B'_c1- + 0.5000 anti-B*0 D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 B*- anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay + +# Excited charmed Baryons LHCb PR 3-05-2006 +Decay Xi_cc*++ + 0.08 e+ nu_e Xi_c+ PHSP ; + 0.08 mu+ nu_mu Xi_c+ PHSP ; +0.51 u anti-d s cu_0 PYTHIA 42; +0.25 u anti-d s cu_1 PYTHIA 42; +0.05 u anti-s s cu_0 PYTHIA 42; +0.03 u anti-s s cu_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc*-- + 0.08 e- anti-nu_e anti-Xi_c- PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c- PHSP; +0.51 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.05 anti-u s anti-s anti-cu_1 PYTHIA 42; +0.03 anti-u s anti-s anti-cu_1 PYTHIA 42; +Enddecay + +Decay Xi_cc++ + 0.08 e+ nu_e Xi_c+ PHSP ; + 0.08 mu+ nu_mu Xi_c+ PHSP ; +0.51 u anti-d s cu_0 PYTHIA 42; +0.25 u anti-d s cu_1 PYTHIA 42; +0.05 u anti-s s cu_0 PYTHIA 42; +0.03 u anti-s s cu_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc-- + 0.08 e- anti-nu_e anti-Xi_c- PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c- PHSP; +0.51 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.05 anti-u s anti-s anti-cu_1 PYTHIA 42; +0.03 anti-u s anti-s anti-cu_1 PYTHIA 42; +Enddecay + +Decay Xi_cc*+ + 0.08 e+ nu_e Xi_c0 PHSP; + 0.08 mu+ nu_mu Xi_c0 PHSP; +0.51 u anti-d s cd_0 PYTHIA 42; +0.25 u anti-d s cd_1 PYTHIA 42; +0.05 u anti-s s cd_0 PYTHIA 42; +0.03 u anti-s s cd_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc*- + 0.08 e- anti-nu_e anti-Xi_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c0 PHSP; +0.51 anti-u d anti-s anti-cd_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cd_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cd_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cd_1 PYTHIA 42; +Enddecay + +Decay Xi_cc+ + 0.08 e+ nu_e Xi_c0 PHSP; + 0.08 mu+ nu_mu Xi_c0 PHSP; +0.51 u anti-d s cd_0 PYTHIA 42; +0.25 u anti-d s cd_1 PYTHIA 42; +0.05 u anti-s s cd_0 PYTHIA 42; +0.03 u anti-s s cd_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc- + 0.08 e- anti-nu_e anti-Xi_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c0 PHSP; +0.51 anti-u d anti-s anti-cd_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cd_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cd_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cd_1 PYTHIA 42; +Enddecay + +Decay Omega_cc+ + 0.08 e+ nu_e Omega_c0 PHSP; + 0.08 mu+ nu_mu Omega_c0 PHSP; +0.51 u anti-d s cs_0 PYTHIA 42; +0.25 u anti-d s cs_1 PYTHIA 42; +0.05 u anti-s s cs_0 PYTHIA 42; +0.03 u anti-s s cs_1 PYTHIA 42; +Enddecay + +Decay anti-Omega_cc- + 0.08 e- anti-nu_e anti-Omega_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Omega_c0 PHSP; +0.51 anti-u d anti-s anti-cs_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cs_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cs_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cs_1 PYTHIA 42; +Enddecay + +Decay Omega_cc*+ + 0.08 e+ nu_e Omega_c0 PHSP; + 0.08 mu+ nu_mu Omega_c0 PHSP; +0.51 u anti-d s cs_0 PYTHIA 42; +0.25 u anti-d s cs_1 PYTHIA 42; +0.05 u anti-s s cs_0 PYTHIA 42; +0.03 u anti-s s cs_1 PYTHIA 42; +Enddecay + +Decay anti-Omega_cc*- + 0.08 e- anti-nu_e anti-Omega_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Omega_c0 PHSP; +0.51 anti-u d anti-s anti-cs_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cs_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cs_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cs_1 PYTHIA 42; +Enddecay + +Decay K_L0 +#0.202464226 pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.202464226 pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.135033299 pi+ mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.135033299 pi- mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000025738 pi0 pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000025738 pi0 pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000006205 pi+ e- anti-nu_e e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000006205 pi- e+ nu_e e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.194795855 pi0 pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.125231606 pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.001880711 pi+ e- anti-nu_e gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.001880711 pi- e+ nu_e gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000277023 pi+ mu- anti-nu_mu gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000277023 pi- mu+ nu_mu gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000040995 pi+ pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000001262 pi0 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000016 pi0 gamma e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000545653 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000009265 e+ e- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000355 mu+ mu- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000584 e+ e- gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000007 mu+ mu- gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay + +End diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg new file mode 100644 index 000000000..8109ace4c --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg @@ -0,0 +1,39 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 From c8dda3cf32faf7ebb9d695023134c520fba6fde0 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Fri, 12 Jun 2026 12:58:24 +0200 Subject: [PATCH 348/362] setenv_calib.sh: add new ErrorInfo ITS deadmap builder input to CALIBDATASPEC_BARREL_TF --- DATA/common/setenv_calib.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index b44de438a..5521c4b0d 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -263,7 +263,10 @@ if [[ -z ${CALIBDATASPEC_BARREL_TF:-} ]]; then if [[ $CALIB_PRIMVTX_MEANVTX == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "pvtx:GLO/PVTX/0"; fi # ITS - if [[ $CALIB_ITS_DEADMAP_TIME == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "itsChipStatus:ITS/CHIPSSTATUS/0"; fi + if [[ $CALIB_ITS_DEADMAP_TIME == 1 ]]; then + add_semicolon_separated CALIBDATASPEC_BARREL_TF "itsChipStatus:ITS/CHIPSSTATUS/0" + add_semicolon_separated CALIBDATASPEC_BARREL_TF "itsErrorInfo:ITS/ErrorInfo/0" + fi # MFT if [[ $CALIB_MFT_DEADMAP_TIME == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "mftChipStatus:MFT/CHIPSSTATUS/0"; fi From 732c81fe6592655947f4e056b02dbb8045dc6ca6 Mon Sep 17 00:00:00 2001 From: shreyasiacharya <34233706+shreyasiacharya@users.noreply.github.com> Date: Tue, 16 Jun 2026 10:03:03 +0200 Subject: [PATCH 349/362] Adding chiC (#2384) * Update generator_pythia8_HadronTriggered_withGap.C * Create Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C * Update Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini --- ...enerator_pythia8_HadronTriggered_withGap.C | 40 ++++++- ...eJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini | 2 +- ...ctedInclusiveJpsiMidy_Pythia8_TriggerGap.C | 102 ++++++++++++++++++ 3 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C index 8e8f46938..d34092a8c 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C @@ -211,4 +211,42 @@ FairGenerator* // gen->PrintDebug(); return gen; -} \ No newline at end of file +} +FairGenerator * +GeneratorInclusiveJpsiPsi2SChiC_EvtGenMidY(int triggerGap, double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->addHadronPDGs(100443); + gen->addHadronPDGs(445); + gen->addHadronPDGs(200443); + gen->setVerbose(verbose); + + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + + gen->SetSizePdg(4); + gen->AddPdg(443, 0); + gen->AddPdg(100443, 1); + gen->AddPdg(443, 2); + gen->AddPdg(100443, 3); + + gen->SetForceDecay(kEvtDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in | ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} diff --git a/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini index 7ed21efdf..7843272c2 100644 --- a/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini +++ b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini @@ -1,7 +1,7 @@ ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C -funcName=GeneratorInclusiveJpsiPsi2S_EvtGenMidY(5,-1.5,1.5) +funcName=GeneratorInclusiveJpsiPsi2SChiC_EvtGenMidY(5,-1.5,1.5) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C new file mode 100644 index 000000000..45dafa928 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C @@ -0,0 +1,102 @@ +int External() +{ + int checkPdgSignal[] = {443, 100443}; + int checkPdgDecay = 11; + double rapiditymin = -4.3; + double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) + { + // count leptons + nLeptons++; + } + else if (pdg == -checkPdgDecay) + { + // count anti-leptons + nAntileptons++; + } + else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) + { + if (idMoth < 0) + { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if (rapidity > rapiditymin && rapidity < rapiditymax) + { + pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++; + } + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) + { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) + { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) + { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) + { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) + { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From c36702ac9e646bf69f1e6b4e20218f8143bb2f4d Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Tue, 16 Jun 2026 13:44:05 +0200 Subject: [PATCH 350/362] Add missing B_s -> JPsi decays (#2385) * Add missing B_s -> JPsi decays * remove copy-paste --- MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC b/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC index 8303dde7d..3ced468f5 100644 --- a/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC +++ b/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC @@ -346,6 +346,8 @@ Decay anti-B_s0 0.00070 J/psi K- K+ PHSP; 0.00070 J/psi anti-K0 K+ pi- PHSP; 0.00070 J/psi K- K+ pi0 PHSP; +0.000035 J/psi anti-K*0 PHSP; +0.000107 J/psi K*0 anti-K*0 PHSP; # LHCb PR 04/02/04 Add (cc) phi n pi(+/0) 0.00039 J/psi phi pi+ pi- PHSP; 0.00039 J/psi phi pi0 pi0 PHSP; @@ -415,6 +417,8 @@ Decay B_s0 0.00070 J/psi K- K+ PHSP; 0.00070 J/psi K0 K- pi+ PHSP; 0.00070 J/psi K- K+ pi0 PHSP; +0.000035 J/psi K*0 PHSP; +0.000107 J/psi K*0 anti-K*0 PHSP; # LHCb PR 04/02/04 Add (cc) phi n pi(+/0) 0.00039 J/psi phi pi+ pi- PHSP; 0.00039 J/psi phi pi0 pi0 PHSP; From 5b7fb4633495eb02471043afdc0a95e57f67abee Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 23 Jun 2026 19:42:19 +0200 Subject: [PATCH 351/362] Option to bias the MeanVertex with ALIEN_JDL_MVBIAS --- DATA/production/configurations/asyncReco/setenv_extra.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index 55f97b10b..f9f5ed532 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -828,6 +828,11 @@ if [[ $ALIEN_JDL_PREPROPAGATE == "1" ]] ; then export ARGS_EXTRA_PROCESS_o2_aod_producer_workflow+=" --propagate-tracks --propagate-tracks-max-xiu 5" fi +# possibility to bias the MeanVertex from the CCDB, see https://github.com/AliceO2Group/AliceO2/pull/15549 +if [[ -n $ALIEN_JDL_MVBIAS ]]; then + export O2_DPL_MVBIAS=$ALIEN_JDL_MVBIAS +fi + # Enabling QC if [[ $ALIEN_JDL_QCOFF != "1" ]]; then export WORKFLOW_PARAMETERS="QC,${WORKFLOW_PARAMETERS}" From b4a073bd7d202fbfb1b1120ffc237a252f0c8ec1 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 25 Jun 2026 18:39:26 +0200 Subject: [PATCH 352/362] Allow arbitrary prodsplits in grid_submit --- GRID/utils/grid_submit.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/GRID/utils/grid_submit.sh b/GRID/utils/grid_submit.sh index 911252658..dcf6f78da 100755 --- a/GRID/utils/grid_submit.sh +++ b/GRID/utils/grid_submit.sh @@ -230,7 +230,13 @@ export JOBLABEL export MATTERMOSTHOOK export CONTROLSERVER -[[ $PRODSPLIT -gt 100 ]] && echo "Production split needs to be smaller than 100 for the moment" && exit 1 +# Validate the production split level and derive the zero-padding width used for the +# per-subjob OutputDir counter (#alien_counter_i#) and for local fetching. The width +# adapts to PRODSPLIT (minimum 3, so existing 3-digit layouts are unchanged), which lifts +# the former hard cap of 100 while keeping OutputDir naming consistent at any scale. +[[ ! $PRODSPLIT =~ ^[0-9]+$ || $PRODSPLIT -lt 1 ]] && echo "Production split must be a positive integer (got '${PRODSPLIT}')" && exit 1 +COUNTERWIDTH=${#PRODSPLIT} +[[ $COUNTERWIDTH -lt 3 ]] && COUNTERWIDTH=3 # check for presence of jq (needed in code path to fetch output files) [[ "$FETCHOUTPUT" ]] && { which jq &> /dev/null || { echo "Could not find jq command. Please load or install" && exit 1; }; } @@ -371,7 +377,7 @@ ${DATACOLLECTION:+InputDataListFormat = ${QUOT}txt-list${QUOT};} ${DATACOLLECTION:+InputDataCollection = ${QUOT}LF:${MY_JOBWORKDIR}/collection.xml,nodownload${QUOT};} ${PRODSPLIT:+Split = ${QUOT}${SPLITMODE}${QUOT};} ${DATACOLLECTION:+SplitMaxInputFileNumber = 1;} -OutputDir = "${MY_JOBWORKDIR}/${PRODSPLIT:+#alien_counter_03i#}"; +OutputDir = "${MY_JOBWORKDIR}/${PRODSPLIT:+#alien_counter_0${COUNTERWIDTH}i#}"; Requirements = member(other.GridPartitions,"${GRIDPARTITION:-multicore_8}"); CPUCores = "${CPUCORES}"; MemorySize = "60GB"; @@ -504,7 +510,7 @@ EOF THIS_JOB=${SUBJOBIDS[jobindex]} echo "Fetching for job ${THIS_JOB}" if [ "${THIS_STATUS}" == "DONE" ]; then - SPLITOUTDIR=$(printf "%03d" ${splitcounter}) + SPLITOUTDIR=$(printf "%0${COUNTERWIDTH}d" ${splitcounter}) [ ! -f ${SPLITOUTDIR} ] && mkdir ${SPLITOUTDIR} echo "Fetching result files for subjob ${splitcounter} into ${PWD}" CPCMD="alien.py cp ${MY_JOBWORKDIR}/${SPLITOUTDIR}/* file:./${SPLITOUTDIR}" From 9d7321b422e7e82994287b07057b5e1cb6d62063 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Fri, 26 Jun 2026 18:57:03 +0200 Subject: [PATCH 353/362] Fix seed initialisation of c-deuteron gun and status codes (#2389) --- .../generator_pythia8_embed_charmnuclei.C | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C index 4e6f69ba0..94c9c0b80 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C @@ -22,7 +22,7 @@ class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 public: /// constructor - GeneratorPythia8HFEmbedCharmNuclei(int pdgCode = 2010010020, float lifetime = 1.f, int nCharmNucleiPerEvent = 10, float yMin = -1.f, float yMax = 1.f, float ptMax = 25.f, bool trivialCoal = false, float coalMomentum = 0.2, float fracFromB = 0.f) + GeneratorPythia8HFEmbedCharmNuclei(int pdgCode = 2010010020, float lifetime = 1.f, int nCharmNucleiPerEvent = 10, float yMin = -1.f, float yMax = 1.f, float ptMax = 25.f, bool trivialCoal = false, float coalMomentum = 0.2, float fracFromB = 0.f, unsigned int seed = 0u) { nNumberOfCharmNucleiPerEvent = nCharmNucleiPerEvent; mRapidityMinCharmNuclei = yMin; @@ -33,6 +33,7 @@ class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 mFractionFromBeauty = fracFromB; mPdgCharmNucleus = pdgCode; mSign = 1; + mUsedSeed = seed; if (std::abs(mPdgCharmNucleus) == 2010010020) { mMassCharmNucleus = 3.226f; } else { @@ -63,6 +64,9 @@ class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 LOG(fatal) << "Failed to init \'GeneratorPythia8\': problems with configuration file " << cfg; } + mPythiaGun.readString("Random:setSeed = on"); + mPythiaGun.readString("Random:seed = " + std::to_string(seed)); + if (!mPythiaGun.init()) { LOG(fatal) << "Failed to init \'GeneratorPythia8\': init returned with error"; } @@ -170,7 +174,8 @@ class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 mPythiaGun.moreDecays(); std::array dausToCoal = {-1, -1}; std::vector pdgShortLivedResos = {313, 2224, 102134}; - std::map statusResoDecay = {{313, 95}, {2224, 96}, {102134, 97}}; // do not use 94, it is used by default for no resonances + std::map statusResoDecay = {{313, -85}, {2224, -86}, {102134, -87}}; // do not use 94, it is used by default for no resonances + std::map statusResoDecayFromB = {{313, -95}, {2224, -96}, {102134, -97}}; // do not use 94, it is used by default for no resonances int whichReso{0}; int idxCharmNucleus{-1}; for (int iPart{0}; iPart{1000010020}, mTrivialCoal, mCoalMomentum, dausToCoal[0], dausToCoal[1], 10.); if (whichReso > 0) { - mPythiaGun.event[idxCharmNucleus].status(statusResoDecay[whichReso]); + if (isFromB) { + mPythiaGun.event[idxCharmNucleus].status(statusResoDecayFromB[whichReso]); + } else { + mPythiaGun.event[idxCharmNucleus].status(statusResoDecay[whichReso]); + } } if (isCoalSuccess) { restoreEnergyConservation(mPythiaGun.event, idxCharmNucleus); @@ -332,8 +341,8 @@ private: ///___________________________________________________________ FairGenerator *GenerateHFEmbedCDeuteron(float lifetime = 1.f, int nCharmNucleiPerEvent = 10, float yMin = -1.f, float yMax = 1.f, float ptMax = 25.f, bool trivialCoal = false, float coalMomentum = 0.2f, float fracFromB = 0.25f) { - auto myGen = new GeneratorPythia8HFEmbedCharmNuclei(2010010020, lifetime, nCharmNucleiPerEvent, yMin, yMax, ptMax, trivialCoal, coalMomentum, fracFromB); auto seed = (gRandom->TRandom::GetSeed() % 900000000); + auto myGen = new GeneratorPythia8HFEmbedCharmNuclei(2010010020, lifetime, nCharmNucleiPerEvent, yMin, yMax, ptMax, trivialCoal, coalMomentum, fracFromB, seed); myGen->readString("Random:setSeed on"); myGen->readString("Random:seed " + std::to_string(seed)); return myGen; From 0a6a1bfb6b09cdf4e058631354468b0a32caf131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Pu=C5=82awski?= Date: Wed, 24 Jun 2026 17:14:34 +0200 Subject: [PATCH 354/362] DPG: update FIT parameters for 2023 and 2024 data --- MC/bin/o2dpg_sim_config.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index 6261401a3..e2dee7435 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -97,10 +97,22 @@ def add(cfg, flatconfig): add(config, {"FwdMatching.cutFcn" : "cut3SigmaXYAngles"}) # FIT digitizer settings + #2023 pp + if 534125 <= int(args.run) and int(args.run) <= 543113: + add(config, {"FV0DigParam.adcChannelsPerMip": "15"}) + if COLTYPEIR == "pp": + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "40", "FT0DigParam.mtrg_semicentral_trh": "20"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "8"}) # 2023 PbPb if 543437 <= int(args.run) and int(args.run) <= 545367: add(config, {"FT0DigParam.mMip_in_V": "7", "FT0DigParam.mMV_2_Nchannels": "2", "FT0DigParam.mMV_2_NchannelsInverse": "0.5"}) add(config, {"FV0DigParam.adcChannelsPerMip": "4"}) + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "1433", "FT0DigParam.mtrg_semicentral_trh": "35"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "1080"}) # 2024 # first and last run of 2024 if 546088 <= int(args.run) and int(args.run) <= 560623: @@ -111,6 +123,15 @@ def add(cfg, flatconfig): if COLTYPEIR == "PbPb": # 4 ADC channels / MIP add(config, {"FV0DigParam.adcChannelsPerMip": "4"}) + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "1433", "FT0DigParam.mtrg_semicentral_trh": "35"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "1080"}) + if COLTYPEIR == "pp": + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "40", "FT0DigParam.mtrg_semicentral_trh": "20"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "8"}) # 2025 # first and last run of 2025 if 562260 <= int(args.run) and int(args.run) <= 568721: From f26986ec77c29ace87331222b31d831f52d45612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Pu=C5=82awski?= Date: Wed, 24 Jun 2026 17:16:45 +0200 Subject: [PATCH 355/362] DPG: update FIT parameters for 2023 and 2024 data --- MC/bin/o2dpg_sim_config.py | 1 - 1 file changed, 1 deletion(-) diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index e2dee7435..79c6a4179 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -99,7 +99,6 @@ def add(cfg, flatconfig): # FIT digitizer settings #2023 pp if 534125 <= int(args.run) and int(args.run) <= 543113: - add(config, {"FV0DigParam.adcChannelsPerMip": "15"}) if COLTYPEIR == "pp": # central and semicentral FT0 thresholds add(config, {"FT0DigParam.mtrg_central_trh": "40", "FT0DigParam.mtrg_semicentral_trh": "20"}) From fa9dc0ab6c5ffa2dffc00802f8ae5152b6afe95c Mon Sep 17 00:00:00 2001 From: wiechula Date: Wed, 17 Jun 2026 11:56:57 +0200 Subject: [PATCH 356/362] Add extended search roads and option to disable them --- DATA/common/setenv_calib.sh | 2 +- .../configurations/asyncReco/async_pass.sh | 2 +- .../configurations/asyncReco/setenv_extra.sh | 24 +++++++++++-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index 5521c4b0d..59d457889 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -40,7 +40,7 @@ if [[ $SYNCMODE != 1 ]] && has_detector_reco TPC; then CAN_DO_CALIB_ASYNC_EXTRAC if has_detector CTP; then export CALIB_TPC_SCDCALIB_CTP_INPUT="--enable-ctp"; else export CALIB_TPC_SCDCALIB_CTP_INPUT=""; fi if [[ ${DISABLE_TRD_PH:-} == 1 ]]; then CAN_DO_CALIB_TRD_T0=0; fi -: ${CALIB_TPC_SCDCALIB_SLOTLENGTH:=600} # the slot length needs to be known both on the aggregator and the processing nodes, therefore it is defined (in seconds!) here +: ${CALIB_TPC_SCDCALIB_SLOTLENGTH:=300} # the slot length needs to be known both on the aggregator and the processing nodes, therefore it is defined (in seconds!) here : ${CALIB_TPC_SCDCALIB_SENDTRKDATA:=1} # by default, we want to write the track information in addition to unbinned residuals to allow finer filtering offline if [[ $BEAMTYPE != "cosmic" ]] || [[ ${FORCECALIBRATIONS:-} == 1 ]] ; then # Calibrations enabled in non-COSMIC runs diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index 508198546..5a178344d 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -308,7 +308,7 @@ fi if [[ $ALIEN_JDL_DOEMCCALIB == "1" ]]; then SETTING_ROOT_OUTPUT+="ENABLE_ROOT_OUTPUT_o2_emcal_emc_offline_calib_workflow= " fi -if [[ $DO_TPC_RESIDUAL_EXTRACTION == "1" ]]; then +if [[ -n "$DO_TPC_RESIDUAL_EXTRACTION" && $DO_TPC_RESIDUAL_EXTRACTION != "0" ]]; then SETTING_ROOT_OUTPUT+="ENABLE_ROOT_OUTPUT_o2_calibration_residual_aggregator= " fi if [[ $ALIEN_JDL_DOTRDVDRIFTEXBCALIB == "1" ]]; then diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index f9f5ed532..307c88d71 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -289,7 +289,7 @@ isFT0inDataTaking=`echo $RUN_DETECTOR_LIST | grep FT0` # For runs shorter than 10 minutes we have only a single slot. # In that case we have to adopt the slot length in order to # set the maximum number of processed tracks per TF correctly -if (( RUN_DURATION < 600 )); then +if (( RUN_DURATION < 300 )); then export CALIB_TPC_SCDCALIB_SLOTLENGTH=$RUN_DURATION fi @@ -716,17 +716,21 @@ if [[ $ADD_CALIB == "1" ]]; then export CALIB_TOF_INTEGRATEDCURR=0 export CALIB_ITS_DEADMAP_TIME=0 export CALIB_MFT_DEADMAP_TIME=0 - if [[ $DO_TPC_RESIDUAL_EXTRACTION == "1" ]]; then + if [[ -n "$DO_TPC_RESIDUAL_EXTRACTION" && $DO_TPC_RESIDUAL_EXTRACTION != "0" ]]; then + : ${ALIEN_JDL_TPCRESIDUALTRKSOURCESMAPEXTRACTION:="ITS-TPC"} + : ${ALIEN_JDL_TPCRESIDUALMAXTRACKSPERSLOT:=-1} + : ${ALIEN_JDL_TPCRESIDUALADDTRACKSMAP:=35000000} export CALIB_TPC_SCDCALIB=1 export CALIB_TPC_SCDCALIB_SENDTRKDATA=1 - export CONFIG_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=";scdcalib.additionalTracksMap=35000000;scdcalib.minPtNoOuterPoint=0.2;scdcalib.maxQ2Pt=5;scdcalib.minITSNClsNoOuterPoint=6;scdcalib.minITSNCls=4;scdcalib.minTPCNClsNoOuterPoint=90;scdcalib.minTOFTRDPVContributors=2" - : ${TPC_RESIDUAL_TRK_SOURCES_MAP_EXTRACTION:="ITS-TPC"} - export ARGS_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=" --tracking-sources-map-extraction $TPC_RESIDUAL_TRK_SOURCES_MAP_EXTRACTION" - # ad-hoc settings for TPC residual extraction - export ARGS_EXTRA_PROCESS_o2_calibration_residual_aggregator+=" --output-type trackParams,unbinnedResid" - if [[ $ALIEN_JDL_DEBUGRESIDUALEXTRACTION == "1" ]]; then - export CONFIG_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=";scdcalib.maxTracksPerCalibSlot=-1;scdcalib.minPtNoOuterPoint=0.8;scdcalib.minTPCNClsNoOuterPoint=120" - export ARGS_EXTRA_PROCESS_o2_trd_global_tracking+=" --enable-qc" + export CONFIG_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=";scdcalib.maxTracksPerCalibSlot=$ALIEN_JDL_TPCRESIDUALMAXTRACKSPERSLOT;scdcalib.additionalTracksMap=$ALIEN_JDL_TPCRESIDUALADDTRACKSMAP;scdcalib.minPtNoOuterPoint=0.2;scdcalib.maxQ2Pt=5;scdcalib.minITSNClsNoOuterPoint=6;scdcalib.minITSNCls=4;scdcalib.minTPCNClsNoOuterPoint=50;scdcalib.minTOFTRDPVContributors=2" + export ARGS_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=" --tracking-sources-map-extraction $ALIEN_JDL_TPCRESIDUALTRKSOURCESMAPEXTRACTION" + if [[ ! $DO_TPC_RESIDUAL_EXTRACTION =~ "NOEXTCLROAD" ]]; then + clusterErrors=";GPU_rec_tpc.clusterError2AdditionalY=0.3;GPU_rec_tpc.clusterError2AdditionalZ=0.3" + + export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";$clusterErrors" + export CONFIG_EXTRA_PROCESS_o2_tpcits_match_workflow+=";$clusterErrors" + export CONFIG_EXTRA_PROCESS_o2_tof_matcher_workflow+=";$clusterErrors" + export CONFIG_EXTRA_PROCESS_o2_trd_global_tracking+=";$clusterErrors" fi fi export CALIB_EMC_ASYNC_RECALIB="$ALIEN_JDL_DOEMCCALIB" From 249fae8d3caa6f5aee4bb7fc1c876e0c3400f25c Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Sun, 28 Jun 2026 17:32:31 +0200 Subject: [PATCH 357/362] MC/PWGEM: update DY simulation (#2391) --- MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg index 4919e698d..d839106eb 100644 --- a/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg +++ b/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg @@ -4,10 +4,11 @@ Beams:idB 2212 # proton Beams:eCM 13600. # GeV #user can change eCM from command line. ### processes -WeakSingleBoson:ffbar2ffbar(s:gmZ) on # ffbar -> Z/gamma* -> ffbar -PhaseSpace:mHatMin 0 -PhaseSpace:mHatMax -1 -PhaseSpace:pTHatMinDiverge 0.5 # this allows for mll > 1 GeV/c2 +WeakSingleBoson:ffbar2gmZ on # ffbar -> Z/gamma* +PhaseSpace:mHatMin 0.5 +PhaseSpace:mHatMax 15 +23:mMin 0.5 +TimeShower:mMaxGamma 0.5 23:onMode off # switch off all Z0 decay channels. # User must switch back on Z0 going to l+ l- in C or ini. gamma* is tread as 23, too. ### decays From 34b72ef3e75956296da93fdfe86d39a9d9d974a6 Mon Sep 17 00:00:00 2001 From: Nasir Mehdi Malik <89008506+nasirmehdimalik@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:32:16 +0530 Subject: [PATCH 358/362] [PWGLF] Added configuration for baryonic resonances efficiency studies for NeNe (#2392) * Add particle data Id for 20Ne in Pythia8 * Injected baryonic resonances nene system * inject baryonic resonance Lambda(1520) and Xi --- ...orLF_ResonancesBaryonic_NeNe_injection.ini | 10 ++ ...atorLF_ResonancesBaryonic_NeNe_injection.C | 142 ++++++++++++++++++ .../pythia8/generator_pythia8_LF_rapidity.C | 6 +- 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_NeNe_injection.ini create mode 100644 MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_NeNe_injection.C diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_NeNe_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_NeNe_injection.ini new file mode 100644 index 000000000..2646765a9 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_NeNe_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_NeNe_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_NeNe_injection.C new file mode 100644 index 000000000..63a9b6922 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_NeNe_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_ResonancesBaryonic_NeNe_injection() { External(); } diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C index b88a9a7a6..0a10286dd 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C @@ -116,7 +116,8 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } pythiaObjectSignal.readString("Random:setSeed = on"); pythiaObjectSignal.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); - + pythiaObjectMinimumBias.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); + mPythiaGun.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); if (!pythiaObjectMinimumBias.init()) { LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; } @@ -141,6 +142,9 @@ class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 } pythiaObjectMinimumBias.readString("Random:setSeed = on"); pythiaObjectMinimumBias.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + + pythiaObjectMinimumBias.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); + mPythiaGun.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); if (!pythiaObjectMinimumBias.init()) { LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; } From e03096e36dbfab3c1c08c6de7a48a0830a1839a6 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Wed, 1 Jul 2026 14:28:29 +0200 Subject: [PATCH 359/362] Add diffraction-tuned pythia8 inel generator (#2393) * Add diffraction-tuned pythia8 inel cfg * Adjust default energy to 13.6 --- .../common/ini/pythia8_inel_difftuned.ini | 2 ++ .../common/ini/tests/pythia8_inel_difftuned.C | 24 ++++++++++++++++++ .../generator/pythia8_inel_difftuned.cfg | 25 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 MC/config/common/ini/pythia8_inel_difftuned.ini create mode 100644 MC/config/common/ini/tests/pythia8_inel_difftuned.C create mode 100644 MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg diff --git a/MC/config/common/ini/pythia8_inel_difftuned.ini b/MC/config/common/ini/pythia8_inel_difftuned.ini new file mode 100644 index 000000000..65ff9b972 --- /dev/null +++ b/MC/config/common/ini/pythia8_inel_difftuned.ini @@ -0,0 +1,2 @@ +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg diff --git a/MC/config/common/ini/tests/pythia8_inel_difftuned.C b/MC/config/common/ini/tests/pythia8_inel_difftuned.C new file mode 100644 index 000000000..7ee7ea397 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_inel_difftuned.C @@ -0,0 +1,24 @@ +int pythia8() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg b/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg new file mode 100644 index 000000000..22dcfbb7e --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg @@ -0,0 +1,25 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### adjust diffraction +### note that PYTHIA calculates the ND sigma via a +### 'remaining from total' formula: no need to put +### that in by hand + +SigmaTotal:mode 0 +SigmaDiffractive:mode 0 +SigmaTotal:sigmaTot 78.6 +SigmaTotal:sigmaEl 0.0 +SigmaTotal:sigmaXB 10.625 +SigmaTotal:sigmaAX 10.625 +SigmaTotal:sigmaXX 9.78 +SigmaTotal:sigmaAXB 0.0 From d70a8d124765e683efc4260b59078d07a0e2a569 Mon Sep 17 00:00:00 2001 From: Rrantu <156880782+Rrantu@users.noreply.github.com> Date: Mon, 6 Jul 2026 09:21:47 +0200 Subject: [PATCH 360/362] Add triggerLc function call to makeStarlightConfig.py (#2398) * Add triggerLc function for Lambda_c particle selection * Refactor process argument choices in makeStarlightConfig.py * Add triggerLc function call to makeStarlightConfig.py --- MC/config/PWGUD/ini/makeStarlightConfig.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MC/config/PWGUD/ini/makeStarlightConfig.py b/MC/config/PWGUD/ini/makeStarlightConfig.py index 46dc4823c..1655624c7 100755 --- a/MC/config/PWGUD/ini/makeStarlightConfig.py +++ b/MC/config/PWGUD/ini/makeStarlightConfig.py @@ -127,6 +127,8 @@ fout.write('funcName = triggerPhi(-0.9,0.9) \n') if 'Kstar' in args.process: fout.write('funcName = triggerKstar(-0.9,0.9) \n') + if 'Lc' in args.process: + fout.write('funcName = triggerLc(-0.9,0.9) \n') ### close outout file fout.close() From f0f978d88d99738f16371a8bcccbb6602ffe36c4 Mon Sep 17 00:00:00 2001 From: Amit Kumar Pradhan <124381334+vetex007@users.noreply.github.com> Date: Tue, 7 Jul 2026 01:05:00 +0530 Subject: [PATCH 361/362] =?UTF-8?q?PWGDQ:=20Add=20Ne=E2=80=93Ne=20prompt?= =?UTF-8?q?=20charmonia=20generator=20configuration=20for=20anchored=20MC?= =?UTF-8?q?=20(#2394)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * PWGDQ: add Ne-Ne prompt charmonia generator configuration * PWGDQ: add Ne-Ne validation test * PWGDQ: reduce Ne-Ne trigger gap from 5 to 2 --- ...romptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini | 7 ++ ...dPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C | 85 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini create mode 100644 MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini new file mode 100644 index 000000000..3668ce8df --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(2,11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} From 5f8f8184bc2053f011fa9bb10565ec0541a98398 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Tue, 7 Jul 2026 12:40:38 +0200 Subject: [PATCH 362/362] External to Hybrid example (#2401) --- MC/config/examples/hybrid/example.json | 30 +++++++++++++++ MC/config/examples/hybrid/examplemanifest.dat | 10 +++++ .../examples/ini/GeneratorExtToHybrid.ini | 3 ++ .../examples/ini/tests/GeneratorExtToHybrid.C | 38 +++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 MC/config/examples/hybrid/example.json create mode 100755 MC/config/examples/hybrid/examplemanifest.dat create mode 100644 MC/config/examples/ini/GeneratorExtToHybrid.ini create mode 100644 MC/config/examples/ini/tests/GeneratorExtToHybrid.C diff --git a/MC/config/examples/hybrid/example.json b/MC/config/examples/hybrid/example.json new file mode 100644 index 000000000..a43766ab7 --- /dev/null +++ b/MC/config/examples/hybrid/example.json @@ -0,0 +1,30 @@ +{ + "generators": [ + { + "name": "pythia8", + "config": { + "config": "${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg", + "hooksFileName": "", + "hooksFuncName": "", + "includePartonEvent": false, + "particleFilter": "", + "verbose": 0 + } + }, + { + "name": "evtpool", + "config": { + "eventPoolPath" : "${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/hybrid/examplemanifest.dat", + "skipNonTrackable" : true, + "roundRobin" : false, + "randomize" : true, + "rngseed" : 0, + "randomphi" : false + } + } + ], + "fractions": [ + 1, + 1 + ] +} diff --git a/MC/config/examples/hybrid/examplemanifest.dat b/MC/config/examples/hybrid/examplemanifest.dat new file mode 100755 index 000000000..5cbfda065 --- /dev/null +++ b/MC/config/examples/hybrid/examplemanifest.dat @@ -0,0 +1,10 @@ +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/001/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/002/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/003/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/004/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/005/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/006/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/007/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/008/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/009/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/010/evtpool.root \ No newline at end of file diff --git a/MC/config/examples/ini/GeneratorExtToHybrid.ini b/MC/config/examples/ini/GeneratorExtToHybrid.ini new file mode 100644 index 000000000..62e0986b7 --- /dev/null +++ b/MC/config/examples/ini/GeneratorExtToHybrid.ini @@ -0,0 +1,3 @@ +[GeneratorHybrid] +configFile = ${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/hybrid/example.json +switchExtToHybrid = true \ No newline at end of file diff --git a/MC/config/examples/ini/tests/GeneratorExtToHybrid.C b/MC/config/examples/ini/tests/GeneratorExtToHybrid.C new file mode 100644 index 000000000..2694d57e4 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorExtToHybrid.C @@ -0,0 +1,38 @@ +int Hybrid() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + return 0; +}