diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFMuon.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFMuon.C new file mode 100644 index 000000000..b84608346 --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFMuon.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_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_cr2_forceddecayscharm_semimuonic.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, 13); + myGen->setDaughterRapidity(-6., -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_bbbar_forceddecayscharmbeauty_semimuonic.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, 13); + myGen->setDaughterRapidity(-6., -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_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, 13); + myGen->setDaughterRapidity(-6., -1.); + return myGen; +} diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap1_pp13600GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap1_pp13600GeV.ini new file mode 100644 index 000000000..101e8ce12 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap1_pp13600GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(1, 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/GeneratorHFGapTriggered_BeautyNoForcedDecay_Muon_pp13600GeV_Gap1.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Muon_pp13600GeV_Gap1.ini new file mode 100644 index 000000000..0641b5724 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Muon_pp13600GeV_Gap1.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFMuon.C +funcName = GeneratorPythia8GapTriggeredBeautyNoForcedDecays(1, 3, -6, -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_Muon_pp13600GeV_Gap1.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Muon_pp13600GeV_Gap1.ini new file mode 100644 index 000000000..302abe087 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Muon_pp13600GeV_Gap1.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFMuon.C +funcName = GeneratorPythia8GapTriggeredCharmLepton(1, 1, -6, -1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap1_pp13600GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap1_pp13600GeV.C new file mode 100644 index 000000000..0332e54fc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap1_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/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Muon_pp13600GeV_Gap1.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Muon_pp13600GeV_Gap1.C new file mode 100644 index 000000000..99e697a46 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Muon_pp13600GeV_Gap1.C @@ -0,0 +1,113 @@ +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./1; // one event triggered out of 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/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_Muon_pp13600GeV_Gap1.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Muon_pp13600GeV_Gap1.C new file mode 100644 index 000000000..41ee27f54 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Muon_pp13600GeV_Gap1.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./1.; // one event triggered out of 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/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_bbbar_forceddecayscharmbeauty_semimuonic.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_forceddecayscharmbeauty_semimuonic.cfg new file mode 100644 index 000000000..7dd200525 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_forceddecayscharmbeauty_semimuonic.cfg @@ -0,0 +1,105 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # 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 for charm +### D+ +411:oneChannel = 1 0.0868 0 -311 -13 14 +411:addChannel = 1 0.0527 0 -313 -13 14 +411:addChannel = 1 0.0019 0 -321 211 -13 14 +### D0 +421:oneChannel = 1 0.03418 0 -321 -13 14 +421:addChannel = 1 0.02060 0 -323 -13 14 +421:addChannel = 1 0.000421 0 -321 111 -13 14 +421:addChannel = 1 0.00267 0 -211 -13 14 +421:addChannel = 1 0.00145 0 -211 111 -13 14 +### Ds +431:oneChannel = 1 0.0224 0 333 -13 14 +431:addChannel = 1 0.0224 0 221 -13 14 +431:addChannel = 1 0.0080 0 331 -13 14 + +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -13 14 +### Xi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -13 14 +### Xi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -13 14 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -13 14 + + +### only semileptonic decays for beauty +### B0 +511:oneChannel = 1 0.0212000 0 -411 -13 14 +511:addChannel = 1 0.0490000 0 -413 -13 14 +511:addChannel = 1 0.0028500 0 -10413 -13 14 +511:addChannel = 1 0.0025000 0 -20413 -13 14 +511:addChannel = 1 0.0014100 0 -415 -13 14 +511:addChannel = 1 0.0001500 0 -211 -13 14 +511:addChannel = 1 0.0002940 0 -213 -13 14 + +### B+ +521:oneChannel = 1 0.022100 0 -421 -13 14 +521:addChannel = 1 0.055300 0 -423 -13 14 +521:addChannel = 1 0.000900 0 -10421 -13 14 +521:addChannel = 1 0.002840 0 -10423 -13 14 +521:addChannel = 1 0.001700 0 -20423 -13 14 +521:addChannel = 1 0.001590 0 -425 -13 14 +521:addChannel = 1 0.000300 0 -431 321 -13 14 +521:addChannel = 1 0.000290 0 -433 321 -13 14 +521:addChannel = 1 0.000078 0 111 -13 14 +521:addChannel = 1 0.000035 0 221 -13 14 +521:addChannel = 1 0.000024 0 331 -13 14 +521:addChannel = 1 0.000119 0 223 -13 14 +521:addChannel = 1 0.000158 0 113 -13 14 + +### Bs +531:oneChannel = 1 0.023100 0 -431 -13 14 +531:addChannel = 1 0.052000 0 -433 -13 14 +531:addChannel = 1 0.000106 0 -321 -13 14 + +### Lambdab +5122:oneChannel = 1 0.06200 0 4122 13 -14 +5122:addChannel = 1 0.00790 0 14122 13 -14 +5122:addChannel = 1 0.01300 0 4124 13 -14 + +# Forced exclusive decay; BR=1 is not a physical branching fraction +### Xi_{b}^{-} +5132:oneChannel = 1 1.0 0 4132 13 -14 +### Xi_{b}^{0} +5232:oneChannel = 1 1.0 0 4232 13 -14 +### Omega_{b}^{-} +5332:oneChannel = 1 1.0 0 4332 13 -14 + +# 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_cr2_forceddecayscharm_semimuonic.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_cr2_forceddecayscharm_semimuonic.cfg new file mode 100644 index 000000000..330b31a23 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_cr2_forceddecayscharm_semimuonic.cfg @@ -0,0 +1,67 @@ +### main + +Main:timesAllowErrors 2000 +#allow more errors in the pythia. + + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600 # 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 +### D+ +411:oneChannel = 1 0.0868 0 -311 -13 14 +411:addChannel = 1 0.0527 0 -313 -13 14 +411:addChannel = 1 0.0019 0 -321 211 -13 14 +### D0 +421:oneChannel = 1 0.03418 0 -321 -13 14 +421:addChannel = 1 0.02060 0 -323 -13 14 +421:addChannel = 1 0.000421 0 -321 111 -13 14 +421:addChannel = 1 0.00267 0 -211 -13 14 +421:addChannel = 1 0.00145 0 -211 111 -13 14 +### Ds +431:oneChannel = 1 0.0224 0 333 -13 14 +431:addChannel = 1 0.0224 0 221 -13 14 +431:addChannel = 1 0.0080 0 331 -13 14 + +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -13 14 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -13 14 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -13 14 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -13 14 + +# 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/runAnchoredDYmumu_pp_13600_Gap1.sh b/MC/run/PWGEM/runAnchoredDYmumu_pp_13600_Gap1.sh new file mode 100644 index 000000000..86e411252 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYmumu_pp_13600_Gap1.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# +# Steering script for DY->dimuon MC anchored to LHC26 pp 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="GeneratorDYmumu_GapTriggered_Gap1_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 diff --git a/MC/run/PWGEM/runAnchoredHFmumu_pp_13600_Gap1.sh b/MC/run/PWGEM/runAnchoredHFmumu_pp_13600_Gap1.sh new file mode 100644 index 000000000..6e60d1815 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredHFmumu_pp_13600_Gap1.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC26 pp 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=LHC26e9 +export ALIEN_JDL_LPMANCHORRUN=559348 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC26ac +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_Muon_pp13600GeV_Gap1.ini" +elif [[ $RNDSIG -ge 20 && $RNDSIG -lt 100 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_BeautyNoForcedDecay_Muon_pp13600GeV_Gap1.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