]>
Commit | Line | Data |
---|---|---|
2dbde04b | 1 | /** |
2 | * @file QABase.h | |
3 | * @author Christian Holm Christensen <cholm@nbi.dk> | |
4 | * @date Thu Nov 17 11:58:11 2011 | |
5 | * | |
6 | * @brief Base class for QA active classes | |
7 | * | |
bd6f5206 | 8 | * @ingroup pwglf_forward_qa_scripts |
2dbde04b | 9 | * |
10 | */ | |
11 | #ifndef QABASE_H | |
12 | #define QABASE_H | |
13 | #ifndef __CINT__ | |
14 | # include <TTree.h> | |
15 | # include <TFile.h> | |
16 | # include <TError.h> | |
17 | # include <TCanvas.h> | |
18 | # include <TSystem.h> | |
19 | # include <fstream> | |
20 | # include <TLatex.h> | |
21 | # include <TStyle.h> | |
22 | # include "QARing.h" | |
23 | #else | |
24 | class TTree; | |
25 | class TFile; | |
26 | class QARing; | |
27 | class Global; | |
28 | class TCanvas; | |
29 | #endif | |
30 | ||
31 | /** | |
32 | * Base class for active QA classes. This manages the I/O files, like | |
33 | * the tree file, the LaTeX file, and the storage file | |
34 | * | |
bd6f5206 | 35 | * @ingroup pwglf_forward_qa_scripts |
2dbde04b | 36 | */ |
37 | struct QABase | |
38 | { | |
27fcc3c7 | 39 | QABase(const TString& dataType, |
40 | Int_t prodYear, | |
41 | const TString& period, | |
42 | const TString& pass) | |
2dbde04b | 43 | : fFMD1i(0), |
44 | fFMD2i(0), | |
45 | fFMD2o(0), | |
46 | fFMD3i(0), | |
47 | fFMD3o(0), | |
48 | fGlobal(0), | |
49 | fTree(0), | |
50 | fOutput(0), | |
51 | fStore(0), | |
52 | fTeX(0), | |
3405bb49 | 53 | fHtml(0), |
27fcc3c7 | 54 | fTeXName("index"), |
2dbde04b | 55 | fToDelete(""), |
56 | fCanvas(0), | |
27fcc3c7 | 57 | fOutputName("trending.root"), |
58 | fDataType(dataType), | |
7fbaa8da | 59 | fYear(prodYear), |
27fcc3c7 | 60 | fPeriod(period), |
61 | fPass(pass) | |
2dbde04b | 62 | {} |
63 | /** | |
64 | * Copy constructor | |
65 | * | |
66 | * @param o Object to copy from | |
67 | */ | |
68 | QABase(const QABase& o) | |
69 | : fFMD1i(o.fFMD1i), | |
70 | fFMD2i(o.fFMD2i), | |
71 | fFMD2o(o.fFMD2o), | |
72 | fFMD3i(o.fFMD3i), | |
73 | fFMD3o(o.fFMD3o), | |
74 | fGlobal(o.fGlobal), | |
75 | fTree(o.fTree), | |
76 | fOutput(o.fOutput), | |
77 | fStore(o.fStore), | |
78 | fTeX(o.fTeX), | |
3405bb49 | 79 | fHtml(o.fHtml), |
2dbde04b | 80 | fTeXName(o.fTeXName), |
81 | fToDelete(o.fToDelete), | |
82 | fCanvas(o.fCanvas), | |
27fcc3c7 | 83 | fOutputName(o.fOutputName), |
84 | fDataType(o.fDataType), | |
85 | fYear(o.fYear), | |
86 | fPeriod(o.fPeriod), | |
87 | fPass(o.fPass) | |
2dbde04b | 88 | {} |
89 | /** | |
90 | * Assignment operator | |
91 | * | |
92 | * @return Reference to this object | |
93 | */ | |
94 | QABase& operator=(const QABase&) { return *this; } | |
95 | /** | |
96 | * Desctructor | |
97 | */ | |
98 | virtual ~QABase() | |
99 | { | |
100 | if (fFMD1i) { delete fFMD1i; } | |
101 | if (fFMD2i) { delete fFMD2i; } | |
102 | if (fFMD2o) { delete fFMD2o; } | |
103 | if (fFMD3i) { delete fFMD3i; } | |
104 | if (fFMD3o) { delete fFMD3o; } | |
105 | if (fGlobal) { delete fGlobal; } | |
106 | if (fTree) { delete fTree; } | |
107 | if (fOutput) { delete fOutput; } | |
108 | if (fStore) { delete fStore; } | |
109 | if (fTeX) { fTeX->close(); fTeX = 0; } | |
3405bb49 | 110 | if (fHtml) { fHtml->close(); fHtml = 0; } |
2dbde04b | 111 | } |
bae153e5 | 112 | /** |
113 | * Set the output file name | |
114 | * | |
115 | * @param name Name of output (tree) file | |
116 | */ | |
117 | void SetOutputName(const char* name) { fOutputName = name; } | |
2dbde04b | 118 | /** |
119 | * The name of the TTree output file | |
120 | * | |
121 | * @return Output file name | |
122 | */ | |
bae153e5 | 123 | const char* OutputName() const { return fOutputName.Data(); } |
60db3344 | 124 | /** |
125 | * Make a tree | |
126 | * | |
127 | * @param read If true, read from file | |
128 | * | |
129 | * @return True on success | |
130 | */ | |
bae153e5 | 131 | virtual Bool_t MakeTree(bool read) |
2dbde04b | 132 | { |
27fcc3c7 | 133 | fOutput = new TFile(OutputName(), (read ? "READ" : "RECREATE")); |
134 | if (!fOutput) { | |
135 | Error("MakeTree", "Failed to open output file"); | |
136 | return false; | |
2dbde04b | 137 | } |
27fcc3c7 | 138 | if (read) fTree = static_cast<TTree*>(fOutput->Get("T")); |
139 | else fTree = new TTree("T", "T"); | |
bae153e5 | 140 | if (!fTree) { |
141 | Error("MakeTree", "No tree defined!"); | |
142 | return false; | |
143 | } | |
144 | ||
145 | return true; | |
146 | } | |
147 | /** | |
148 | * Initialize | |
149 | * | |
150 | * @param read If true initialise for reading tree file | |
151 | * | |
152 | * @return True on success | |
153 | */ | |
154 | Bool_t Init(bool read=false) | |
155 | { | |
156 | if (!MakeTree(read)) return false; | |
157 | ||
2dbde04b | 158 | if (read) fGlobal = Global::SetBranch(fTree); |
159 | else fGlobal = Global::MakeBranch(fTree); | |
bae153e5 | 160 | |
161 | fToDelete = ""; | |
2dbde04b | 162 | |
163 | fFMD1i->Init(fTree, read); | |
164 | fFMD2i->Init(fTree, read); | |
165 | fFMD2o->Init(fTree, read); | |
166 | fFMD3i->Init(fTree, read); | |
167 | fFMD3o->Init(fTree, read); | |
168 | ||
169 | return true; | |
170 | } | |
171 | /** | |
172 | * Make a canvas, LaTeX file, and storage file | |
173 | * | |
174 | * @param title Title of canvas and files | |
175 | */ | |
176 | void MakeCanvas(const char* title) | |
177 | { | |
dc8aa359 | 178 | if (fCanvas) { |
179 | delete fCanvas; | |
180 | fCanvas = 0; | |
181 | } | |
182 | const char* base = fTeXName.Data(); | |
183 | gSystem->Exec(Form("rm -f %s.tex %s.html %s.root %s.pdf", | |
184 | base, base, base, base)); | |
185 | ||
186 | fTeX = new std::ofstream(Form("%s.tex", base)); | |
187 | fHtml = new std::ofstream(Form("%s.html", base)); | |
6953b59b | 188 | |
189 | TString texTitle(title); | |
190 | texTitle.ReplaceAll("_", "-"); | |
3405bb49 | 191 | |
2dbde04b | 192 | *fTeX << "\\documentclass[landscape,a4paper,12pt]{article}\n" |
6953b59b | 193 | << "\\nonstopmode\n" |
2dbde04b | 194 | << "\\usepackage[margin=2cm,a4paper]{geometry}\n" |
195 | << "\\usepackage{graphicx}\n" | |
6953b59b | 196 | << "\\title{{\\Huge\\bf " << texTitle << "}}\n" |
2dbde04b | 197 | << "\\author{{\\LARGE FMD Team}}\n" |
198 | << "\\date{{\\Large \\today}}\n" | |
199 | << "\\begin{document}\n" | |
200 | << "\\thispagestyle{empty}\n" | |
201 | << "\\maketitle" << std::endl; | |
202 | ||
7fbaa8da | 203 | *fHtml << "<!DOCTYPE html>\n" |
204 | << "<html>\n" | |
3405bb49 | 205 | << " <head>\n" |
206 | << " <title>QA information - " << title << "</title>\n" | |
b288a8e6 | 207 | << " <link rel='stylesheet' href='style.css'>\n" |
7fbaa8da | 208 | << " <link rel='shortcut icon' href='fmd_favicon.png' " |
209 | << "type='image/x-png'>\n" | |
3405bb49 | 210 | << " </head>\n" |
211 | << "<body>\n" | |
212 | << " <h1>" << title << "</h1>\n" | |
213 | << " <table>" | |
214 | << std::endl; | |
215 | ||
2dbde04b | 216 | gStyle->SetPalette(1); |
217 | gStyle->SetOptFit(0); | |
218 | gStyle->SetOptStat(0); | |
219 | gStyle->SetOptTitle(1); | |
220 | gStyle->SetTitleW(.4); | |
221 | gStyle->SetTitleH(.1); | |
222 | // gStyle->SetTitleColor(0); | |
223 | gStyle->SetTitleStyle(0); | |
224 | gStyle->SetTitleBorderSize(0); | |
225 | gStyle->SetTitleX(.6); | |
226 | ||
227 | fCanvas = new TCanvas("qa", title, 900, 700); | |
228 | fCanvas->SetFillColor(0); | |
229 | fCanvas->SetBorderSize(0); | |
230 | fCanvas->SetLeftMargin(0.15); | |
231 | fCanvas->SetRightMargin(0.02); | |
232 | fCanvas->SetTopMargin(0.10); | |
233 | fCanvas->SetBottomMargin(0.10); | |
234 | ||
235 | fStore = TFile::Open(Form("%s.root", fTeXName.Data()), "RECREATE"); | |
236 | if (!fStore) | |
237 | Warning("MakeCanvas", "Failed to make store %s.root", fTeXName.Data()); | |
238 | ||
239 | fToDelete = ""; | |
240 | } | |
241 | /** | |
242 | * Put a title on the canvas. Also clears page in LaTeX file | |
243 | * | |
244 | * @param title Title | |
245 | */ | |
246 | void CanvasTitle(const char* title) | |
247 | { | |
248 | if (!fCanvas) return; | |
249 | ||
250 | fCanvas->cd(); | |
251 | fCanvas->Clear(); | |
252 | fCanvas->SetBorderSize(0); | |
253 | fCanvas->SetLeftMargin(0.15); | |
254 | fCanvas->SetRightMargin(0.02); | |
255 | fCanvas->SetTopMargin(0.10); | |
256 | fCanvas->SetBottomMargin(0.10); | |
257 | ||
258 | *fTeX << "\\clearpage\n" | |
259 | << "%% -----------------------------------------------------" | |
260 | << std::endl; | |
261 | ||
3405bb49 | 262 | TString tit(title); |
263 | tit.ReplaceAll("#LT", "<"); | |
264 | tit.ReplaceAll("#GT", ">"); | |
265 | tit.ReplaceAll("#Delta", "Δ"); | |
266 | tit.ReplaceAll("#xi", "ξ"); | |
267 | tit.ReplaceAll("#sigma", "σ"); | |
268 | tit.ReplaceAll("#chi", "χ"); | |
269 | tit.ReplaceAll("#nu", "ν"); | |
dc8aa359 | 270 | tit.ReplaceAll("_{p}", "<sub>p</sub>"); |
271 | tit.ReplaceAll("_{z}", "<sub>z</sub>"); | |
272 | tit.ReplaceAll("^{2}", "<sup>2</sup>"); | |
3405bb49 | 273 | *fHtml << "<tr><td>" << tit << "</td>" << std::flush; |
274 | ||
5e8eab11 | 275 | PutCanvasTitle(title); |
276 | } | |
60db3344 | 277 | /** |
278 | * Put a title on the canvas | |
279 | * | |
280 | * @param title Title | |
281 | */ | |
5e8eab11 | 282 | void PutCanvasTitle(const char* title) |
283 | { | |
2dbde04b | 284 | // Put title on top |
285 | TLatex* topText = new TLatex(.5, .99, title); | |
286 | topText->SetTextAlign(23); | |
287 | topText->SetTextSize(.038); | |
288 | topText->SetTextFont(42); | |
289 | topText->SetTextColor(kBlue+3); | |
290 | topText->SetNDC(); | |
291 | topText->Draw(); | |
292 | } | |
293 | /** | |
294 | * Print the canvas to PNG and include it into LaTeX file | |
295 | * | |
296 | * @param pngName Base name of PNG | |
297 | * @param runNo Run number to append | |
298 | */ | |
27fcc3c7 | 299 | void PrintCanvas(const char* pngName, UInt_t /*runNo*/) |
2dbde04b | 300 | { |
27fcc3c7 | 301 | // TString s(Form("%s_%09d", pngName, runNo)); |
302 | TString s(pngName); | |
2dbde04b | 303 | PrintCanvas(s.Data()); |
304 | } | |
305 | /** | |
306 | * Print the canvas to PNG and include it into LaTeX file. Stores | |
307 | * canvas in storage file | |
308 | * | |
309 | * @param pngName Base name of PNG | |
33438b4c | 310 | * @param areas Areas to print |
2dbde04b | 311 | */ |
7fbaa8da | 312 | void PrintCanvas(const char* pngName, TCollection* areas=0) |
2dbde04b | 313 | { |
dc8aa359 | 314 | gSystem->Exec(Form("rm -f %s.png %s.html", pngName, pngName)); |
2dbde04b | 315 | fCanvas->SaveAs(Form("%s.png", pngName)); |
316 | *fTeX << "\\begin{center}\n" | |
317 | << "\\includegraphics[keepaspectratio,height=\\textheight]{" | |
318 | << pngName << "}\n" | |
319 | << "\\end{center}" << std::endl; | |
3405bb49 | 320 | *fHtml << "<td><a href='" << pngName << ".html'>Plot</a></td></tr>" |
321 | << std::endl; | |
322 | ||
323 | std::ofstream img(Form("%s.html", pngName)); | |
7fbaa8da | 324 | img << "<!DOCTYPE html>\n" |
325 | << "<html>\n" | |
3405bb49 | 326 | << " <head>\n" |
327 | << " <title>" << pngName << "</title>\n" | |
7fbaa8da | 328 | << " <link rel='stylesheet' href='style.css'></link>\n" |
329 | << " <link rel='shortcut icon' href='fmd_favicon.png' " | |
330 | << "type='image/x-png'>\n" | |
3405bb49 | 331 | << " </head>\n" |
332 | << " <body>\n" | |
333 | << " <h1>" << pngName << "</h1>\n" | |
7fbaa8da | 334 | << " <div id=\"imap\">\n" |
335 | << " <img src=\"" << pngName << ".png\">\n"; | |
336 | if (areas) { | |
337 | TIter next(areas); | |
338 | TObject* o = 0; | |
339 | while ((o = next())) | |
340 | img << " " << o->GetName() << "\n"; | |
341 | } | |
342 | img << " </div>\n" << std::endl; | |
3405bb49 | 343 | WriteImageFooter(img, pngName); |
344 | img << " </body>\n" | |
345 | << "</html>" << std::endl; | |
346 | img.close(); | |
347 | gSystem->Exec(Form("chmod g+rw %s.html", pngName)); | |
348 | ||
2dbde04b | 349 | fToDelete.Append(Form(" %s.png", pngName)); |
350 | TDirectory* d = gDirectory; | |
351 | fStore->cd(); | |
352 | fCanvas->Write(); | |
353 | d->cd(); | |
354 | } | |
60db3344 | 355 | /** |
356 | * Write out image footer | |
357 | * | |
358 | * @param o Output stream | |
359 | */ | |
3405bb49 | 360 | virtual void WriteImageFooter(std::ostream& o, const char* /*pngName*/) |
361 | { | |
362 | TDatime now; | |
363 | o << "<div class='back'>\n" | |
364 | << "<a href='" << fTeXName << ".html'>Back</a>\n" | |
365 | << "</div>\n" | |
b288a8e6 | 366 | << "<div class='change'>\n" |
3405bb49 | 367 | << " Last update: " << now.AsString() << "\n" |
368 | << "</div>" << std::endl; | |
369 | } | |
2dbde04b | 370 | /** |
371 | * Close the LaTeX and storage files. Runs PDFLaTeX on LaTeX | |
372 | * file. Makes sure that the files are group writable. | |
373 | * | |
374 | * @param deletePNGs If true, delete intermident PNG files | |
375 | */ | |
376 | void Close(bool deletePNGs=true) | |
377 | { | |
3405bb49 | 378 | const char* base = fTeXName.Data(); |
2dbde04b | 379 | if (fTeX) { |
380 | *fTeX << "\\end{document}\n" | |
381 | << "%% EOF" << std::endl; | |
382 | fTeX->close(); | |
383 | fTeX = 0; | |
384 | ||
2dbde04b | 385 | gSystem->Exec(Form("pdflatex %s.tex > /dev/null 2>&1", base)); |
2dbde04b | 386 | Info("Close", "PDF file %s.pdf generated", base); |
387 | } | |
3405bb49 | 388 | if (fHtml) { |
389 | TDatime now; | |
390 | *fHtml << "</table>" << std::endl; | |
9a684059 | 391 | WriteLinks(); |
3405bb49 | 392 | WriteFooter(); |
393 | *fHtml << "</body></html>" << std::endl; | |
394 | fHtml->close(); | |
395 | fHtml = 0; | |
396 | gSystem->Exec(Form("chmod g+rw %s.html", fTeXName.Data())); | |
397 | } | |
2dbde04b | 398 | if (fStore) { |
399 | fStore->Write(); | |
400 | fStore->Close(); | |
3405bb49 | 401 | gSystem->Exec(Form("chmod 664 %s.root", fTeXName.Data())); |
2dbde04b | 402 | } |
3405bb49 | 403 | TString cmd(Form("rm -f %s.log %s.aux %s.tex %s", |
404 | base, base, base, | |
405 | deletePNGs ? fToDelete.Data() : "")); | |
3405bb49 | 406 | gSystem->Exec(cmd.Data()); |
407 | gSystem->Exec(Form("chmod g+rw %s.pdf %s", base, | |
408 | deletePNGs ? "" : fToDelete.Data())); | |
409 | } | |
60db3344 | 410 | /** |
411 | * Output links | |
412 | * | |
413 | */ | |
9a684059 | 414 | virtual void WriteLinks() |
3405bb49 | 415 | { |
9a684059 | 416 | *fHtml << "<h3>Collection of plots</h3>\n" |
417 | << "<ul>\n" | |
3405bb49 | 418 | << " <li><a href='" << fTeXName << ".pdf'>PDF</a></li>\n" |
419 | << " <li><a href='" << fTeXName << ".root'>ROOT</a></li>\n" | |
9a684059 | 420 | << "</ul>" << std::endl; |
421 | } | |
422 | /** | |
423 | * Write full job footer | |
424 | * | |
425 | */ | |
426 | virtual void WriteFooter() | |
427 | { | |
428 | TDatime now; | |
429 | *fHtml << "<div class='back'>\n" | |
3405bb49 | 430 | << "<a href='index.html'>Back</a>\n" |
431 | << "</div>\n" | |
b288a8e6 | 432 | << "<div class='change'>\n" |
3405bb49 | 433 | << " Last update: " << now.AsString() << "\n" |
434 | << "</div>" << std::endl; | |
2dbde04b | 435 | } |
2dbde04b | 436 | // --- Members ----------------------------------------------------- |
437 | QARing* fFMD1i; // Pointer to ring object | |
438 | QARing* fFMD2i; // Pointer to ring object | |
439 | QARing* fFMD2o; // Pointer to ring object | |
440 | QARing* fFMD3i; // Pointer to ring object | |
441 | QARing* fFMD3o; // Pointer to ring object | |
442 | Global* fGlobal; // Pointer to global run object | |
443 | TTree* fTree; // Pointer to tree object | |
444 | TFile* fOutput; // Pointer to tree file | |
445 | TFile* fStore; // Pointer to storage file | |
446 | std::ofstream* fTeX; // pointer to LaTeX stream | |
3405bb49 | 447 | std::ofstream* fHtml; // pointer to HTML stream |
2dbde04b | 448 | TString fTeXName; // Base name of LaTeX file |
449 | TString fToDelete; // List of files to possibly delete | |
450 | TCanvas* fCanvas; // Pointer to canvas object | |
bae153e5 | 451 | TString fOutputName; // Output tree file name |
27fcc3c7 | 452 | TString fDataType; // Data type |
7fbaa8da | 453 | Int_t fYear; // Production year |
27fcc3c7 | 454 | TString fPeriod; // Period identifier |
455 | TString fPass; // Pass identifier | |
2dbde04b | 456 | }; |
457 | ||
458 | #endif | |
459 | ||
460 | ||
461 | // Local Variables: | |
462 | // mode: C++ | |
463 | // End: |