ROOT logo
/* pt generation limits */
const Double_t ptMin = 0.;
const Double_t ptMax = 10.;
/* y generation limits */
const Double_t yMin = -0.1;
const Double_t yMax = 0.1;
/* phi generation limits */
const Double_t phiMin = -TMath::Pi();
const Double_t phiMax = TMath::Pi();

const Double_t pionMass = 139.57018e-3;
const Double_t kaonMass = 493.677e-3;
const Double_t protonMass = 938.272046e-3;

PhiModel(Int_t ngen = 1.e6)
{
    
    Double_t m = TDatabasePDG::Instance()->GetParticle("phi")->Mass();
    Double_t w = TDatabasePDG::Instance()->GetParticle("phi")->Width();
    Double_t dm[2] = {kaonMass, kaonMass};
    Int_t di[2] = {3, -3};
    
    ResonanceModel(m, w, 2, dm, di, "PhiModel.root", ngen);
}

KStarModel(Int_t ngen = 1.e6, Bool_t antiparticle = kFALSE)
{
    
    Double_t m = TDatabasePDG::Instance()->GetParticle("K*0")->Mass();
    Double_t w = TDatabasePDG::Instance()->GetParticle("K*0")->Width();
    Double_t dm[2] = {kaonMass, pionMass};
    Int_t di[2] = {3, -2};
    if (antiparticle) {di[0] = -di[0]; di[1] = -di[1];}
    
    if (antiparticle) ResonanceModel(m, w, 2, dm, di, "KStarBarModel.root", ngen);
    else ResonanceModel(m, w, 2, dm, di, "KStarModel.root", ngen);
}

Lambda1520Model(Int_t ngen = 1.e6, Bool_t antiparticle = kFALSE)
{
    
    Double_t m = 1519.54e-3; /* GeV */
    Double_t w = 15.73e-3; /* GeV */
    Double_t dm[2] = {protonMass, kaonMass};
    Int_t di[2] = {4, -3};
    if (antiparticle) {di[0] = -di[0]; di[1] = -di[1];}
    
    if (antiparticle) ResonanceModel(m, w, 2, dm, di, "Lambda1520BarModel.root", ngen);
    else ResonanceModel(m, w, 2, dm, di, "Lambda1520Model.root", ngen);
}

