Skip to content

Commit 4abc96e

Browse files
authored
add output to .root
1 parent f4293b5 commit 4abc96e

1 file changed

Lines changed: 76 additions & 31 deletions

File tree

‎DPG/Tasks/AOTEvent/macros/plotBcOccupancyQa.C‎

Lines changed: 76 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
///
1515
/// Usage:
1616
/// root -l -b -q 'plotBcOccupancyQa.C("AnalysisResults.root")'
17-
/// root -l -b -q 'plotBcOccupancyQa.C("AnalysisResults.root", "bcOccupancyQa.pdf", "bc-occupancy-qa-task")'
17+
/// root -l -b -q 'plotBcOccupancyQa.C("AnalysisResults.root", "bcOccupancyQa.pdf", "bc-occupancy-qa-task", "bcOccupancyQa.root")'
18+
/// Output: multi-page PDF, and a ROOT file with the canvases and the histograms (by default: name of the PDF with .root)
1819
///
1920
/// \author Igor Altsybeev <Igor.Altsybeev@cern.ch>
2021

@@ -60,6 +61,7 @@ T* getHist(const char* name)
6061
return nullptr;
6162
}
6263
h->SetDirectory(nullptr);
64+
h->SetStats(false); // also when the saved canvases are drawn later
6365
return h;
6466
}
6567

@@ -69,6 +71,7 @@ TH1D* makeRatio(const TH1* num, const TH1* den, const char* name, const char* ti
6971
auto* r = static_cast<TH1D*>(num->Clone(name));
7072
r->SetTitle(title);
7173
r->Divide(num, den, 1., 1., "B");
74+
r->SetStats(false);
7275
return r;
7376
}
7477

@@ -86,13 +89,12 @@ double upperEdgeOfFilledRange(const TH1* h)
8689
}
8790
} // namespace bcoccqa
8891

