diff --git a/macro/analysis/much/Optimization_jpsi_TMVA.C b/macro/analysis/much/Optimization_jpsi_TMVA.C new file mode 100644 index 0000000000000000000000000000000000000000..a5e878fab6493d23d7110e12a4fafb4bd8978c03 --- /dev/null +++ b/macro/analysis/much/Optimization_jpsi_TMVA.C @@ -0,0 +1,535 @@ +/* Copyright (C) 2019-2020 Facility for Antiproton and Ion Research in Europe, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Anna Senger [committer] */ + +//--------------------------------------------------- +// +// invariant mass spectra for omega mesons @ 8-10 A GeV/c +// +// CbmAnaDimuonAnalysis has to be used: +// - with UseCuts(kFALSE) for type 0 (cuts optimization) +// - with UseCuts(kTRUE) for type 1 (geometry optimization) +// +// Invariant mass spectrum for background is calculated using super-event technics +// +// Abhishek Kumar Sharma, Anna Senger abhishekhep@gmail.com, a.senger@gsi.de +// +//--------------------------------------------------- + +void Optimization_jpsi_TMVA(Int_t energy = 10, Int_t NofFiles = 1250, Int_t type = 0, TString version = "v22a",TString dir = "/lustre/cbm/users/aksharma/cbmroot_new/cbmroot_vikas/cbmroot/macro/much/data/v23a/sis100_muon_jpsi/", TString methodName = "BDTG", TString weightfile = "v22a_jpsi_1L/weights/TMVAClassification_BDTG.weights.xml", Double_t model_cut = 0.451) +{ + gStyle->SetCanvasColor(10); + gStyle->SetFrameFillColor(10); + gStyle->SetHistLineWidth(4); + gStyle->SetPadColor(10); + gStyle->SetStatColor(10); + gStyle->SetPalette(55); + gStyle->SetPaintTextFormat("2.1f"); + + + // ######################################### TMVA ######################################### + // This loads the library + TMVA::Tools::Instance(); + // Create the Reader object + TMVA::Reader *reader = new TMVA::Reader(); + + Float_t v1,v2,v3,v4,v5,v6,v7,v8,v9; + + reader->AddVariable("NofMUCH",&v1); + reader->AddVariable("NofSTS",&v2); + reader->AddVariable("NofTRD",&v3); + reader->AddVariable("Chi2MUCH",&v4); + reader->AddVariable("Chi2STS",&v5); + reader->AddVariable("Chi2Vertex",&v6); + reader->AddVariable("Chi2TRD",&v7); + reader->AddVariable("M",&v8); + reader->AddVariable("P",&v9); + + methodName="BDTG method"; + weightfile="v22a_jpsi_1L/weights/TMVAClassification_BDTG.weights.xml"; + reader->BookMVA( methodName, weightfile); + + Double_t sgn_mult = 0.06 * 5.0 * 1e-6; // multiplicity from UrQMD 5*10e-6 and HSD 2*10e-7 + TH1D* invM_sgn = new TH1D("invM_jpsi", "invM_jpsi", 400, 0, 4); + + (invM_sgn->GetXaxis())->SetTitle("m_{inv} (GeV/c^{2})"); + (invM_sgn->GetYaxis())->SetTitle("counts/(events #times 10 MeV/c^{2})"); + invM_sgn->SetLineColor(kRed); + invM_sgn->SetMarkerColor(kRed); + invM_sgn->SetMarkerStyle(20); + + TH1D* invM_sgntrue = (TH1D*) invM_sgn->Clone("invM_sgntrue"); + + + TH1D* invM_bg = (TH1D*) invM_sgn->Clone("invM_bg"); + invM_bg->SetTitle("invM_bg"); + invM_bg->SetLineColor(kBlack); + invM_bg->SetMarkerColor(kBlack); + + TH1D* invM_full = (TH1D*) invM_sgn->Clone("invM_full"); + invM_full->SetTitle("invM_full"); + invM_full->SetLineColor(kBlack); + invM_full->SetMarkerColor(kBlack); + + TClonesArray* MuPlus = new TClonesArray("CbmAnaMuonCandidate"); + TClonesArray* MuMinus = new TClonesArray("CbmAnaMuonCandidate"); + TTree* InputTree; + + Double_t NofEvents[2]; + + //-------------- cuts --------------------------------- + + Int_t MUCHhits = 8; + Int_t STShits = 5; + Int_t TRDhits = 1; + Int_t TOFhits = 1; + + Double_t MUCHchi2 = 20.0; + Double_t STSchi2 = 20.0; + Double_t Vchi2 = 20.0; + Double_t TRDchi2 = 20.0; + + Int_t sigmaTOFCut = 2; + + TString dir_par = getenv("VMCWORKDIR"); + TString name = dir_par + "/parameters/much/TOF8gev_fitParam_sigma2.sis100_muon_jpsi.root"; + Double_t p0min, p1min, p2min; + Double_t p0max, p1max, p2max; + + TFile* FF = new TFile(name); + TTree* MinParam = (TTree*) FF->Get("MinParam"); + MinParam->SetBranchAddress("p0", &p0min); + MinParam->SetBranchAddress("p1", &p1min); + MinParam->SetBranchAddress("p2", &p2min); + MinParam->GetEntry(0); + + TTree* MaxParam = (TTree*) FF->Get("MaxParam"); + MaxParam->SetBranchAddress("p0", &p0max); + MaxParam->SetBranchAddress("p1", &p1max); + MaxParam->SetBranchAddress("p2", &p2max); + MaxParam->GetEntry(0); + Int_t counter_mn=0, counter_pl=0; + + //-------------------------------------------------------- + + for (int k = 250; k < NofFiles + 1; k++) { + name.Form("%s/%dgev/%d/center/J_psi/Signal_v22a_10gev_auau_center.ana.root", dir.Data(), energy, k); + TFile* f = new TFile(name); + if (f->IsZombie() || f->GetNkeys() < 1 || f->TestBit(TFile::kRecovered)) { + f->Close(); + continue; + } + + if (k % 100 == 0) cout << "Input File " << k << " : " << f->GetName() << endl; + + InputTree = (TTree*) f->Get("cbmsim"); + if (!InputTree) { + f->Close(); + continue; + } + + InputTree->SetBranchAddress("MuPlus", &MuPlus); + InputTree->SetBranchAddress("MuMinus", &MuMinus); + + //----------------------------------------------------------- + + for (int iEvent = 0; iEvent < InputTree->GetEntries(); iEvent++) { + InputTree->GetEntry(iEvent); + + NofEvents[0]++; + + int NofPlus = MuPlus->GetEntriesFast(); + int NofMinus = MuMinus->GetEntriesFast(); + if (NofPlus == 0 || NofMinus == 0) continue; + + for (int iPart = 0; iPart < NofPlus; iPart++) { + CbmAnaMuonCandidate* mu_pl = (CbmAnaMuonCandidate*) MuPlus->At(iPart); + if (type == 0) { + if (mu_pl->GetNStsHits() < STShits) continue; + if (mu_pl->GetNMuchHits() < MUCHhits) continue; + if (mu_pl->GetNTrdHits() < TRDhits) continue; + if (mu_pl->GetNTofHits() < TOFhits) continue; + if (mu_pl->GetChiToVertex() > Vchi2) continue; + if (mu_pl->GetChiSts() > STSchi2) continue; + if (mu_pl->GetChiMuch() > MUCHchi2) continue; + if (mu_pl->GetChiTrd() > TRDchi2) continue; + v1 = mu_pl->GetNMuchHits(); + v2 = mu_pl->GetNStsHits(); + v3 = mu_pl->GetNTrdHits(); + v4 = mu_pl->GetChiMuch(); + v5 = mu_pl->GetChiSts(); + v6 = mu_pl->GetChiToVertex(); + v7 = mu_pl->GetChiTrd(); + v8 = mu_pl->GetTofM(); + v9 = mu_pl->GetMomentum()->P(); + double y1 = reader->EvaluateMVA( methodName); // ML evaluation ########## + if (y1 < model_cut) continue; // Using a cut on the ML output ########## + } + TLorentzVector* P_pl = mu_pl->GetMomentum(); + counter_pl = counter_pl+1; + Double_t mass = mu_pl->GetTofM(); + Double_t mom = P_pl->P(); + if (type == 0) + if (mass < (p0min + p1min * mom + p2min * mom * mom) || mass > (p0max + p1max * mom + p2max * mom * mom)) + continue; + + for (int jPart = 0; jPart < NofMinus; jPart++) { + CbmAnaMuonCandidate* mu_mn = (CbmAnaMuonCandidate*) MuMinus->At(jPart); + if (type == 0) { + if (mu_mn->GetNStsHits() < STShits) continue; + if (mu_mn->GetNMuchHits() < MUCHhits) continue; + if (mu_mn->GetNTrdHits() < TRDhits) continue; + if (mu_mn->GetNTofHits() < TOFhits) continue; + + if (mu_mn->GetChiToVertex() > Vchi2) continue; + if (mu_mn->GetChiSts() > STSchi2) continue; + if (mu_mn->GetChiMuch() > MUCHchi2) continue; + if (mu_mn->GetChiTrd() > TRDchi2) continue; + + v1 = mu_mn->GetNMuchHits(); + v2 = mu_mn->GetNStsHits(); + v3 = mu_mn->GetNTrdHits(); + v4 = mu_mn->GetChiMuch(); + v5 = mu_mn->GetChiSts(); + v6 = mu_mn->GetChiToVertex(); + v7 = mu_mn->GetChiTrd(); + v8 = mu_mn->GetTofM(); + v9 = mu_mn->GetMomentum()->P(); + + double y1 = reader->EvaluateMVA( methodName); // ML evaluation ########## + if (y1 < model_cut) continue; // Using a cut on the ML output ########## + } + TLorentzVector* P_mn = mu_mn->GetMomentum(); + counter_mn = counter_mn+1; + mass = mu_mn->GetTofM(); + mom = P_mn->P(); + + if (type == 0) + if (mass < (p0min + p1min * mom + p2min * mom * mom) || mass > (p0max + p1max * mom + p2max * mom * mom)) + continue; + + TLorentzVector M(*P_pl + *P_mn); + invM_sgn->Fill(M.M(), sgn_mult / 10.); // normalized with bin value + + if(mu_pl->GetTrueMu() == 1 && mu_mn->GetTrueMu() == 1){ + invM_sgntrue->Fill(M.M(), sgn_mult / 10.); + } + } + } + } + f->Close(); + } + + TLorentzVector P1, P2, M; + TTree* Plus = new TTree("Plus", "part-"); + Plus->Branch("P0", &P1(0), "Px/D:Py:Pz:E", 10000000); + + TTree* Minus = new TTree("Minus", "part+"); + Minus->Branch("P0", &P2(0), "Px/D:Py:Pz:E", 10000000); + + for (int k = 250; k < NofFiles + 1; k++) { + name.Form("%s/%dgev/centr/%d/center/J_psi/Back_v22a_10gev_auau_center.ana.root", dir.Data(), energy, k); + + TFile* f = new TFile(name); + if (f->IsZombie() || f->GetNkeys() < 1 || f->TestBit(TFile::kRecovered)) { + f->Close(); + continue; + } + + if (k % 100 == 0) cout << "Input File " << k << " : " << f->GetName() << endl; + + InputTree = (TTree*) f->Get("cbmsim"); + if (!InputTree) { + f->Close(); + continue; + } + + InputTree->SetBranchAddress("MuPlus", &MuPlus); + InputTree->SetBranchAddress("MuMinus", &MuMinus); + + //----------------------------------------------------------- + + for (int iEvent = 0; iEvent < InputTree->GetEntries(); iEvent++) { + InputTree->GetEntry(iEvent); + NofEvents[1]++; + + + int NofPlus = MuPlus->GetEntriesFast(); + int NofMinus = MuMinus->GetEntriesFast(); + + for (int iPart = 0; iPart < NofPlus; iPart++) { + CbmAnaMuonCandidate* mu_pl = (CbmAnaMuonCandidate*) MuPlus->At(iPart); + if (type == 0) { + if (mu_pl->GetNStsHits() < STShits) continue; + if (mu_pl->GetNMuchHits() < MUCHhits) continue; + if (mu_pl->GetNTrdHits() < TRDhits) continue; + if (mu_pl->GetNTofHits() < TOFhits) continue; + if (mu_pl->GetChiToVertex() > Vchi2) continue; + if (mu_pl->GetChiSts() > STSchi2) continue; + if (mu_pl->GetChiMuch() > MUCHchi2) continue; + if (mu_pl->GetChiTrd() > TRDchi2) continue; + v1 = mu_pl->GetNMuchHits(); + v2 = mu_pl->GetNStsHits(); + v3 = mu_pl->GetNTrdHits(); + v4 = mu_pl->GetChiMuch(); + v5 = mu_pl->GetChiSts(); + v6 = mu_pl->GetChiToVertex(); + v7 = mu_pl->GetChiTrd(); + v8 = mu_pl->GetTofM(); + v9 = mu_pl->GetMomentum()->P(); + + double y1 = reader->EvaluateMVA( methodName); // ML evaluation ########## + if (y1 < model_cut) continue; // Using a cut on the ML output ########## + } + TLorentzVector* P_pl = mu_pl->GetMomentum(); + + Double_t mass = mu_pl->GetTofM(); + Double_t mom = P_pl->P(); + + if (type == 0) + if (mass < (p0min + p1min * mom + p2min * mom * mom) || mass > (p0max + p1max * mom + p2max * mom * mom)) + continue; + P1 = *mu_pl->GetMomentum(); + Plus->Fill(); + } + for (int jPart = 0; jPart < NofMinus; jPart++) { + CbmAnaMuonCandidate* mu_mn = (CbmAnaMuonCandidate*) MuMinus->At(jPart); + if (type == 0) { + if (mu_mn->GetNStsHits() < STShits) continue; + if (mu_mn->GetNMuchHits() < MUCHhits) continue; + if (mu_mn->GetNTrdHits() < TRDhits) continue; + if (mu_mn->GetNTofHits() < TOFhits) continue; + + if (mu_mn->GetChiToVertex() > Vchi2) continue; + if (mu_mn->GetChiSts() > STSchi2) continue; + if (mu_mn->GetChiMuch() > MUCHchi2) continue; + if (mu_mn->GetChiTrd() > TRDchi2) continue; + v1 = mu_mn->GetNMuchHits(); + v2 = mu_mn->GetNStsHits(); + v3 = mu_mn->GetNTrdHits(); + v4 = mu_mn->GetChiMuch(); + v5 = mu_mn->GetChiSts(); + v6 = mu_mn->GetChiToVertex(); + v7 = mu_mn->GetChiTrd(); + v8 = mu_mn->GetTofM(); + v9 = mu_mn->GetMomentum()->P(); + + double y1 = reader->EvaluateMVA(methodName); // ML evaluation ########## + if (y1 < model_cut) continue; // Using a cut on the ML output ########## +} + TLorentzVector* P_mn = mu_mn->GetMomentum(); + + Double_t mass = mu_mn->GetTofM(); + Double_t mom = P_mn->P(); + + if (type == 0) + if (mass < (p0min + p1min * mom + p2min * mom * mom) || mass > (p0max + p1max * mom + p2max * mom * mom)) + continue; + P2 = *mu_mn->GetMomentum(); + Minus->Fill(); + } + } + + f->Close(); + if (Plus->GetEntries() > 10000) break; // speed up of calculation + } + + Plus->SetBranchAddress("P0", &P1(0)); + Minus->SetBranchAddress("P0", &P2(0)); + + Double_t entriesPlus = Plus->GetEntries(); + Double_t entriesMinus = Minus->GetEntries(); + + for (int jPart = 0; jPart < entriesPlus; jPart++) { + if (jPart % 1000 == 0) cout << entriesPlus << " ----- " << jPart << endl; + Plus->GetEntry(jPart); + for (int iPart = 0; iPart < entriesMinus; iPart++) { + Minus->GetEntry(iPart); + M = P1 + P2; + invM_bg->Fill(M.M(), 1. / 10.); + } + } + invM_sgn->Scale(1. / NofEvents[0]); + invM_sgntrue->Scale(1./ NofEvents[0]); + invM_full->Add(invM_sgn); + + invM_bg->Scale(1. / NofEvents[1] / NofEvents[1]); + + invM_full->Add(invM_bg); + + Double_t initPar[] = {3.097, 0.04}; // jpsi mass and sigma for fit initialization + + TF1* fit = new TF1("fullFit", "gaus(0)+pol2(3)", 2.90, 3.30); + + fit->SetParNames("Const", "Mass", "Sigma", "a0", "a1", "a2"); + fit->SetNpx(10000); + fit->SetLineColor(2); + fit->SetParameter(1, (2.90 + 3.30) / 2); + fit->SetParameter(2, (3.30 - 2.90) / 4); + fit->SetParLimits(2, 0, 1); + + fit->FixParameter(1, initPar[0]); + fit->FixParameter(2, initPar[1]); + invM_full->Fit("fullFit", "QRN", "", 2.90, 3.30); + + fit->ReleaseParameter(1); + fit->ReleaseParameter(2); + invM_full->Fit("fullFit", "QRN", "", 2.90, 3.30); + + float start = fit->GetParameter(1) - 2 * fit->GetParameter(2); + float end = fit->GetParameter(1) + 2 * fit->GetParameter(2); + + cout<<" start "<<start<<" end "<<end<<endl; + + invM_full->Fit("fullFit", "", "", 2.90, 3.30); + + TF1* fitSgn = new TF1("sgnFit", "gaus", 2.90, 3.30); + for (int iPar = 0; iPar < 3; iPar++) + fitSgn->SetParameter(iPar, fit->GetParameter(iPar)); + + TF1* fitBg = new TF1("bgFit", "pol2", 2.90, 3.30); + for (int iPar = 3; iPar < 6; iPar++) + fitBg->SetParameter(iPar - 3, fit->GetParameter(iPar)); + + Double_t min_histo = (invM_sgn->GetXaxis())->GetXmin(); + Double_t max_histo = (invM_sgn->GetXaxis())->GetXmax(); + Double_t bin_histo = (max_histo - min_histo) / invM_sgn->GetNbinsX(); + + float S = fitSgn->Integral(start, end) / bin_histo; + float B = fitBg->Integral(start, end) / bin_histo; + cout<<" mu+ "<<counter_pl<<" mu- "<<counter_mn<<endl; + float SBratio = S / B; + cout<<" signal "<<S<<" Bg "<<B<<" SbyB "<<SBratio<<endl; + Double_t eff = S / sgn_mult * 10. * 100.; + cout<<"Eff "<<eff<<" % "<<endl; + char tmpString[5]; + sprintf(tmpString, "%4.4f", (S / B)); + + TString LegendEntry[8]; + LegendEntry[0] = "N^{#mu_{+}#mu_{-}}"; + LegendEntry[1] = "S/B = "; + LegendEntry[1] += tmpString; + LegendEntry[2] = "#varepsilon = "; + sprintf(tmpString, "%2.2f ", eff); + LegendEntry[2] += tmpString; + LegendEntry[2] += "%"; + LegendEntry[3] = "#frac{S}{#sqrt{S+B}} = "; + sprintf(tmpString, "%1.3e", S / sqrt(S + B)); + LegendEntry[3] += tmpString; + LegendEntry[4] = " "; + LegendEntry[5] = "CB^{mix}"; + LegendEntry[6] = "Signal = N^{#mu_{+}#mu_{-}} - CB^{mix}"; + + TCanvas* c1; + c1 = new TCanvas("c1", "Particles", 0, 0, 1200, 600); + c1->UseCurrentStyle(); + gPad->SetFixedAspectRatio(kFALSE); + + TLatex *t = new TLatex(10, 30, "Au-Au 10AGeV 0-10%"); + + TLegend* legend = legend = new TLegend(0.60, 0.55, .99, .99); + legend->SetFillColor(0); + legend->SetTextSize(0.05); + legend->SetMargin(0.1); + + TGaxis::SetMaxDigits(3); + + invM_full->GetXaxis()->SetTitleSize(0.05); + invM_full->GetXaxis()->SetLabelSize(0.04); + invM_full->GetXaxis()->SetTitleOffset(0.9); + invM_full->GetXaxis()->SetRangeUser(2.5, 3.5); + + invM_full->GetYaxis()->SetTitleSize(0.04); + invM_full->GetYaxis()->SetLabelSize(0.04); + invM_full->GetYaxis()->SetTitleOffset(1.3); + + invM_full->SetLineColor(kBlack); + invM_full->SetMarkerStyle(20); + invM_full->SetMarkerColor(kBlack); + invM_full->SetMarkerSize(0.7); + invM_full->SetLineStyle(2); + + + invM_full->GetXaxis()->SetTitle("m_{inv} (GeV/#it{c}^{2})"); + invM_full->GetYaxis()->SetTitle("counts/(events #times 10 MeV/#it{c}^{2})"); + + + invM_sgntrue->SetLineColor(kRed); + invM_sgntrue->SetMarkerStyle(20); + invM_sgntrue->SetMarkerColor(kRed); + invM_sgntrue->SetMarkerSize(0.4); + + invM_bg->SetLineColor(kBlue); + invM_bg->SetMarkerStyle(24); + invM_bg->SetMarkerColor(kBlue); + invM_bg->SetMarkerSize(0.4); + + legend->AddEntry(invM_full, LegendEntry[0].Data(), "l"); + legend->AddEntry(invM_bg, LegendEntry[5].Data(), "l"); + legend->AddEntry(invM_sgntrue, LegendEntry[6].Data(), "l"); + legend->AddEntry((TObject*) 0, LegendEntry[1].Data(), ""); + legend->AddEntry((TObject*) 0, LegendEntry[2].Data(), ""); + + if (type == 0) { + c1->Divide(2, 1); + c1->cd(1); + + invM_bg->Draw("pe"); + invM_sgntrue->Draw("pesame"); + invM_full->Draw("pesame"); + t->DrawLatex(2.5, 0.0, "Au-Au @ 10AGeV 0-10%"); + legend->Draw(); + + c1->cd(2); + + TLatex Tl; + Tl.SetTextAlign(12); + Tl.SetTextSize(0.04); + + name = "Cuts:"; + Tl.DrawLatex(0.3, 0.95, name); + name.Form("N of STS hits #geq %d", STShits); + Tl.DrawLatex(0.3, 0.9, name); + name.Form("N of MUCH hits #geq %d", MUCHhits); + Tl.DrawLatex(0.3, 0.8, name); + name.Form("N of TRD hits #geq %d", TRDhits); + Tl.DrawLatex(0.3, 0.7, name); + name.Form("N of TOF hits #geq %d", TOFhits); + Tl.DrawLatex(0.3, 0.6, name); + name.Form("#chi^{2}_{vertex} #leq %1.1f", Vchi2); + Tl.DrawLatex(0.3, 0.5, name); + name.Form("#chi^{2}_{STS} #leq %1.1f", STSchi2); + Tl.DrawLatex(0.3, 0.4, name); + name.Form("#chi^{2}_{MUCH} #leq %1.1f", MUCHchi2); + Tl.DrawLatex(0.3, 0.3, name); + name.Form("#chi^{2}_{TRD} #leq %1.1f", TRDchi2); + Tl.DrawLatex(0.3, 0.2, name); + name.Form("%d#sigma cut in TOF", sigmaTOFCut); + Tl.DrawLatex(0.3, 0.1, name); + + name.Form("%sML Model with cut %1.3f", methodName.Data(), model_cut); + Tl.DrawLatex(0.3, 0.05, name); + } + else { + invM_full->Draw("pe"); + legend->Draw(); + } + + + + if (type == 0) name.Form("invM_bg_jpsi_%dgev.cuts_with_TOF_sigma2_BDTG_%0.3f_trained_1L_tracks", energy, model_cut); + else + name.Form("%s/invM_bg_jpsi_%dgev.geo_", methodName.Data(), energy); + name += version + ".root"; + + TFile* FFF = new TFile(name, "recreate"); + c1->Write(); + invM_sgn->Write(); + invM_bg->Write(); + invM_full->Write(); + invM_sgntrue->Write(); + FFF->Close(); + + name += ".ps"; + c1->Print(name); +}