]>
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); | |
5dd7d263 | 232 | |
2dbde04b | 233 | fCanvas->SetTopMargin(0.10); |
234 | fCanvas->SetBottomMargin(0.10); | |
235 | ||
236 | fStore = TFile::Open(Form("%s.root", fTeXName.Data()), "RECREATE"); | |
237 | if (!fStore) | |
238 | Warning("MakeCanvas", "Failed to make store %s.root", fTeXName.Data()); | |
239 | ||
240 | fToDelete = ""; | |
241 | } | |
242 | /** | |
243 | * Put a title on the canvas. Also clears page in LaTeX file | |
244 | * | |
245 | * @param title Title | |
246 | */ | |
247 | void CanvasTitle(const char* title) | |
248 | { | |
249 | if (!fCanvas) return; | |
250 | ||
251 | fCanvas->cd(); | |
252 | fCanvas->Clear(); | |
253 | fCanvas->SetBorderSize(0); | |
254 | fCanvas->SetLeftMargin(0.15); | |
255 | fCanvas->SetRightMargin(0.02); | |
e140afb9 | 256 | |
2dbde04b | 257 | fCanvas->SetTopMargin(0.10); |
258 | fCanvas->SetBottomMargin(0.10); | |
259 | ||
260 | *fTeX << "\\clearpage\n" | |
261 | << "%% -----------------------------------------------------" | |
262 | << std::endl; | |
263 | ||
3405bb49 | 264 | TString tit(title); |
265 | tit.ReplaceAll("#LT", "<"); | |
266 | tit.ReplaceAll("#GT", ">"); | |
267 | tit.ReplaceAll("#Delta", "Δ"); | |
268 | tit.ReplaceAll("#xi", "ξ"); | |
269 | tit.ReplaceAll("#sigma", "σ"); | |
270 | tit.ReplaceAll("#chi", "χ"); | |
271 | tit.ReplaceAll("#nu", "ν"); | |
dc8aa359 | 272 | tit.ReplaceAll("_{p}", "<sub>p</sub>"); |
273 | tit.ReplaceAll("_{z}", "<sub>z</sub>"); | |
274 | tit.ReplaceAll("^{2}", "<sup>2</sup>"); | |
3405bb49 | 275 | *fHtml << "<tr><td>" << tit << "</td>" << std::flush; |
276 | ||
5e8eab11 | 277 | PutCanvasTitle(title); |
278 | } | |
60db3344 | 279 | /** |
280 | * Put a title on the canvas | |
281 | * | |
282 | * @param title Title | |
283 | */ | |
5e8eab11 | 284 | void PutCanvasTitle(const char* title) |
285 | { | |
2dbde04b | 286 | // Put title on top |
287 | TLatex* topText = new TLatex(.5, .99, title); | |
288 | topText->SetTextAlign(23); | |
289 | topText->SetTextSize(.038); | |
290 | topText->SetTextFont(42); | |
291 | topText->SetTextColor(kBlue+3); | |
292 | topText->SetNDC(); | |
293 | topText->Draw(); | |
294 | } | |
295 | /** | |
296 | * Print the canvas to PNG and include it into LaTeX file | |
297 | * | |
298 | * @param pngName Base name of PNG | |
299 | * @param runNo Run number to append | |
300 | */ | |
27fcc3c7 | 301 | void PrintCanvas(const char* pngName, UInt_t /*runNo*/) |
2dbde04b | 302 | { |
27fcc3c7 | 303 | // TString s(Form("%s_%09d", pngName, runNo)); |
304 | TString s(pngName); | |
2dbde04b | 305 | PrintCanvas(s.Data()); |
306 | } | |
307 | /** | |
308 | * Print the canvas to PNG and include it into LaTeX file. Stores | |
309 | * canvas in storage file | |
310 | * | |
311 | * @param pngName Base name of PNG | |
33438b4c | 312 | * @param areas Areas to print |
2dbde04b | 313 | */ |
7fbaa8da | 314 | void PrintCanvas(const char* pngName, TCollection* areas=0) |
2dbde04b | 315 | { |
dc8aa359 | 316 | gSystem->Exec(Form("rm -f %s.png %s.html", pngName, pngName)); |
2dbde04b | 317 | fCanvas->SaveAs(Form("%s.png", pngName)); |
318 | *fTeX << "\\begin{center}\n" | |
319 | << "\\includegraphics[keepaspectratio,height=\\textheight]{" | |
320 | << pngName << "}\n" | |
321 | << "\\end{center}" << std::endl; | |
3405bb49 | 322 | *fHtml << "<td><a href='" << pngName << ".html'>Plot</a></td></tr>" |
323 | << std::endl; | |
324 | ||
325 | std::ofstream img(Form("%s.html", pngName)); | |
7fbaa8da | 326 | img << "<!DOCTYPE html>\n" |
327 | << "<html>\n" | |
3405bb49 | 328 | << " <head>\n" |
329 | << " <title>" << pngName << "</title>\n" | |
7fbaa8da | 330 | << " <link rel='stylesheet' href='style.css'></link>\n" |
331 | << " <link rel='shortcut icon' href='fmd_favicon.png' " | |
332 | << "type='image/x-png'>\n" | |
3405bb49 | 333 | << " </head>\n" |
334 | << " <body>\n" | |
335 | << " <h1>" << pngName << "</h1>\n" | |
7fbaa8da | 336 | << " <div id=\"imap\">\n" |
337 | << " <img src=\"" << pngName << ".png\">\n"; | |
338 | if (areas) { | |
339 | TIter next(areas); | |
340 | TObject* o = 0; | |
341 | while ((o = next())) | |
342 | img << " " << o->GetName() << "\n"; | |
343 | } | |
344 | img << " </div>\n" << std::endl; | |
3405bb49 | 345 | WriteImageFooter(img, pngName); |
346 | img << " </body>\n" | |
347 | << "</html>" << std::endl; | |
348 | img.close(); | |
349 | gSystem->Exec(Form("chmod g+rw %s.html", pngName)); | |
350 | ||
2dbde04b | 351 | fToDelete.Append(Form(" %s.png", pngName)); |
352 | TDirectory* d = gDirectory; | |
353 | fStore->cd(); | |
354 | fCanvas->Write(); | |
355 | d->cd(); | |
356 | } | |
60db3344 | 357 | /** |
358 | * Write out image footer | |
359 | * | |
360 | * @param o Output stream | |
361 | */ | |
3405bb49 | 362 | virtual void WriteImageFooter(std::ostream& o, const char* /*pngName*/) |
363 | { | |
364 | TDatime now; | |
365 | o << "<div class='back'>\n" | |
366 | << "<a href='" << fTeXName << ".html'>Back</a>\n" | |
367 | << "</div>\n" | |
b288a8e6 | 368 | << "<div class='change'>\n" |
3405bb49 | 369 | << " Last update: " << now.AsString() << "\n" |
370 | << "</div>" << std::endl; | |
371 | } | |
2dbde04b | 372 | /** |
373 | * Close the LaTeX and storage files. Runs PDFLaTeX on LaTeX | |
374 | * file. Makes sure that the files are group writable. | |
375 | * | |
376 | * @param deletePNGs If true, delete intermident PNG files | |
377 | */ | |
378 | void Close(bool deletePNGs=true) | |
379 | { | |
3405bb49 | 380 | const char* base = fTeXName.Data(); |
2dbde04b | 381 | if (fTeX) { |
382 | *fTeX << "\\end{document}\n" | |
383 | << "%% EOF" << std::endl; | |
384 | fTeX->close(); | |
385 | fTeX = 0; | |
386 | ||
2dbde04b | 387 | gSystem->Exec(Form("pdflatex %s.tex > /dev/null 2>&1", base)); |
2dbde04b | 388 | Info("Close", "PDF file %s.pdf generated", base); |
389 | } | |
3405bb49 | 390 | if (fHtml) { |
391 | TDatime now; | |
392 | *fHtml << "</table>" << std::endl; | |
9a684059 | 393 | WriteLinks(); |
3405bb49 | 394 | WriteFooter(); |
395 | *fHtml << "</body></html>" << std::endl; | |
396 | fHtml->close(); | |
397 | fHtml = 0; | |
398 | gSystem->Exec(Form("chmod g+rw %s.html", fTeXName.Data())); | |
399 | } | |
2dbde04b | 400 | if (fStore) { |
401 | fStore->Write(); | |
402 | fStore->Close(); | |
3405bb49 | 403 | gSystem->Exec(Form("chmod 664 %s.root", fTeXName.Data())); |
2dbde04b | 404 | } |
3405bb49 | 405 | TString cmd(Form("rm -f %s.log %s.aux %s.tex %s", |
406 | base, base, base, | |
407 | deletePNGs ? fToDelete.Data() : "")); | |
3405bb49 | 408 | gSystem->Exec(cmd.Data()); |
409 | gSystem->Exec(Form("chmod g+rw %s.pdf %s", base, | |
410 | deletePNGs ? "" : fToDelete.Data())); | |
411 | } | |
60db3344 | 412 | /** |
413 | * Output links | |
414 | * | |
415 | */ | |
9a684059 | 416 | virtual void WriteLinks() |
3405bb49 | 417 | { |
9a684059 | 418 | *fHtml << "<h3>Collection of plots</h3>\n" |
419 | << "<ul>\n" | |
3405bb49 | 420 | << " <li><a href='" << fTeXName << ".pdf'>PDF</a></li>\n" |
421 | << " <li><a href='" << fTeXName << ".root'>ROOT</a></li>\n" | |
9a684059 | 422 | << "</ul>" << std::endl; |
e140afb9 | 423 | if (fPeriod.IsNull()) return; |
424 | Bool_t isMC = (fDataType.EqualTo("sim", TString::kIgnoreCase) || | |
5cd23d34 | 425 | fPass.BeginsWith("passMC", TString::kIgnoreCase)); |
e140afb9 | 426 | *fHtml << "<ul>\n" |
427 | << " <li><a href='https://alimonitor.cern.ch/" | |
428 | << (isMC ? "job_details.jsp" : "production/raw.jsp") | |
429 | << "?jt_field1=" << fPeriod << "'>Producion(s)</a></li>\n" | |
430 | << "</ul>" << std::endl; | |
5dd7d263 | 431 | if (fPeriod.IsNull()) return; |
432 | Bool_t isMC = (fDataType.EqualTo("sim", TString::kIgnoreCase) || | |
433 | fPass.BeginsWith("passMC", TString::kIgnoreCase)); | |
434 | *fHtml << "<ul>\n" | |
435 | << " <li><a href='https://alimonitor.cern.ch/" | |
436 | << (isMC ? "job_details.jsp" : "production/raw.jsp") | |
437 | << "?jt_field1=" << fPeriod << "'>Producion(s)</a></li>\n" | |
438 | << "</ul>" << std::endl; | |
9a684059 | 439 | } |
440 | /** | |
441 | * Write full job footer | |
442 | * | |
443 | */ | |
444 | virtual void WriteFooter() | |
445 | { | |
446 | TDatime now; | |
447 | *fHtml << "<div class='back'>\n" | |
3405bb49 | 448 | << "<a href='index.html'>Back</a>\n" |
449 | << "</div>\n" | |
b288a8e6 | 450 | << "<div class='change'>\n" |
3405bb49 | 451 | << " Last update: " << now.AsString() << "\n" |
452 | << "</div>" << std::endl; | |
2dbde04b | 453 | } |
2dbde04b | 454 | // --- Members ----------------------------------------------------- |
455 | QARing* fFMD1i; // Pointer to ring object | |
456 | QARing* fFMD2i; // Pointer to ring object | |
457 | QARing* fFMD2o; // Pointer to ring object | |
458 | QARing* fFMD3i; // Pointer to ring object | |
459 | QARing* fFMD3o; // Pointer to ring object | |
460 | Global* fGlobal; // Pointer to global run object | |
461 | TTree* fTree; // Pointer to tree object | |
462 | TFile* fOutput; // Pointer to tree file | |
463 | TFile* fStore; // Pointer to storage file | |
464 | std::ofstream* fTeX; // pointer to LaTeX stream | |
3405bb49 | 465 | std::ofstream* fHtml; // pointer to HTML stream |
2dbde04b | 466 | TString fTeXName; // Base name of LaTeX file |
467 | TString fToDelete; // List of files to possibly delete | |
468 | TCanvas* fCanvas; // Pointer to canvas object | |
bae153e5 | 469 | TString fOutputName; // Output tree file name |
27fcc3c7 | 470 | TString fDataType; // Data type |
7fbaa8da | 471 | Int_t fYear; // Production year |
27fcc3c7 | 472 | TString fPeriod; // Period identifier |
473 | TString fPass; // Pass identifier | |
2dbde04b | 474 | }; |
475 | ||
476 | #endif | |
477 | ||
478 | ||
479 | // Local Variables: | |
480 | // mode: C++ | |
481 | // End: |