89-
void plotBcOccupancyQa(const char* fileName = "AnalysisResults.root", const char* outPdf = "bcOccupancyQa.pdf", const char* dirName = "bc-occupancy-qa-task")
92+
void plotBcOccupancyQa(const char* fileName = "AnalysisResults.root", const char* outPdf = "bcOccupancyQa.pdf", const char* dirName = "bc-occupancy-qa-task", const char* outRoot = "")
9093
{
9194
using namespace bcoccqa;
9295
TH1::AddDirectory(kFALSE);
9396
gStyle->SetOptStat(0);
9497
gStyle->SetPalette(kViridis);
95-
gStyle->SetPaperSize(30., 20.); // landscape pages, same aspect ratio as the canvas
9698

9799
std::unique_ptr<TFile> f(TFile::Open(fileName, "READ"));
98100
if (!f || f->IsZombie()) {
@@ -152,85 +154,88 @@ void plotBcOccupancyQa(const char* fileName = "AnalysisResults.root", const char
152154
// ### plots
153155
const double maxOccTracks = hOccTracks ? upperEdgeOfFilledRange(hOccTracks) : 0.;
154156
const double maxOccFT0C = hOccFT0C ? upperEdgeOfFilledRange(hOccFT0C) : 0.;
155-
TCanvas c("c", "BC occupancy QA", 1200, 800);
156-
c.Print(Form("%s[", outPdf));
157-
auto newPage = [&c](int nx, int ny) {
158-
c.Clear();
159-
c.Divide(nx, ny);
157+
// one canvas per page, with the size adapted to the number of pads
158+
std::vector<TCanvas*> canvases;
159+
std::vector<TH1*> derivedHists; // histograms made here (fractions), also saved to the ROOT file
160+
auto newPage = [&canvases](const char* name, const char* title, int width, int height, int nx, int ny) {
161+
auto* canvas = new TCanvas(name, title, width, height);
162+
canvas->Divide(nx, ny);
163+
canvases.push_back(canvas);
164+
return canvas;
160165
};
166+
TCanvas* c = nullptr;
161167

162168
// page 1: BC counters and the cross-check of the lookup by global BC
163-
newPage(3, 1);
169+
c = newPage("cBcCounters", "BC counters", 1500, 550, 3, 1);
164170
if (hBcCounter) {
165-
c.cd(1)->SetLeftMargin(0.15);
171+
c->cd(1)->SetLeftMargin(0.15);
166172
hBcCounter->SetTitle("number of BCs");
167173
hBcCounter->Draw("hist text");
168174
}
169175
if (hNumCollsInBC) {
170-
c.cd(2)->SetLogy();
176+
c->cd(2)->SetLogy();
171177
hNumCollsInBC->SetTitle("all BCs;number of collisions found in the BC;N BCs");
172178
hNumCollsInBC->Draw("hist");
173179
}
174180
if (hBcIndexCheck) {
175-
c.cd(3)->SetBottomMargin(0.3);
176-
c.cd(3)->SetLogy(); // rows of BcOccsAll vs (much fewer) BCs of aod::BCs
181+
c->cd(3)->SetBottomMargin(0.3);
182+
c->cd(3)->SetLogy(); // rows of BcOccsAll vs (much fewer) BCs of aod::BCs
177183
hBcIndexCheck->SetTitle("lookup in BcOccsAll by global BC;;counts");
178184
hBcIndexCheck->GetXaxis()->LabelsOption("v");
179185
hBcIndexCheck->SetMinimum(0.5);
180186
hBcIndexCheck->Draw("hist text");
181187
}
182-
c.Print(outPdf);
183188

184189
// page 2: occupancy distributions
185-
newPage(2, 2);
190+
c = newPage("cOccupancy", "occupancy distributions", 1200, 800, 2, 2);
186191
if (hOccTracks) {
187-
c.cd(1)->SetLogy();
192+
c->cd(1)->SetLogy();
188193
hOccTracks->SetTitle("occupancy by ITS tracks;occupancy by ITS tracks;N BCs");
189194
hOccTracks->GetXaxis()->SetRangeUser(0., maxOccTracks);
190195
hOccTracks->Draw("hist");
191196
}
192197
if (hOccFT0C) {
193-
c.cd(2)->SetLogy();
198+
c->cd(2)->SetLogy();
194199
hOccFT0C->SetTitle("occupancy by FT0C;occupancy by FT0C amplitudes;N BCs");
195200
hOccFT0C->GetXaxis()->SetRangeUser(0., maxOccFT0C);
196201
hOccFT0C->Draw("hist");
197202
}
198203
if (hOccTracksVsFT0C) {
199-
c.cd(3)->SetLogz();
204+
c->cd(3)->SetLogz();
200205
hOccTracksVsFT0C->SetTitle("occupancy: ITS tracks vs FT0C;occupancy by FT0C amplitudes;occupancy by ITS tracks");
201206
hOccTracksVsFT0C->GetXaxis()->SetRangeUser(0., maxOccFT0C);
202207
hOccTracksVsFT0C->GetYaxis()->SetRangeUser(0., maxOccTracks);
203208
hOccTracksVsFT0C->Draw("colz");
204209
}
205210
if (hMedianTime) {
206-
c.cd(4)->SetLogy();
211+
c->cd(4)->SetLogy();
207212
hMedianTime->SetTitle("median time of the occupancy;#Deltat (#mus);N BCs");
208213
hMedianTime->Draw("hist");
209214
}
210-
c.Print(outPdf);
211215

212216
// page 3: occupancy flags
213-
newPage(2, 1);
217+
c = newPage("cOccupancyFlags", "occupancy flags", 1200, 550, 2, 1);
214218
if (hFlags && hFlags->GetBinContent(1) > 0) {
215-
c.cd(1)->SetBottomMargin(0.3);
219+
c->cd(1)->SetBottomMargin(0.3);
216220
auto* hFlagsFrac = static_cast<TH1*>(hFlags->Clone("hFlagsFrac"));
217221
hFlagsFrac->Scale(1. / hFlags->GetBinContent(1));
218222
hFlagsFrac->SetTitle("fraction of BCs passing each flag;;fraction of BCs");
219223
hFlagsFrac->GetXaxis()->LabelsOption("v");
220224
hFlagsFrac->SetMinimum(0.);
221225
hFlagsFrac->SetMaximum(1.1);
222226
hFlagsFrac->Draw("hist text");
227+
derivedHists.push_back(hFlagsFrac);
223228
}
224229
if (hFlagsVsOcc) {
225230
// fraction of BCs passing each flag vs occupancy
226-
c.cd(2);
231+
c->cd(2);
227232
TLegend* leg = new TLegend(0.45, 0.6, 0.89, 0.89);
228233
TH1D* hAll = hFlagsVsOcc->ProjectionY("hFlagsAll", 1, 1);
229234
const int colors[] = {kRed + 1, kOrange + 7, kGreen + 2, kAzure + 2, kBlue + 2, kMagenta + 1, kBlack};
230235
bool first = true;
231236
for (int i = 2; i <= hFlagsVsOcc->GetNbinsX(); i++) {
232237
TH1D* hPass = hFlagsVsOcc->ProjectionY(Form("hFlagPass%d", i), i, i);
233-
TH1D* hFrac = makeRatio(hPass, hAll, Form("hFlagFrac%d", i), "fraction of BCs passing the flags vs occupancy;occupancy by ITS tracks;fraction of BCs");
238+
TH1D* hFrac = makeRatio(hPass, hAll, Form("hFracVsOccupancy_%s", hFlagsVsOcc->GetXaxis()->GetBinLabel(i)), "fraction of BCs passing the flags vs occupancy;occupancy by ITS tracks;fraction of BCs");
234239
hFrac->SetLineColor(colors[(i - 2) % 7]);
235240
hFrac->SetMarkerColor(colors[(i - 2) % 7]);
236241
hFrac->SetMarkerStyle(20);
@@ -239,34 +244,74 @@ void plotBcOccupancyQa(const char* fileName = "AnalysisResults.root", const char
239244
hFrac->SetMaximum(1.1);
240245
hFrac->GetXaxis()->SetRangeUser(0., maxOccTracks);
241246
hFrac->Draw(first ? "p" : "p same");
247+
derivedHists.push_back(hFrac);
242248
leg->AddEntry(hFrac, hFlagsVsOcc->GetXaxis()->GetBinLabel(i), "p");
243249
first = false;
244250
}
245251
leg->Draw();
246252
}
247-
c.Print(outPdf);
248253

249254
// page 4: BC position in the TF and in the orbit
250-
newPage(1, 3);
255+
c = newPage("cBcPosition", "BC position in the TF and in the orbit", 1200, 800, 1, 3);
251256
if (hBcInTF && hBcInTFDefined) {
252-
c.cd(1);
257+
c->cd(1);
253258
TH1D* hFracDefined = makeRatio(hBcInTFDefined, hBcInTF, "hFracDefined", "fraction of BCs with calculated occupancy;BC in TF;fraction");
254259
hFracDefined->SetMinimum(0.);
255260
hFracDefined->SetMaximum(1.1);
256261
hFracDefined->Draw("hist");
262+
derivedHists.push_back(hFracDefined);
257263
}
258264
if (pOccVsBcInTF) {
259-
c.cd(2);
265+
c->cd(2);
260266
pOccVsBcInTF->SetTitle("mean occupancy vs BC in TF;BC in TF;mean occupancy by ITS tracks");
261267
pOccVsBcInTF->Draw();
262268
}
263269
if (pOccVsBcInOrbit) {
264-
c.cd(3);
270+
c->cd(3);
265271
pOccVsBcInOrbit->SetTitle("mean occupancy vs BC in orbit;BC in orbit;mean occupancy by ITS tracks");
266272
pOccVsBcInOrbit->Draw("hist"); // 3564 bins: error bars would hide the pattern
267273
}
268-
c.Print(outPdf);
269274

270-
c.Print(Form("%s]", outPdf));
275+
// PDF: each page with the aspect ratio of its canvas
276+
for (size_t i = 0; i < canvases.size(); i++) {
277+
gStyle->SetPaperSize(30., 30. * canvases[i]->GetWh() / canvases[i]->GetWw());
278+
if (i == 0) {
279+
canvases[i]->Print(Form("%s[", outPdf));
280+
}
281+
canvases[i]->Print(outPdf);
282+
if (i == canvases.size() - 1) {
283+
canvases[i]->Print(Form("%s]", outPdf));
284+
}
285+
}
271286
std::printf("plots saved in %s\n", outPdf);
287+
288+
// ROOT file: canvases and histograms (from the QA task and the fractions made here)
289+
TString rootName = outRoot;
290+
if (rootName.IsNull()) {
291+
rootName = outPdf;
292+
if (rootName.EndsWith(".pdf")) {
293+
rootName.Resize(rootName.Length() - 4);
294+
}
295+
rootName += ".root";
296+
}
297+
std::unique_ptr<TFile> fOut(TFile::Open(rootName, "RECREATE"));
298+
if (!fOut || fOut->IsZombie()) {
299+
std::printf("cannot create %s\n", rootName.Data());
300+
return;
301+
}
302+
fOut->mkdir("canvases")->cd();
303+
for (auto* canvas : canvases) {
304+
canvas->Write();
305+
}
306+
fOut->mkdir("histograms")->cd();
307+
for (TH1* h : {static_cast<TH1*>(hBcCounter), hNumCollsInBC, hBcInTF, hBcInTFDefined, hOccTracks, hOccFT0C, static_cast<TH1*>(hOccTracksVsFT0C), hMedianTime,
308+
static_cast<TH1*>(pOccVsBcInTF), static_cast<TH1*>(pOccVsBcInOrbit), hFlags, static_cast<TH1*>(hFlagsVsOcc), hBcIndexCheck}) {
309+
if (h) {
310+
h->Write();
311+
}
312+
}
313+
for (TH1* h : derivedHists) {
314+
h->Write();
315+
}
316+
std::printf("canvases and histograms saved in %s\n", rootName.Data());
272317
}

0 commit comments

Comments
 (0)