ResonanceModel(Double_t resonanceMass, Double_t resonanceWidth, Int_t nDaughters, Double_t *daughterMass, Int_t *daughterID, const Char_t *outname, Int_t ngen = 1.e6)
{
    
    /* functions */
    TF1 *fBW = new TF1("fBW", "[0] * TMath::BreitWigner(x, [1], [2])");
    fBW->SetParameter(0, ngen / 100.);
    fBW->SetParameter(1, resonanceMass);
    fBW->SetParameter(2, resonanceWidth);
    
    /* histograms */
    Int_t massBins = 50;
    Int_t ptBins = 50;
    Double_t massMin = resonanceMass - 10. * resonanceWidth;
    Double_t massMax = resonanceMass + 10. * resonanceWidth;
    
    TH1F *hGenMass = new TH1F("hGenMass", ";m (GeV/#it{c}^{2});", massBins, massMin, massMax);
    hGenMass->SetMarkerColor(2);
    hGenMass->SetMarkerStyle(25);
    hGenMass->Sumw2();
    
    TH1F *hRecMass = new TH1F("hRecMass", ";m (GeV/#it{c}^{2});", massBins, massMin, massMax);
    hRecMass->SetMarkerColor(4);
    hRecMass->SetMarkerStyle(20);
    hRecMass->Sumw2();
    
    TH1F *hGenPt = new TH1F("hGenPt", ";#it{p}_{T} (GeV/#it{c});", ptBins, ptMin, ptMax);
    hGenPt->SetMarkerColor(2);
    hGenPt->SetMarkerStyle(25);
    hGenPt->Sumw2();
    
    TH1F *hRecPt = new TH1F("hRecPt", ";#it{p}_{T} (GeV/#it{c});", ptBins, ptMin, ptMax);
    hRecPt->SetMarkerColor(4);
    hRecPt->SetMarkerStyle(20);
    hRecPt->Sumw2();
    
    /* init random generator */
    TRandom *gRandom = new TRandom();
    gRandom->SetSeed(123456789);
    
    /* resonance four-momentum */
    TLorentzVector resonance;
    TLorentzVector recoP;
    TGenPhaseSpace decay;
    
    /* benchmark */
    TBenchmark bm;
    bm.Start("time");
    
    /* loop over generation */
    Int_t igen = 0;
    while (igen < ngen) {
        
        /* generate mass */
        Double_t mass = gRandom->BreitWigner(resonanceMass, resonanceWidth);
        /* generate pt */
        Double_t pt = gRandom->Uniform(ptMin, ptMax);
        /* generate y */
        Double_t y = gRandom->Uniform(yMin, yMax);
        /* get eta */
        Double_t eta = y2eta(pt, resonanceMass, y);
        /* generate phi */
        Double_t phi = gRandom->Uniform(phiMin, phiMax);
        
        /* init resonance four-momentum */
        resonance.SetPtEtaPhiM(pt, eta, phi, mass);
        /* decay particle, if allowed */
        if (!decay.SetDecay(resonance, nDaughters, daughterMass)) continue;
        
        /* decay allowed */
        igen++;
        decay.Generate();
        
        /* fill gen plots */
        hGenMass->Fill(mass);
        hGenPt->Fill(pt);
        
        /* reconstructed invariant mass */
        recoP.SetPtEtaPhiM(0., 0., 0., 0.);
        TLorentzVector *daughterP;
        Bool_t daughterLost = kFALSE;
        for (Int_t idaugh = 0; idaugh < nDaughters; idaugh++) {
            daughterP = decay.GetDecay(idaugh);
            recoP += *daughterP;
            Double_t eff = GetEfficiency(daughterP, daughterID[idaugh]);
            if (gRandom->Uniform(0., 1.) > eff) daughterLost = kTRUE;
        }
        
        /* fill reco plots */
        if (!daughterLost) {
            hRecMass->Fill(recoP.M());
            hRecPt->Fill(pt);
        }
    }
    
    /* benchmark */
    bm.Stop("time");
    bm.Print("time");
    
    gStyle->SetHistMinimumZero();
    
    TCanvas *cGenRec = new TCanvas("cGenRec", "cRecGen", 600, 600);
    cGenRec->Divide(1, 2);
    cGenRec->cd(1);
    hGenMass->DrawCopy();
    hRecMass->DrawCopy("same");
    cGenRec->cd(2);
    hGenPt->DrawCopy();
    hRecPt->DrawCopy("same");
    
    TCanvas *cEff = new TCanvas("cEff", "cEff", 600, 600);
    cEff->Divide(1, 2);
    cEff->cd(1);
    TH1 *hEffMass = (TH1 *)hRecMass->Clone("hEffMass");
    hEffMass->Divide(hEffMass, hGenMass, 1., 1., "B");
    hEffMass->DrawCopy();
    cEff->cd(2);
    TH1 *hEffPt = (TH1 *)hRecPt->Clone("hEffPt");
    hEffPt->Divide(hEffPt, hGenPt, 1., 1., "B");
    hEffPt->DrawCopy();
    
    TFile *fout = TFile::Open(outname, "RECREATE");
    hGenMass->Write();
    hRecMass->Write();
    hGenPt->Write();
    hRecPt->Write();
    hEffPt->Write();
    fout->Close();
    
}

/*****************************************************************/

TFile *fTrackEff = NULL;
TFile *fMatchEff = NULL;

