From f016ee96ae3a80bd56f93fdbbe276d5928b8f801 Mon Sep 17 00:00:00 2001 From: tiantian cheng Date: Thu, 17 Jul 2025 13:57:12 +0800 Subject: [PATCH 1/2] New files for producing eventpool of undecayed XiC --- ...eneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini | 8 ++++ ...eneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini | 8 ++++ .../pythia8_charmhadronic_XiC_NoDecay.cfg | 42 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini create mode 100644 MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini create mode 100644 MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg 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_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/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 a783fc3e1284fdee3088880de0c89abcbc1690a1 Mon Sep 17 00:00:00 2001 From: tiantian cheng Date: Sun, 20 Jul 2025 14:01:03 +0800 Subject: [PATCH 2/2] add scripts for testing the new .ini files --- ..._D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.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 ++ ...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 +++++++++++ 15 files changed, 765 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_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_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 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_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_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