|
| 1 | +#include "FairGenerator.h" |
| 2 | +#include "Generators/GeneratorPythia8.h" |
| 3 | +#include "Pythia8/Pythia.h" |
| 4 | +#include "TRandom.h" |
| 5 | + |
| 6 | +#include <string> |
| 7 | +#include <vector> |
| 8 | + |
| 9 | +using namespace o2::eventgen; |
| 10 | + |
| 11 | +namespace o2 |
| 12 | +{ |
| 13 | +namespace eventgen |
| 14 | +{ |
| 15 | + |
| 16 | +class GeneratorLikeSignDimuonGapTriggered : public o2::eventgen::GeneratorPythia8 { |
| 17 | +public: |
| 18 | + |
| 19 | + /// constructor |
| 20 | + GeneratorLikeSignDimuonGapTriggered(int inputTriggerRatio = 3) |
| 21 | + { |
| 22 | + mGeneratedEvents = 0; |
| 23 | + mInverseTriggerRatio = inputTriggerRatio; |
| 24 | + mRequiredMuonMultiplicity = 2; |
| 25 | + mMuonRapidityMin = -4.3; |
| 26 | + mMuonRapidityMax = -2.2; |
| 27 | + mVerbose = false; |
| 28 | + |
| 29 | + // minimum-bias Pythia8 instance |
| 30 | + auto seed = (gRandom->TRandom::GetSeed() % 900000000); |
| 31 | + TString pathconfigMB = gSystem->ExpandPathName("$O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/pythia8/generator/pythia8_inel_cr2.cfg"); |
| 32 | + pythiaMBgen.readFile(pathconfigMB.Data()); |
| 33 | + pythiaMBgen.readString("Random:setSeed on"); |
| 34 | + pythiaMBgen.readString("Random:seed " + std::to_string(seed)); |
| 35 | + } |
| 36 | + /// Destructor |
| 37 | + ~GeneratorLikeSignDimuonGapTriggered() = default; |
| 38 | + |
| 39 | + void setMuonMultiplicity(int n) { mRequiredMuonMultiplicity = n; } |
| 40 | + void setMuonRapidity(double yMin, double yMax) |
| 41 | + { |
| 42 | + mMuonRapidityMin = yMin; |
| 43 | + mMuonRapidityMax = yMax; |
| 44 | + } |
| 45 | + void setVerbose(bool v) { mVerbose = v; } |
| 46 | + |
| 47 | + protected: |
| 48 | + |
| 49 | + Bool_t generateEvent() override |
| 50 | + { |
| 51 | + if (mGeneratedEvents % mInverseTriggerRatio == 0) { |
| 52 | + // signal event: keep generating until like-sign dimuon found |
| 53 | + bool genOk = false; |
| 54 | + while (!genOk) { |
| 55 | + mPythia.event.reset(); |
| 56 | + genOk = GeneratorPythia8::generateEvent(); |
| 57 | + if (genOk) genOk = selectLikeSignDimuon(mPythia.event); |
| 58 | + } |
| 59 | + } else { |
| 60 | + // minimum-bias event from the independent generator |
| 61 | + bool genOk = false; |
| 62 | + pythiaMBgen.event.reset(); |
| 63 | + while (!genOk) genOk = pythiaMBgen.next(); |
| 64 | + mPythia.event = pythiaMBgen.event; |
| 65 | + } |
| 66 | + mGeneratedEvents++; |
| 67 | + if (mVerbose) mOutputEvent.list(); |
| 68 | + return true; |
| 69 | + } |
| 70 | + |
| 71 | + Bool_t Init() override |
| 72 | + { |
| 73 | + GeneratorPythia8::Init(); |
| 74 | + pythiaMBgen.init(); |
| 75 | + return true; |
| 76 | + } |
| 77 | + |
| 78 | + // Accept the event if at least mRequiredMuonMultiplicity muons fall in the rapidity window AND at least one same-sign pair exists among them. |
| 79 | + bool selectLikeSignDimuon(Pythia8::Event& event) |
| 80 | + { |
| 81 | + std::vector<const Pythia8::Particle*> muonsInWindow; |
| 82 | + for (int ipa = 0; ipa < event.size(); ++ipa) { |
| 83 | + if (std::abs(event[ipa].id()) != 13) continue; |
| 84 | + float rap = event[ipa].y(); |
| 85 | + if (rap > mMuonRapidityMin && rap < mMuonRapidityMax) { |
| 86 | + muonsInWindow.push_back(&event[ipa]); |
| 87 | + } |
| 88 | + } |
| 89 | + if ((int)muonsInWindow.size() < mRequiredMuonMultiplicity) return false; |
| 90 | + for (size_t i = 0; i < muonsInWindow.size(); ++i) { |
| 91 | + for (size_t j = i + 1; j < muonsInWindow.size(); ++j) { |
| 92 | + if (muonsInWindow[i]->id() * muonsInWindow[j]->id() > 0) return true; |
| 93 | + } |
| 94 | + } |
| 95 | + return false; |
| 96 | + } |
| 97 | + |
| 98 | + private: |
| 99 | + Pythia8::Event mOutputEvent; |
| 100 | + |
| 101 | + unsigned long long mGeneratedEvents; |
| 102 | + int mInverseTriggerRatio; |
| 103 | + Pythia8::Pythia pythiaMBgen; |
| 104 | + |
| 105 | + int mRequiredMuonMultiplicity; |
| 106 | + double mMuonRapidityMin; |
| 107 | + double mMuonRapidityMax; |
| 108 | + bool mVerbose; |
| 109 | +}; |
| 110 | + |
| 111 | +} // namespace eventgen |
| 112 | +} // namespace o2 |
| 113 | + |
| 114 | +FairGenerator* GeneratorLikeSignDimuonGapTriggered_dq(double rapidityMin = -4.3, double rapidityMax = -2.2, int requiredMuons = 2, int inputTriggerRatio = 3, bool verbose = false) |
| 115 | +{ |
| 116 | + auto gen = new o2::eventgen::GeneratorLikeSignDimuonGapTriggered(inputTriggerRatio); |
| 117 | + gen->setMuonMultiplicity(requiredMuons); |
| 118 | + gen->setMuonRapidity(rapidityMin, rapidityMax); |
| 119 | + gen->setVerbose(verbose); |
| 120 | + |
| 121 | + // random seed |
| 122 | + gen->readString("Random:setSeed on"); |
| 123 | + uint random_seed; |
| 124 | + unsigned long long int random_value = 0; |
| 125 | + std::ifstream urandom("/dev/urandom", std::ios::in | std::ios::binary); |
| 126 | + urandom.read(reinterpret_cast<char*>(&random_value), sizeof(random_seed)); |
| 127 | + gen->readString(Form("Random:seed = %d", random_value % 900000001)); |
| 128 | + |
| 129 | + return gen; |
| 130 | +} |
0 commit comments