Double_t
GetEfficiency(TLorentzVector *lv, Int_t ipart)
{
    
    Char_t *pname[5] = {"", "", "pion", "kaon", "proton"};
    Char_t *cname[2] = {"positive", "negative"};
    
    Int_t icharge = ipart > 0 ? 0 : 1;
    ipart = TMath::Abs(ipart);

    Double_t pt = lv->Pt();
    Double_t eta = lv->Eta();
    Double_t phi = lv->Phi();

    if (!fTrackEff) fTrackEff = TFile::Open("TOF_trackingEfficiency.root");
    if (!fMatchEff) fMatchEff = TFile::Open("TOF_matchingEfficiency.root");
    TH1 *hTrackEff = fTrackEff->Get(Form("hTrackingEff_MB_%s_%s", pname[ipart], cname[icharge]));
    TH1 *hMatchEff = fMatchEff->Get(Form("hMatchEff_MB_%s_%s", pname[ipart], cname[icharge]));
    
    Double_t trackEff = hTrackEff->Interpolate(pt);
    Double_t matchEff = hMatchEff->Interpolate(pt);

    Double_t trackEff_GF = TrackingEff_geantflukaCorrection(ipart, icharge)->Eval(pt);
    Double_t matchEff_GF = TOFmatchMC_geantflukaCorrection(ipart, icharge)->Eval(pt);
    
    Double_t eff = trackEff;
    if (ipart == 3 && pt > 0.6) eff = trackEff * matchEff;
    if (ipart == 4 && pt > 1.1) eff = trackEff * matchEff;
    
    Double_t pidEff = 0.954;
    eff *= pidEff;

//    return trackEff;
    return eff;
}

/*****************************************************************/

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));
}
Double_t 
eta2y(Double_t pt, Double_t mass, Double_t eta){
    Double_t mt = TMath::Sqrt(mass * mass + pt * pt);
    return TMath::ASinH(pt / mt * TMath::SinH(eta));
}

/*****************************************************************/

TF1 *fTrackEff_GF[5][2] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
TF1 *fMatchEff_GF[5][2] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

TF1 *
TrackingEff_geantflukaCorrection(Int_t ipart, Int_t icharge)
{
    
    if (fTrackEff_GF[ipart][icharge]) return fTrackEff_GF[ipart][icharge];
    
    Char_t *pname[3] = {"pion", "kaon", "proton"};
    Char_t *cname[2] = {"positive", "negative"};
    
    TF1 *f;
    if (ipart == 3 && icharge == 1)
        f = new TF1(Form("fGeantFluka_%s_%s", pname[ipart - 2], cname[icharge]), "TrackingPtGeantFlukaCorrectionKaMinus(x)", 0., 5.);
    else if (ipart == 4 && icharge == 1)
        f = new TF1(Form("fGeantFluka_%s_%s", pname[ipart - 2], cname[icharge]), "TrackingPtGeantFlukaCorrectionPrMinus(x)", 0., 5.);
    else
        f = new TF1(Form("fGeantFluka_%s_%s", pname[ipart - 2], cname[icharge]), "TrackingPtGeantFlukaCorrectionNull(x)", 0., 5.);
    
    fTrackEff_GF[ipart][icharge] = f;
    return f;
}

Double_t
TrackingPtGeantFlukaCorrectionNull(Double_t pTmc)
{
    return 1.;
}

Double_t
TrackingPtGeantFlukaCorrectionPrMinus(Double_t pTmc)
{
    return (1 - 0.129758 *TMath::Exp(-pTmc*0.679612));
}

Double_t
TrackingPtGeantFlukaCorrectionKaMinus(Double_t pTmc)
{
    return TMath::Min((0.972865 + 0.0117093*pTmc), 1.);
}

/*****************************************************************/

