Skip to content

Commit 58633ac

Browse files
committed
ITS: extend macros for pull distributions
Signed-off-by: Felix Schlepper <[email protected]>
1 parent 322209c commit 58633ac

File tree

1 file changed

+191
-103
lines changed

1 file changed

+191
-103
lines changed

Detectors/ITSMFT/ITS/macros/test/CheckTracksCA.C

Lines changed: 191 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "SimulationDataFormat/MCEventHeader.h"
3232
#include "DetectorsBase/Propagator.h"
3333
#include "SimulationDataFormat/TrackReference.h"
34+
#include "SimulationDataFormat/O2DatabasePDG.h"
3435
#include "SimulationDataFormat/MCTrack.h"
3536
#include "SimulationDataFormat/MCCompLabel.h"
3637
#include "SimulationDataFormat/MCTruthContainer.h"
@@ -60,11 +61,15 @@ struct ParticleInfo {
6061
bool isPrimary = 0u;
6162
unsigned char storedStatus = 2; /// not stored = 2, fake = 1, good = 0
6263
o2::its::TrackITS track;
64+
o2::MCTrack mcTrack;
6365
};
6466

6567
#pragma link C++ class ParticleInfo + ;
6668

67-
void CheckTracksCA(bool doFakeClStud = false,
69+
void CheckTracksCA(bool doEffStud = false,
70+
bool doFakeClStud = false,
71+
bool doPullStud = true,
72+
bool createOutput = false,
6873
std::string tracfile = "o2trac_its.root",
6974
std::string magfile = "o2sim_grp.root",
7075
std::string clusfile = "o2clus_its.root",
@@ -124,7 +129,10 @@ void CheckTracksCA(bool doFakeClStud = false,
124129
info[n].resize(mcArr->size());
125130
hZvertex->Fill(mcEvent->GetZ());
126131
for (unsigned int mcI{0}; mcI < mcArr->size(); ++mcI) {
127-
auto part = mcArr->at(mcI);
132+
const auto part = mcArr->at(mcI);
133+
if (!o2::O2DatabasePDG::Instance()->GetParticle(part.GetPdgCode())) {
134+
continue;
135+
}
128136
info[n][mcI].event = n;
129137
info[n][mcI].pdg = part.GetPdgCode();
130138
info[n][mcI].pvx = mcEvent->GetX();
@@ -134,6 +142,7 @@ void CheckTracksCA(bool doFakeClStud = false,
134142
info[n][mcI].phi = part.GetPhi();
135143
info[n][mcI].eta = part.GetEta();
136144
info[n][mcI].isPrimary = part.isPrimary();
145+
info[n][mcI].mcTrack = part;
137146
}
138147
}
139148
std::cout << "done." << std::endl;
@@ -214,117 +223,108 @@ void CheckTracksCA(bool doFakeClStud = false,
214223
std::cout << "\t- Total number of fakes: " << fakes << " (" << fakes * 100. / total << "%)" << std::endl;
215224
std::cout << "\t- Total number of good: " << good << " (" << good * 100. / total << "%)" << std::endl;
216225

217-
int nb = 100;
218-
double xbins[nb + 1], ptcutl = 0.01, ptcuth = 10.;
219-
double a = std::log(ptcuth / ptcutl) / nb;
220-
for (int i = 0; i <= nb; i++)
221-
xbins[i] = ptcutl * std::exp(i * a);
222-
TH1D* num = new TH1D("num", ";#it{p}_{T} (GeV/#it{c});Efficiency (fake-track rate)", nb, xbins);
223-
num->Sumw2();
224-
TH1D* numEta = new TH1D("numEta", ";#eta;Number of tracks", 60, -3, 3);
225-
numEta->Sumw2();
226-
TH1D* numChi2 = new TH1D("numChi2", ";#it{p}_{T} (GeV/#it{c});Efficiency (fake-track rate)", 200, 0, 100);
227-
228-
TH1D* fak = new TH1D("fak", ";#it{p}_{T} (GeV/#it{c});Fak", nb, xbins);
229-
fak->Sumw2();
230-
TH1D* multiFak = new TH1D("multiFak", ";#it{p}_{T} (GeV/#it{c});Fak", nb, xbins);
231-
multiFak->Sumw2();
232-
TH1D* fakChi2 = new TH1D("fakChi2", ";#it{p}_{T} (GeV/#it{c});Fak", 200, 0, 100);
233-
234-
TH1D* clone = new TH1D("clone", ";#it{p}_{T} (GeV/#it{c});Clone", nb, xbins);
235-
clone->Sumw2();
236-
237-
TH1D* den = new TH1D("den", ";#it{p}_{T} (GeV/#it{c});Den", nb, xbins);
238-
den->Sumw2();
239-
240-
for (auto& evInfo : info) {
241-
for (auto& part : evInfo) {
242-
if ((part.clusters & 0x7f) != 0x7f) {
243-
// part.clusters != 0x3f && part.clusters != 0x3f << 1 &&
244-
// part.clusters != 0x1f && part.clusters != 0x1f << 1 && part.clusters != 0x1f << 2 &&
245-
// part.clusters != 0x0f && part.clusters != 0x0f << 1 && part.clusters != 0x0f << 2 && part.clusters != 0x0f << 3) {
246-
continue;
247-
}
248-
if (!part.isPrimary) {
249-
continue;
250-
}
251-
den->Fill(part.pt);
252-
if (part.isReco) {
253-
num->Fill(part.pt);
254-
numEta->Fill(part.eta);
255-
if (part.isReco > 1) {
256-
for (int _i{0}; _i < part.isReco - 1; ++_i) {
257-
clone->Fill(part.pt);
226+
TFile* file{nullptr};
227+
if (createOutput) {
228+
file = TFile::Open("CheckTracksCA.root", "recreate");
229+
}
230+
231+
if (doEffStud) {
232+
std::cout << "Calculating efficiencies... ";
233+
const int nb = 100;
234+
double xbins[nb + 1], ptcutl = 0.01, ptcuth = 10.;
235+
double a = std::log(ptcuth / ptcutl) / nb;
236+
for (int i = 0; i <= nb; i++)
237+
xbins[i] = ptcutl * std::exp(i * a);
238+
TH1D* num = new TH1D("num", ";#it{p}_{T} (GeV/#it{c});Efficiency (fake-track rate)", nb, xbins);
239+
num->Sumw2();
240+
TH1D* numEta = new TH1D("numEta", ";#eta;Number of tracks", 60, -3, 3);
241+
numEta->Sumw2();
242+
TH1D* numChi2 = new TH1D("numChi2", ";#it{p}_{T} (GeV/#it{c});Efficiency (fake-track rate)", 200, 0, 100);
243+
244+
TH1D* fak = new TH1D("fak", ";#it{p}_{T} (GeV/#it{c});Fak", nb, xbins);
245+
fak->Sumw2();
246+
TH1D* multiFak = new TH1D("multiFak", ";#it{p}_{T} (GeV/#it{c});Fak", nb, xbins);
247+
multiFak->Sumw2();
248+
TH1D* fakChi2 = new TH1D("fakChi2", ";#it{p}_{T} (GeV/#it{c});Fak", 200, 0, 100);
249+
250+
TH1D* clone = new TH1D("clone", ";#it{p}_{T} (GeV/#it{c});Clone", nb, xbins);
251+
clone->Sumw2();
252+
253+
TH1D* den = new TH1D("den", ";#it{p}_{T} (GeV/#it{c});Den", nb, xbins);
254+
den->Sumw2();
255+
256+
for (auto& evInfo : info) {
257+
for (auto& part : evInfo) {
258+
if ((part.clusters & 0x7f) != 0x7f) {
259+
// part.clusters != 0x3f && part.clusters != 0x3f << 1 &&
260+
// part.clusters != 0x1f && part.clusters != 0x1f << 1 && part.clusters != 0x1f << 2 &&
261+
// part.clusters != 0x0f && part.clusters != 0x0f << 1 && part.clusters != 0x0f << 2 && part.clusters != 0x0f << 3) {
262+
continue;
263+
}
264+
if (!part.isPrimary) {
265+
continue;
266+
}
267+
den->Fill(part.pt);
268+
if (part.isReco) {
269+
num->Fill(part.pt);
270+
numEta->Fill(part.eta);
271+
if (part.isReco > 1) {
272+
for (int _i{0}; _i < part.isReco - 1; ++_i) {
273+
clone->Fill(part.pt);
274+
}
258275
}
259276
}
260-
}
261-
if (part.isFake) {
262-
fak->Fill(part.pt);
263-
if (part.isFake > 1) {
264-
for (int _i{0}; _i < part.isFake - 1; ++_i) {
265-
multiFak->Fill(part.pt);
277+
if (part.isFake) {
278+
fak->Fill(part.pt);
279+
if (part.isFake > 1) {
280+
for (int _i{0}; _i < part.isFake - 1; ++_i) {
281+
multiFak->Fill(part.pt);
282+
}
266283
}
267284
}
268285
}
269286
}
270-
}
271287

272-
TCanvas* c1 = new TCanvas;
273-
c1->SetLogx();
274-
c1->SetGridx();
275-
c1->SetGridy();
276-
TH1* sum = (TH1*)num->Clone("sum");
277-
sum->Add(fak);
278-
sum->Divide(sum, den, 1, 1);
279-
sum->SetLineColor(kBlack);
280-
sum->Draw("hist");
281-
num->Divide(num, den, 1, 1, "b");
282-
num->Draw("histesame");
283-
fak->Divide(fak, den, 1, 1, "b");
284-
fak->SetLineColor(2);
285-
fak->Draw("histesame");
286-
multiFak->Divide(multiFak, den, 1, 1, "b");
287-
multiFak->SetLineColor(kRed + 1);
288-
multiFak->Draw("histsame");
289-
clone->Divide(clone, den, 1, 1, "b");
290-
clone->SetLineColor(3);
291-
clone->Draw("histesame");
292-
TCanvas* c2 = new TCanvas;
293-
c2->SetGridx();
294-
c2->SetGridy();
295-
hZvertex->DrawClone();
296-
297-
std::cout << "** Streaming output TTree to file ... " << std::flush;
298-
TFile file("CheckTracksCA.root", "recreate");
299-
TTree tree("ParticleInfo", "ParticleInfo");
300-
ParticleInfo pInfo;
301-
tree.Branch("particle", &pInfo);
302-
for (auto& event : info) {
303-
for (auto& part : event) {
304-
int nCl{0};
305-
for (unsigned int bit{0}; bit < sizeof(pInfo.clusters) * 8; ++bit) {
306-
nCl += bool(part.clusters & (1 << bit));
307-
}
308-
if (nCl < 3) {
309-
continue;
310-
}
311-
pInfo = part;
312-
tree.Fill();
288+
TCanvas* c1 = new TCanvas;
289+
c1->SetLogx();
290+
c1->SetGridx();
291+
c1->SetGridy();
292+
TH1* sum = (TH1*)num->Clone("sum");
293+
sum->Add(fak);
294+
sum->Divide(sum, den, 1, 1);
295+
sum->SetLineColor(kBlack);
296+
sum->Draw("hist");
297+
num->Divide(num, den, 1, 1, "b");
298+
num->Draw("histesame");
299+
fak->Divide(fak, den, 1, 1, "b");
300+
fak->SetLineColor(2);
301+
fak->Draw("histesame");
302+
multiFak->Divide(multiFak, den, 1, 1, "b");
303+
multiFak->SetLineColor(kRed + 1);
304+
multiFak->Draw("histsame");
305+
clone->Divide(clone, den, 1, 1, "b");
306+
clone->SetLineColor(3);
307+
clone->Draw("histesame");
308+
TCanvas* c2 = new TCanvas;
309+
c2->SetGridx();
310+
c2->SetGridy();
311+
hZvertex->DrawClone();
312+
313+
if (createOutput) {
314+
sum->Write("total");
315+
fak->Write("singleFake");
316+
num->Write("efficiency");
317+
numEta->Write("etaDist");
318+
multiFak->Write("multiFake");
319+
clone->Write("clones");
313320
}
321+
std::cout << " done." << std::endl;
314322
}
315-
tree.Write();
316-
sum->Write("total");
317-
fak->Write("singleFake");
318-
num->Write("efficiency");
319-
numEta->Write("etaDist");
320-
multiFak->Write("multiFake");
321-
clone->Write("clones");
322-
file.Close();
323-
std::cout << " done." << std::endl;
324323

325324
//////////////////////
326325
// Fake clusters study
327326
if (doFakeClStud) {
327+
std::cout << "Creating fake cluster study... ";
328328
std::vector<TH1I*> histLength, histLength1Fake, histLengthNoCl, histLength1FakeNoCl;
329329
std::vector<THStack*> stackLength, stackLength1Fake;
330330
std::vector<TLegend*> legends, legends1Fake;
@@ -364,10 +364,10 @@ void CheckTracksCA(bool doFakeClStud = false,
364364
stackLength1Fake[iH - 4]->Add(histLength1FakeNoCl[iH - 4]);
365365
}
366366

367-
for (auto& event : info) {
368-
for (auto& part : event) {
367+
for (const auto& event : info) {
368+
for (const auto& part : event) {
369369
int nCl{0};
370-
for (unsigned int bit{0}; bit < sizeof(pInfo.clusters) * 8; ++bit) {
370+
for (unsigned int bit{0}; bit < sizeof(part.clusters) * 8; ++bit) {
371371
nCl += bool(part.clusters & (1 << bit));
372372
}
373373
if (nCl < 3) {
@@ -409,5 +409,93 @@ void CheckTracksCA(bool doFakeClStud = false,
409409
gPad->BuildLegend();
410410
}
411411
canvas->SaveAs("fakeClusters.png", "recreate");
412+
std::cout << " done\n";
413+
}
414+
415+
if (doPullStud) {
416+
std::cout << "Creating pull study... ";
417+
const int nBins{30};
418+
const float xWidth{10};
419+
// Pulls
420+
auto hYPull = new TH1F("hYPull", "Pull Y", nBins, -xWidth, xWidth);
421+
auto hZPull = new TH1F("hZPull", "Pull Z", nBins, -xWidth, xWidth);
422+
auto hSPhiPull = new TH1F("hSPhiPull", "Pull Sin(Phi)", nBins, -xWidth, xWidth);
423+
auto hTglPull = new TH1F("hTglPull", "Pull Tg(Lambda)", nBins, -xWidth, xWidth);
424+
auto hQoPtPull = new TH1F("hQoPtPull", "Pull Q/Pt", nBins, -xWidth, xWidth);
425+
// Correlation
426+
auto hCorYZ = new TH2F("hCorYZ", ";#sigma_{Z}^{2};#sigma_{Y}^{2}", nBins, 0, 5e-5, nBins, 0, 5e-5);
427+
auto hCorYSPhi = new TH2F("hCorYSPhi", ";#sigma_{snp}^{2};#sigma_{Y}^{2}", nBins, 0, 5e-5, nBins, 0, 5e-5);
428+
429+
for (const auto& event : info) {
430+
for (const auto& part : event) {
431+
if (((part.clusters & 0x7f) != 0x7f) && !part.isPrimary) {
432+
continue;
433+
}
434+
435+
// prepare mc truth parameters
436+
std::array<float, 3> xyz{(float)part.mcTrack.GetStartVertexCoordinatesX(), (float)part.mcTrack.GetStartVertexCoordinatesY(), (float)part.mcTrack.GetStartVertexCoordinatesZ()};
437+
std::array<float, 3> pxyz{(float)part.mcTrack.GetStartVertexMomentumX(), (float)part.mcTrack.GetStartVertexMomentumY(), (float)part.mcTrack.GetStartVertexMomentumZ()};
438+
o2::track::TrackPar mcTrack(xyz, pxyz, TMath::Nint(o2::O2DatabasePDG::Instance()->GetParticle(part.mcTrack.GetPdgCode())->Charge() / 3), false);
439+
if (!mcTrack.rotate(part.track.getAlpha()) &&
440+
o2::base::Propagator::Instance()->propagateTo(mcTrack, part.track.getX())) {
441+
continue;
442+
}
443+
444+
hYPull->Fill((part.track.getY() - mcTrack.getY()) / std::sqrt(part.track.getSigmaY2()));
445+
hZPull->Fill((part.track.getZ() - mcTrack.getZ()) / std::sqrt(part.track.getSigmaZ2()));
446+
hSPhiPull->Fill((part.track.getSnp() - mcTrack.getSnp()) / std::sqrt(part.track.getSigmaSnp2()));
447+
hTglPull->Fill((part.track.getTgl() - mcTrack.getTgl()) / std::sqrt(part.track.getSigmaTgl2()));
448+
hQoPtPull->Fill((part.track.getQ2Pt() - mcTrack.getQ2Pt()) / std::sqrt(part.track.getSigma1Pt2()));
449+
450+
hCorYZ->Fill(part.track.getSigmaZ2(), part.track.getSigmaY2());
451+
hCorYSPhi->Fill(part.track.getSigmaZ2(), part.track.getSigmaSnp2());
452+
}
453+
}
454+
455+
// normalise, set axis, fit and draw
456+
auto doPullCalc = [](TH1F* h) {
457+
h->Scale(1. / h->Integral("width"));
458+
h->GetYaxis()->SetRangeUser(1e-5, 1.);
459+
h->Fit("gaus", "", "2QMR");
460+
gPad->SetLogy();
461+
h->Draw("hist");
462+
};
463+
464+
auto c = new TCanvas("cPull", "", 1000, 1000);
465+
c->Divide(5, 5);
466+
c->cd(1);
467+
doPullCalc(hYPull);
468+
c->cd(2);
469+
hCorYZ->Draw("colz");
470+
c->cd(3);
471+
hCorYSPhi->Draw("colz");
472+
c->cd(1 + 6);
473+
doPullCalc(hZPull);
474+
c->cd(1 + 12);
475+
doPullCalc(hSPhiPull);
476+
c->cd(1 + 18);
477+
doPullCalc(hTglPull);
478+
c->cd(1 + 24);
479+
doPullCalc(hQoPtPull);
480+
c->Draw();
481+
std::cout << " done\n";
482+
}
483+
484+
if (createOutput) {
485+
std::cout << "** Streaming output TTree to file ... " << std::flush;
486+
TTree tree("ParticleInfo", "ParticleInfo");
487+
ParticleInfo pInfo;
488+
tree.Branch("particle", &pInfo);
489+
for (const auto& event : info) {
490+
for (const auto& part : event) {
491+
if (((part.clusters & 0x7f) != 0x7f) && !part.isPrimary) {
492+
continue;
493+
}
494+
pInfo = part;
495+
tree.Fill();
496+
}
497+
}
498+
tree.Write();
499+
file->Close();
412500
}
413501
}

0 commit comments

Comments
 (0)