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