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