Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/PSITOJPSIPIPI.DEC
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Decay J/psi
### from DECAY.DEC
1.000 e+ e- PHOTOS VLL;
Enddecay
Decay psi(2S)
1.000 J/psi pi+ pi- VVPIPI;
Enddecay
End
10 changes: 10 additions & 0 deletions MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/X3872TOJPSIPIPI.DEC
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Decay X_1(3872)
#### Breit-Wigner function for the pion distribution (S-Wave approximation)
1.000 J/psi pi+ pi- XJPSIRHO0PIPI_S;
Enddecay
Decay J/psi
### from DECAY.DEC
1.000 e+ e- PHOTOS VLL;
Enddecay

End
117 changes: 117 additions & 0 deletions MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,75 @@ class O2_GeneratorParamPsiPbPb5TeV : public GeneratorTGenerator
GeneratorParam* paramPsi = nullptr;
};


class O2_GeneratorParamX3872MidY : public GeneratorTGenerator
{

public:
O2_GeneratorParamX3872MidY() : GeneratorTGenerator("ParamX3872MidY")
{
paramX3872 = new GeneratorParam(1, -1, PtX3872pp13TeV, YX3872pp13TeV, V2X3872pp13TeV, IpX3872pp13TeV);
paramX3872->SetMomentumRange(0., 1.e6);
paramX3872->SetPtRange(0., 1000.);
paramX3872->SetYRange(-1.0, 1.0);
paramX3872->SetPhiRange(0., 360.);
paramX3872->SetDecayer(new TPythia6Decayer()); // Pythia
paramX3872->SetForceDecay(kNoDecay); // particle left undecayed
setTGenerator(paramX3872);
};

~O2_GeneratorParamX3872MidY()
{
delete paramX3872;
};

Bool_t Init() override
{
GeneratorTGenerator::Init();
paramX3872->Init();
return true;
}

void SetNSignalPerEvent(Int_t nsig) { paramX3872->SetNumberParticles(nsig); }

//-------------------------------------------------------------------------//
static Double_t PtX3872pp13TeV(const Double_t* px, const Double_t* /*dummy*/)
{
// prompt X3872 pT
// pp, 13TeV (tuned LHCb pp 13 TeV)
//
const Double_t kC = 7.64519e+00 ;
const Double_t kpt0 = 5.30628e+00;
const Double_t kn = 3.30887e+00;
Double_t pt = px[0];
return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn);
}

//-------------------------------------------------------------------------//
static Double_t YX3872pp13TeV(const Double_t* py, const Double_t* /*dummy*/)
{
// flat rapidity distribution assumed at midrapidity
return 1.;
}

//-------------------------------------------------------------------------//
static Double_t V2X3872pp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/)
{
// X3872 v2
return 0.;
}

//-------------------------------------------------------------------------//
static Int_t IpX3872pp13TeV(TRandom*)
{
return 9920443;
}

private:
GeneratorParam* paramX3872 = nullptr;
};


} // namespace eventgen
} // namespace o2

Expand Down Expand Up @@ -741,6 +810,31 @@ FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp13TeV()
return genCocktailEvtGen;
}


FairGenerator*
GeneratorParamPromptPsiToJpsiPiPiEvtGen_pp13TeV(TString pdgs = "100443")
{
auto gen = new o2::eventgen::GeneratorEvtGen<o2::eventgen::O2_GeneratorParamPsiMidY>();
gen->SetNSignalPerEvent(1); // number of jpsis per event

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));
}
TString pathO2 = gSystem->ExpandPathName("$O2DPG_ROOT/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen");
gen->SetDecayTable(Form("%s/PSITOJPSIPIPI.DEC", pathO2.Data()));

// print debug
gen->PrintDebug();

return gen;
}


FairGenerator*
GeneratorParamPromptJpsiToMuonEvtGen_pp13TeV(TString pdgs = "443")
{
Expand Down Expand Up @@ -844,6 +938,29 @@ FairGenerator*
}


FairGenerator*
GeneratorParamX3872ToJpsiEvtGen_pp13TeV(TString pdgs = "9920443")
{
auto gen = new o2::eventgen::GeneratorEvtGen<o2::eventgen::O2_GeneratorParamX3872MidY>();
gen->SetNSignalPerEvent(1); // number of jpsis per event

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));
}
TString pathO2 = gSystem->ExpandPathName("$O2DPG_ROOT/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen");
gen->SetDecayTable(Form("%s/X3872TOJPSIPIPI.DEC", pathO2.Data()));

// print debug
gen->PrintDebug();

return gen;
}




Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ public:
case 7: // generate prompt charmonia cocktail at forward rapidity at 5TeV
mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToMuonEvtGen_PbPb5TeV();
break;

case 8: // generate prompt X_1(3872) to Jpsi pi pi at midrapidity
mGeneratorParam = (Generator*)GeneratorParamX3872ToJpsiEvtGen_pp13TeV("9920443");
break;
case 9: // generate prompt psi2S to Jpsi pi pi at midrapidity
mGeneratorParam = (Generator*)GeneratorParamPromptPsiToJpsiPiPiEvtGen_pp13TeV("100443");
break;
}
mGeneratorParam->Init();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### The external generator derives from GeneratorPythia8.
[GeneratorExternal]
fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C
funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,9)
[GeneratorPythia8]
config=${O2DPG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### The external generator derives from GeneratorPythia8.
[GeneratorExternal]
fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C
funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,8)
[GeneratorPythia8]
config=${O2DPG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
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<o2::MCTrack>* 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);
Bool_t hasPsi2SMoth = 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]) {
// check daughters
std::cout << "Signal PDG: " << pdg << "\n";
for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) {
auto pdgDau = tracks->at(j).GetPdgCode();
std::cout << "Daughter " << j << " is: " << pdgDau << "\n";
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();
std::cout << "Lepton daughter particles of mother " << trackJpsi.GetPdgCode() << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n";
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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
int External()
{
int checkPdgSignal[] = {9920443}; // pdg code X3872
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<o2::MCTrack>* tracks{};
tree->SetBranchAddress("MCTrack", &tracks);

int nLeptons{};
int nAntileptons{};
int nLeptonPairs{};
int nLeptonPairsToBeDone{};
int nSignalX3872{};
int nSignalPionsPos{};
int nSignalPionsNeg{};
int nSignalPsi2S{};
int nSignalX3872WithinAcc{};
int nSignalPionsPosWithinAcc{};
int nSignalPionsNegWithinAcc{};
auto nEvents = tree->GetEntries();
o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine);
Bool_t hasPsi2SMoth = 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 idX3872 = -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]) {
// check daughters
std::cout << "Signal PDG: " << pdg << "\n";
for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) {
auto pdgDau = tracks->at(j).GetPdgCode();
std::cout << "Daughter " << j << " is: " << pdgDau << "\n";
if(TMath::Abs(pdgDau) == checkPdgDecay[0] ) { nSignalX3872++; if( std::abs(track.GetRapidity()) < rapidityWindow) nSignalX3872WithinAcc++; idX3872 = 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 trackX3872 = tracks->at(idX3872);
for (int j{trackX3872.getFirstDaughterTrackId()}; j <= trackX3872.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();
std::cout << "Lepton daughter particles of mother " << trackX3872.GetPdgCode() << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n";
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 <- X3872): " << nSignalX3872 << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalX3872WithinAcc << "\n"
<< "#signal (pi+ <- X3872): " << nSignalPionsPos << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalPionsPosWithinAcc << "\n"
<< "#signal (pi- <- X3872): " << 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;
}