TF1 *
TOFmatchMC_geantflukaCorrection(Int_t ipart, Int_t icharge)
{

    if (fMatchEff_GF[ipart][icharge]) return fMatchEff_GF[ipart][icharge];
    
    Char_t *pname[3] = {"pion", "kaon", "proton"};
    Char_t *cname[2] = {"positive", "negative"};

    TF1 *f;
    if (ipart == 3 && icharge == 1)
        f = new TF1(Form("fGeantFluka_%s_%s", pname[ipart - 2], cname[icharge]), "MatchingPtGeantFlukaCorrectionKaMinus(x)", 0., 5.);
    else if (ipart == 4 && icharge == 1)
        f = new TF1(Form("fGeantFluka_%s_%s", pname[ipart - 2], cname[icharge]), "MatchingPtGeantFlukaCorrectionPrMinus(x)", 0., 5.);
    else
        f = new TF1(Form("fGeantFluka_%s_%s", pname[ipart - 2], cname[icharge]), "MatchingPtGeantFlukaCorrectionNull(x)", 0., 5.);
    
    fMatchEff_GF[ipart][icharge] = f;
    return f;
}

Double_t
MatchingPtGeantFlukaCorrectionNull(Double_t pTmc)
{
    return 1.;
}

Double_t
MatchingPtGeantFlukaCorrectionPrMinus(Double_t pTmc)
{
    Float_t ptTPCoutP =pTmc*(1-6.81059e-01*TMath::Exp(-pTmc*4.20094));
    return (TMath::Power(1 - 0.129758*TMath::Exp(-ptTPCoutP*0.679612),0.07162/0.03471));
}

Double_t
MatchingPtGeantFlukaCorrectionKaMinus(Double_t pTmc)
{
    Float_t ptTPCoutK=pTmc*(1- 3.37297e-03/pTmc/pTmc - 3.26544e-03/pTmc);
    return TMath::Min((TMath::Power(0.972865 + 0.0117093*ptTPCoutK,0.07162/0.03471)), 1.);
 ResonanceModel.C:1
 ResonanceModel.C:2
 ResonanceModel.C:3
 ResonanceModel.C:4
 ResonanceModel.C:5
 ResonanceModel.C:6
 ResonanceModel.C:7
 ResonanceModel.C:8
 ResonanceModel.C:9
 ResonanceModel.C:10
 ResonanceModel.C:11
 ResonanceModel.C:12
 ResonanceModel.C:13
 ResonanceModel.C:14
 ResonanceModel.C:15
 ResonanceModel.C:16
 ResonanceModel.C:17
 ResonanceModel.C:18
 ResonanceModel.C:19
 ResonanceModel.C:20
 ResonanceModel.C:21
 ResonanceModel.C:22
 ResonanceModel.C:23
 ResonanceModel.C:24
 ResonanceModel.C:25
 ResonanceModel.C:26
 ResonanceModel.C:27
 ResonanceModel.C:28
 ResonanceModel.C:29
 ResonanceModel.C:30
 ResonanceModel.C:31
 ResonanceModel.C:32
 ResonanceModel.C:33
 ResonanceModel.C:34
 ResonanceModel.C:35
 ResonanceModel.C:36
 ResonanceModel.C:37
 ResonanceModel.C:38
 ResonanceModel.C:39
 ResonanceModel.C:40
 ResonanceModel.C:41
 ResonanceModel.C:42
 ResonanceModel.C:43
 ResonanceModel.C:44
 ResonanceModel.C:45
 ResonanceModel.C:46
 ResonanceModel.C:47
 ResonanceModel.C:48
 ResonanceModel.C:49
 ResonanceModel.C:50
 ResonanceModel.C:51
 ResonanceModel.C:52
 ResonanceModel.C:53
 ResonanceModel.C:54
 ResonanceModel.C:55
 ResonanceModel.C:56
 ResonanceModel.C:57
 ResonanceModel.C:58
 ResonanceModel.C:59
 ResonanceModel.C:60
 ResonanceModel.C:61
 ResonanceModel.C:62
 ResonanceModel.C:63
 ResonanceModel.C:64
 ResonanceModel.C:65
 ResonanceModel.C:66
 ResonanceModel.C:67
 ResonanceModel.C:68
 ResonanceModel.C:69
 ResonanceModel.C:70
 ResonanceModel.C:71
 ResonanceModel.C:72
 ResonanceModel.C:73
 ResonanceModel.C:74
 ResonanceModel.C:75
 ResonanceModel.C:76
 ResonanceModel.C:77
 ResonanceModel.C:78
 ResonanceModel.C:79
 ResonanceModel.C:80
 ResonanceModel.C:81
 ResonanceModel.C:82
 ResonanceModel.C:83
 ResonanceModel.C:84
 ResonanceModel.C:85
 ResonanceModel.C:86
 ResonanceModel.C:87
 ResonanceModel.C:88
 ResonanceModel.C:89
 ResonanceModel.C:90
 ResonanceModel.C:91
 ResonanceModel.C:92
 ResonanceModel.C:93
 ResonanceModel.C:94
 ResonanceModel.C:95
 ResonanceModel.C:96
 ResonanceModel.C:97
 ResonanceModel.C:98
 ResonanceModel.C:99
 ResonanceModel.C:100
 ResonanceModel.C:101
 ResonanceModel.C:102
 ResonanceModel.C:103
 ResonanceModel.C:104
 ResonanceModel.C:105
 ResonanceModel.C:106
 ResonanceModel.C:107
 ResonanceModel.C:108
 ResonanceModel.C:109
 ResonanceModel.C:110
 ResonanceModel.C:111
 ResonanceModel.C:112
 ResonanceModel.C:113
 ResonanceModel.C:114
 ResonanceModel.C:115
 ResonanceModel.C:116
 ResonanceModel.C:117
 ResonanceModel.C:118
 ResonanceModel.C:119
 ResonanceModel.C:120
 ResonanceModel.C:121
 ResonanceModel.C:122
 ResonanceModel.C:123
 ResonanceModel.C:124
 ResonanceModel.C:125
 ResonanceModel.C:126
 ResonanceModel.C:127
 ResonanceModel.C:128
 ResonanceModel.C:129
 ResonanceModel.C:130
 ResonanceModel.C:131
 ResonanceModel.C:132
 ResonanceModel.C:133
 ResonanceModel.C:134
 ResonanceModel.C:135
 ResonanceModel.C:136
 ResonanceModel.C:137
 ResonanceModel.C:138
 ResonanceModel.C:139
 ResonanceModel.C:140
 ResonanceModel.C:141
 ResonanceModel.C:142
 ResonanceModel.C:143
 ResonanceModel.C:144
 ResonanceModel.C:145
 ResonanceModel.C:146
 ResonanceModel.C:147
 ResonanceModel.C:148
 ResonanceModel.C:149
 ResonanceModel.C:150
 ResonanceModel.C:151
 ResonanceModel.C:152
 ResonanceModel.C:153
 ResonanceModel.C:154
 ResonanceModel.C:155
 ResonanceModel.C:156
 ResonanceModel.C:157
 ResonanceModel.C:158
 ResonanceModel.C:159
 ResonanceModel.C:160
 ResonanceModel.C:161
 ResonanceModel.C:162
 ResonanceModel.C:163
 ResonanceModel.C:164
 ResonanceModel.C:165
 ResonanceModel.C:166
 ResonanceModel.C:167
 ResonanceModel.C:168
 ResonanceModel.C:169
 ResonanceModel.C:170
 ResonanceModel.C:171
 ResonanceModel.C:172
 ResonanceModel.C:173
 ResonanceModel.C:174
 ResonanceModel.C:175
 ResonanceModel.C:176
 ResonanceModel.C:177
 ResonanceModel.C:178
 ResonanceModel.C:179
 ResonanceModel.C:180
 ResonanceModel.C:181
 ResonanceModel.C:182
 ResonanceModel.C:183
 ResonanceModel.C:184
 ResonanceModel.C:185
 ResonanceModel.C:186
 ResonanceModel.C:187
 ResonanceModel.C:188
 ResonanceModel.C:189
 ResonanceModel.C:190
 ResonanceModel.C:191
 ResonanceModel.C:192
 ResonanceModel.C:193
 ResonanceModel.C:194
 ResonanceModel.C:195
 ResonanceModel.C:196
 ResonanceModel.C:197
 ResonanceModel.C:198
 ResonanceModel.C:199
 ResonanceModel.C:200
 ResonanceModel.C:201
 ResonanceModel.C:202
 ResonanceModel.C:203
 ResonanceModel.C:204
 ResonanceModel.C:205
 ResonanceModel.C:206
 ResonanceModel.C:207
 ResonanceModel.C:208
 ResonanceModel.C:209
 ResonanceModel.C:210
 ResonanceModel.C:211
 ResonanceModel.C:212
 ResonanceModel.C:213
 ResonanceModel.C:214
 ResonanceModel.C:215
 ResonanceModel.C:216
 ResonanceModel.C:217
 ResonanceModel.C:218
 ResonanceModel.C:219
 ResonanceModel.C:220
 ResonanceModel.C:221
 ResonanceModel.C:222
 ResonanceModel.C:223
 ResonanceModel.C:224
 ResonanceModel.C:225
 ResonanceModel.C:226
 ResonanceModel.C:227
 ResonanceModel.C:228
 ResonanceModel.C:229
 ResonanceModel.C:230
 ResonanceModel.C:231
 ResonanceModel.C:232
 ResonanceModel.C:233
 ResonanceModel.C:234
 ResonanceModel.C:235
 ResonanceModel.C:236
 ResonanceModel.C:237
 ResonanceModel.C:238
 ResonanceModel.C:239
 ResonanceModel.C:240
 ResonanceModel.C:241
 ResonanceModel.C:242
 ResonanceModel.C:243
 ResonanceModel.C:244
 ResonanceModel.C:245
 ResonanceModel.C:246
 ResonanceModel.C:247
 ResonanceModel.C:248
 ResonanceModel.C:249
 ResonanceModel.C:250
 ResonanceModel.C:251
 ResonanceModel.C:252
 ResonanceModel.C:253
 ResonanceModel.C:254
 ResonanceModel.C:255
 ResonanceModel.C:256
 ResonanceModel.C:257
 ResonanceModel.C:258
 ResonanceModel.C:259
 ResonanceModel.C:260
 ResonanceModel.C:261
 ResonanceModel.C:262
 ResonanceModel.C:263
 ResonanceModel.C:264
 ResonanceModel.C:265
 ResonanceModel.C:266
 ResonanceModel.C:267
 ResonanceModel.C:268
 ResonanceModel.C:269
 ResonanceModel.C:270
 ResonanceModel.C:271
 ResonanceModel.C:272
 ResonanceModel.C:273
 ResonanceModel.C:274
 ResonanceModel.C:275
 ResonanceModel.C:276
 ResonanceModel.C:277
 ResonanceModel.C:278
 ResonanceModel.C:279
 ResonanceModel.C:280
 ResonanceModel.C:281
 ResonanceModel.C:282
 ResonanceModel.C:283
 ResonanceModel.C:284
 ResonanceModel.C:285
 ResonanceModel.C:286
 ResonanceModel.C:287
 ResonanceModel.C:288
 ResonanceModel.C:289
 ResonanceModel.C:290
 ResonanceModel.C:291
 ResonanceModel.C:292
 ResonanceModel.C:293
 ResonanceModel.C:294
 ResonanceModel.C:295
 ResonanceModel.C:296
 ResonanceModel.C:297
 ResonanceModel.C:298
 ResonanceModel.C:299
 ResonanceModel.C:300
 ResonanceModel.C:301
 ResonanceModel.C:302
 ResonanceModel.C:303
 ResonanceModel.C:304
 ResonanceModel.C:305
 ResonanceModel.C:306
 ResonanceModel.C:307
 ResonanceModel.C:308
 ResonanceModel.C:309
 ResonanceModel.C:310
 ResonanceModel.C:311
 ResonanceModel.C:312
 ResonanceModel.C:313
 ResonanceModel.C:314
 ResonanceModel.C:315
 ResonanceModel.C:316
 ResonanceModel.C:317
 ResonanceModel.C:318
 ResonanceModel.C:319
 ResonanceModel.C:320
 ResonanceModel.C:321