REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestMetadataPlot.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
233
234#include "TRestMetadataPlot.h"
235
236#include "TRestManager.h"
237#include "TRestTools.h"
238
239using namespace std;
240
241#include <TGraph.h>
242#include <TLegend.h>
243#include <TStyle.h>
244
245#include <ctime>
246
247ClassImp(TRestMetadataPlot);
248
253
268TRestMetadataPlot::TRestMetadataPlot(const char* configFilename, const char* name)
269 : TRestMetadata(configFilename) {
270 Initialize();
271
273}
274
279 if (fRun != nullptr) delete fRun;
280}
281
286 SetSectionName(this->ClassName());
287
288 fRun = nullptr;
289
290 fNFiles = 0;
291
292 fCombinedCanvas = nullptr;
293
294 fPlotNamesCheck.clear();
295}
296
301 if (fHostmgr->GetRunInfo() != nullptr) {
302 fRun = fHostmgr->GetRunInfo();
303 }
304
305 RESTDebug << "TRestMetadataPlot: Reading canvas settings" << RESTendl;
306 TiXmlElement* formatDefinition = GetElement("labels");
307 if (formatDefinition != nullptr) {
309 cout << formatDefinition << endl;
310 cout << "Reading format definition : " << endl;
311 cout << "---------------------------" << endl;
312 }
313
314 fTicksScaleX = StringToDouble(GetFieldValue("ticksScaleX", formatDefinition));
315 fTicksScaleY = StringToDouble(GetFieldValue("ticksScaleY", formatDefinition));
316
317 fLabelScaleX = StringToDouble(GetFieldValue("labelScaleX", formatDefinition));
318 fLabelScaleY = StringToDouble(GetFieldValue("labelScaleY", formatDefinition));
319
320 fLabelOffsetX = StringToDouble(GetFieldValue("labelOffsetX", formatDefinition));
321 fLabelOffsetY = StringToDouble(GetFieldValue("labelOffsetY", formatDefinition));
322
323 if (fLabelOffsetX == -1) fLabelOffsetX = 1.1;
324 if (fLabelOffsetY == -1) fLabelOffsetY = 1.3;
325
326 if (fTicksScaleX == -1) fTicksScaleX = 1.5;
327 if (fTicksScaleY == -1) fTicksScaleY = 1.5;
328
329 if (fLabelScaleX == -1) fLabelScaleX = 1.3;
330 if (fLabelScaleY == -1) fLabelScaleY = 1.3;
331
333 cout << "ticks scale X : " << fTicksScaleX << endl;
334 cout << "ticks scale Y : " << fTicksScaleY << endl;
335 cout << "label scale X : " << fLabelScaleX << endl;
336 cout << "label scale Y : " << fLabelScaleY << endl;
337 cout << "label offset X : " << fLabelOffsetX << endl;
338 cout << "label offset Y : " << fLabelOffsetY << endl;
339
341 }
342 }
343
344 TiXmlElement* legendDefinition = GetElement("legendPosition");
345 if (legendDefinition != nullptr) {
347 cout << legendDefinition << endl;
348 cout << "Reading legend definition : " << endl;
349 cout << "---------------------------" << endl;
350 }
351
352 fLegendX1 = StringToDouble(GetFieldValue("x1", legendDefinition));
353 fLegendY1 = StringToDouble(GetFieldValue("y1", legendDefinition));
354
355 fLegendX2 = StringToDouble(GetFieldValue("x2", legendDefinition));
356 fLegendY2 = StringToDouble(GetFieldValue("y2", legendDefinition));
357
358 if (fLegendX1 == -1) fLegendX1 = 0.7;
359 if (fLegendY1 == -1) fLegendY1 = 0.75;
360
361 if (fLegendX2 == -1) fLegendX2 = 0.88;
362 if (fLegendY2 == -1) fLegendY2 = 0.88;
363
365 cout << "x1 : " << fLegendX1 << " y1 : " << fLegendY1 << endl;
366 cout << "x2 : " << fLegendX2 << " y2 : " << fLegendY2 << endl;
367
369 }
370
371 fLegendOption = GetFieldValue("option", legendDefinition);
372 if (fLegendOption == "Not defined") fLegendOption = "lp";
373 }
374
375 TiXmlElement* canvasDefinition = GetElement("canvas");
376 if (canvasDefinition != nullptr) {
377 fCanvasSize = StringTo2DVector(GetFieldValue("size", canvasDefinition));
378 fCanvasDivisions = StringTo2DVector(GetFieldValue("divide", canvasDefinition));
379 fCanvasSave = GetFieldValue("save", canvasDefinition);
380 if (fCanvasSave == "Not defined") {
381 fCanvasSave = GetParameter("pdfFilename", REST_TMP_PATH + "restplot.pdf");
382 }
383 }
384
385 RESTDebug << "TRestMetadataPlot: Reading plot sections" << RESTendl;
386 Int_t maxPlots = (Int_t)fCanvasDivisions.X() * (Int_t)fCanvasDivisions.Y();
387 TiXmlElement* plotele = fElement->FirstChildElement("plot");
388 while (plotele != nullptr) {
389 string active = GetParameter("value", plotele, "ON");
390 if (ToUpper(active) == "ON") {
391 int N = fPlots.size();
392 if (N >= maxPlots) {
393 RESTError << "Your canvas divisions (" << fCanvasDivisions.X() << " , "
394 << fCanvasDivisions.Y() << ") are not enough to show " << N + 1 << " plots"
395 << RESTendl;
396 exit(1);
397 }
398
399 Plot_Info_Set plot;
400 plot.name = RemoveWhiteSpaces(GetParameter("name", plotele, "plot_" + ToString(N)));
401 plot.title = GetParameter("title", plotele, "");
402 plot.xVariable = RemoveWhiteSpaces(GetParameter("xVariable", plotele, "timestamp"));
403 plot.logY = StringToBool(GetParameter("logscale", plotele, "false"));
404 plot.logY = plot.logY ? plot.logY : StringToBool(GetParameter("logY", plotele, "false"));
405 plot.logX = StringToBool(GetParameter("logX", plotele, "false"));
406 plot.labelX = GetParameter("xlabel", plotele, "");
407 plot.labelY = GetParameter("ylabel", plotele, "");
408 plot.legendOn = StringToBool(GetParameter("legend", plotele, "OFF"));
409 plot.timeDisplay = StringToBool(GetParameter("timeDisplay", plotele, "OFF"));
410 plot.save = RemoveWhiteSpaces(GetParameter("save", plotele, ""));
411
412 plot.yRange = StringTo2DVector(GetParameter("yRange", plotele, "(-1,-1)"));
413 plot.xRange = StringTo2DVector(GetParameter("xRange", plotele, "(-1,-1)"));
414
415 RESTDebug << " Plot parameters read from <plot section " << RESTendl;
416 RESTDebug << " --------------------------------------- " << RESTendl;
417 RESTDebug << "- name: " << plot.name << RESTendl;
418 RESTDebug << "- title: " << plot.title << RESTendl;
419 RESTDebug << "- xVariable: " << plot.xVariable << RESTendl;
420 RESTDebug << "- logX: " << plot.logX << RESTendl;
421 RESTDebug << "- logY: " << plot.logY << RESTendl;
422 RESTDebug << "- X-label : " << plot.labelX << RESTendl;
423 RESTDebug << "- Y-label : " << plot.labelY << RESTendl;
424 RESTDebug << "- legendOn: " << plot.legendOn << RESTendl;
425 RESTDebug << "- timeDisplay: " << plot.timeDisplay << RESTendl;
426 RESTDebug << "- save : " << plot.save << RESTendl;
427
428 TiXmlElement* graphele = plotele->FirstChildElement("graph");
429 if (graphele == nullptr) {
430 // in case for single-graph plot, variables might be added directly inside the <plot section
431 graphele = plotele;
432 }
433
434 while (graphele != nullptr) {
435 Graph_Info_Set graph = SetupGraphFromConfigFile(graphele, plot);
436
437 RESTDebug << "Graph name : " << graph.name << RESTendl;
438 RESTDebug << "Graph variable : " << graph.yVariable << RESTendl;
439
440 plot.graphs.push_back(graph);
441
442 graphele = graphele->NextSiblingElement("graph");
443 }
444
445 fPlots.push_back(plot);
446 plotele = plotele->NextSiblingElement("plot");
447 }
448 }
449
450 RESTDebug << "TRestMetadataPlot: Reading panel sections" << RESTendl;
451 maxPlots -= fPlots.size(); // remaining spaces on canvas
452 TiXmlElement* panelele = fElement->FirstChildElement("panel");
453 while (panelele != nullptr) {
454 string active = GetParameter("value", panelele, "ON");
455 if (ToUpper(active) == "ON") {
456 int N = fPanels.size();
457 if (N >= maxPlots) {
458 RESTError << "Your canvas divisions (" << fCanvasDivisions.X() << " , "
459 << fCanvasDivisions.Y() << ") are not enough to show " << fPlots.size()
460 << " plots, and " << N + 1 << " info panels" << RESTendl;
461 exit(1);
462 }
463
464 Panel_Info panel;
465 panel.font_size = StringToDouble(GetParameter("font_size", panelele, "0.1"));
466
467 TiXmlElement* labelele = panelele->FirstChildElement("label");
468 while (labelele != nullptr) {
469 panel.label.push_back(GetParameter("value", labelele, "Error. Label value not defined"));
470 panel.posX.push_back(StringToDouble(GetParameter("x", labelele, "0.1")));
471 panel.posY.push_back(StringToDouble(GetParameter("y", labelele, "0.1")));
472
473 labelele = labelele->NextSiblingElement("label");
474 }
475
476 fPanels.push_back(panel);
477 panelele = panelele->NextSiblingElement("panel");
478 }
479 }
480
481 for (unsigned int n = 0; n < fPanels.size(); n++) {
482 RESTExtreme << "Panel " << n << " with font size : " << fPanels[n].font_size << RESTendl;
483 for (unsigned int m = 0; m < fPanels[n].posX.size(); m++) {
484 RESTExtreme << "Label : " << fPanels[n].label[m] << RESTendl;
485 RESTExtreme << "Pos X : " << fPanels[n].posX[m] << RESTendl;
486 RESTExtreme << "Pos Y : " << fPanels[n].posY[m] << RESTendl;
487 }
488 }
489}
490
495 Plot_Info_Set plot) {
496 Graph_Info_Set graph;
497 graph.name = RemoveWhiteSpaces(GetParameter("name", graphele, plot.name));
498 graph.title = GetParameter("title", graphele, plot.title);
499 graph.yVariable = RemoveWhiteSpaces(GetParameter("yVariable", graphele, ""));
500 graph.drawOption = RemoveWhiteSpaces(GetParameter("option", graphele, ""));
501 graph.metadataRule = RemoveWhiteSpaces(GetParameter("metadataRule", graphele, ""));
502
503 for (unsigned int n = 0; n < fPlotNamesCheck.size(); n++)
504 if (graph.name == fPlotNamesCheck[n]) {
505 RESTError
506 << "Repeated plot/graph names were found! Please, use different names for different plots!"
507 << RESTendl;
508 RESTError << "<plot/graph name=\"" << graph.name << "\" already defined!" << RESTendl;
509 exit(1);
510 }
511
512 if (graph.yVariable == "") {
513 RESTError << "Problem reading yVariable from graph with name : " << graph.name << RESTendl;
514 exit(2);
515 }
516
517 fPlotNamesCheck.push_back(graph.name);
518
519 // 5. read draw style(line color, width, marker style, size, etc.)
520 graph.markerStyle = StringToInteger(GetParameter("markerStyle", graphele));
521 graph.markerSize = StringToInteger(GetParameter("markerSize", graphele));
522 graph.markerColor = StringToInteger(GetParameter("markerColor", graphele));
523 graph.lineColor = StringToInteger(GetParameter("lineColor", graphele));
524 graph.lineWidth = StringToInteger(GetParameter("lineWidth", graphele));
525 graph.lineStyle = StringToInteger(GetParameter("lineStyle", graphele));
526
527 return graph;
528}
529
534void TRestMetadataPlot::AddFile(TString fileName) {
535 RESTDebug << "TRestMetadataPlot::AddFile. Adding file. " << RESTendl;
536 RESTDebug << "File name: " << fileName << RESTendl;
537
538 // TODO: How do we check here that the run is valid?
539 fRunInputFileName.push_back((string)fileName);
540 fNFiles++;
541}
542
547 if (fRun != nullptr) {
548 if (fHostmgr->GetProcessRunner() != nullptr && fRun->GetOutputFileName() != "") {
549 // if we have a TRestProcessRunner before head, we use its output file
550 AddFile(fRun->GetOutputFileName());
551 return;
552 } else if (fRun->GetInputFileNames().size() != 0) {
553 // if we have only TRestRun, we ask for its input file list
554 auto names = fRun->GetInputFileNames();
555 for (unsigned int i = 0; i < names.size(); i++) {
556 this->AddFile(names[i]);
557 }
558 return;
559 }
560 }
561}
562
567 string filepattern = GetParameter("inputFileName", "");
568 auto files = TRestTools::GetFilesMatchingPattern(filepattern);
569
570 for (unsigned int n = 0; n < files.size(); n++) {
571 RESTEssential << "Adding file : " << files[n] << RESTendl;
572 AddFile(files[n]);
573 }
574}
575
579Int_t TRestMetadataPlot::GetPlotIndex(TString plotName) {
580 for (unsigned int n = 0; n < fPlots.size(); n++)
581 if (fPlots[n].name == plotName) return n;
582
583 RESTWarning << "TRestMetadataPlot::GetPlotIndex. Plot name " << plotName << " not found" << RESTendl;
584 return -1;
585}
586
592 RESTInfo << "--------------------------" << RESTendl;
593 RESTInfo << "Starting to GenerateCanvas" << RESTendl;
594 RESTInfo << "--------------------------" << RESTendl;
595 // Add files, first use <addFile section definition
596 TiXmlElement* ele = fElement->FirstChildElement("addFile");
597 while (ele != nullptr) {
598 TString inputfile = GetParameter("name", ele);
599 this->AddFile(inputfile);
600 ele = ele->NextSiblingElement("addFile");
601 }
602 // try to add files from external TRestRun handler
604 // try to add files from env "inputFile", which is set by --i argument
605 if (fNFiles == 0) AddFileFromEnv();
606
607 if (fNFiles == 0) {
608 RESTError << "TRestMetadataPlot: No input files are added!" << RESTendl;
609 exit(1);
610 }
611
612 // initialize output root file if we have TRestRun running
613 TFile* fOutputRootFile = nullptr;
614 if (fRun != nullptr) {
615 fOutputRootFile = fRun->GetOutputFile();
616 if (fOutputRootFile == nullptr) {
617 fRun->SetHistoricMetadataSaving(false);
618 fOutputRootFile = fRun->FormOutputFile();
619 }
620 }
621
622 // Initializing canvas window
623 if (fCombinedCanvas != nullptr) {
624 delete fCombinedCanvas;
625 fCombinedCanvas = nullptr;
626 }
627 fCombinedCanvas = new TCanvas("combined", "combined", 0, 0, fCanvasSize.X(), fCanvasSize.Y());
628 fCombinedCanvas->Divide((Int_t)fCanvasDivisions.X(), (Int_t)fCanvasDivisions.Y());
629
630 // Setting up TStyle
631 TStyle* st = new TStyle();
632 st->SetPalette(1);
633
634 if (fPanels.size() > 0) {
635 Double_t startTime = 0;
636 Double_t endTime = 0;
637 Double_t runLength = 0;
638 Int_t totalEntries = 0;
639 for (unsigned int n = 0; n < fRunInputFileName.size(); n++) {
640 TRestRun* run = new TRestRun();
641 run->SetHistoricMetadataSaving(false);
643
644 RESTInfo << "Loading timestamps from file : " << fRunInputFileName[n] << RESTendl;
645
646 Double_t endTimeStamp = run->GetEndTimestamp();
647 Double_t startTimeStamp = run->GetStartTimestamp();
648
649 // We get the lowest/highest run time stamps.
650 if (!startTime || startTime > endTimeStamp) startTime = endTimeStamp;
651 if (!startTime || startTime > startTimeStamp) startTime = startTimeStamp;
652
653 if (!endTime || endTime < startTimeStamp) endTime = startTimeStamp;
654 if (!endTime || endTime < endTimeStamp) endTime = endTimeStamp;
655
656 if (endTimeStamp - startTimeStamp > 0) {
657 runLength += endTimeStamp - startTimeStamp;
658 totalEntries += run->GetEntries();
659 }
660 delete run;
661 }
662
663 Double_t meanRate = totalEntries / runLength;
664
665 runLength /= 3600.;
666
667 TRestRun* panelRun = new TRestRun();
668 panelRun->SetHistoricMetadataSaving(false);
669 panelRun->OpenInputFile(fRunInputFileName[0]);
670 for (unsigned int n = 0; n < fPanels.size(); n++) {
671 fCombinedCanvas->cd(n + 1);
672 for (unsigned int m = 0; m < fPanels[n].posX.size(); m++) {
673 string label = fPanels[n].label[m];
674
675 size_t pos = 0;
676 label = Replace(label, "<<startTime>>", ToDateTimeString(startTime), pos);
677 pos = 0;
678 label = Replace(label, "<<endTime>>", ToDateTimeString(endTime), pos);
679 pos = 0;
680 label = Replace(label, "<<entries>>", Form("%d", totalEntries), pos);
681 pos = 0;
682 label = Replace(label, "<<runLength>>", Form("%5.2lf", runLength), pos);
683 pos = 0;
684 label = Replace(label, "<<meanRate>>", Form("%5.2lf", meanRate), pos);
685
686 label = panelRun->ReplaceMetadataMembers(label);
687
688 TLatex* texxt = new TLatex(fPanels[n].posX[m], fPanels[n].posY[m], label.c_str());
689 texxt->SetTextColor(1);
690 texxt->SetTextSize(fPanels[n].font_size);
691 texxt->Draw("same");
692 }
693 }
694 delete panelRun;
695 }
696
697 // start drawing plots
698 vector<TGraph*> graphCollectionAll;
699 for (unsigned int n = 0; n < fPlots.size(); n++) {
700 Plot_Info_Set plot = fPlots[n];
701
702 TPad* targetPad = (TPad*)fCombinedCanvas->cd(n + 1 + fPanels.size());
703 targetPad->SetLogx(plot.logX);
704 targetPad->SetLogy(plot.logY);
705 targetPad->SetLeftMargin(0.18);
706 targetPad->SetRightMargin(0.1);
707 targetPad->SetBottomMargin(0.15);
708 targetPad->SetTopMargin(0.07);
709
710 // If the first graph does not contain the axis option we must add it manually
711 if (plot.graphs[0].drawOption.find("A") == string::npos)
712 plot.graphs[0].drawOption = plot.graphs[0].drawOption + "A";
713
714 // draw to a new graph
715 vector<TGraph*> graphCollectionPlot;
716 for (unsigned int i = 0; i < plot.graphs.size(); i++) {
717 Graph_Info_Set graph = plot.graphs[i];
718
719 TString graphName = graph.name;
720 TString graphVariable = graph.yVariable;
721
723 cout << endl;
724 cout << "--------------------------------------" << endl;
725 cout << "Graph name : " << graphName << endl;
726 cout << "Graph variable : " << graphVariable << endl;
727 cout << "++++++++++++++++++++++++++++++++++++++" << endl;
728 }
729
730 // Perhaps an RML option?
731 Bool_t skipZeroData = true;
732
733 std::vector<Double_t> xData;
734 std::vector<Double_t> yData;
735 std::map<Double_t, Double_t> dataMap;
736 std::map<Double_t, Int_t> dataMapN;
737
738 // TODO Here we open the file for each graph construction. This might slowdown these
739 // drawing routines when we load thousands of files and we have many graphs. It could be
740 // optimized for the case of many graphs by preloading TGraph data into a dedicated
741 // structure at Graph_Info_Set
742
743 // We build the corresponding TGraph extracting the points from each file
744 for (unsigned int j = 0; j < fRunInputFileName.size(); j++) {
745 RESTInfo << "Loading file : " << fRunInputFileName[j] << RESTendl;
746
747 TRestRun* run = new TRestRun();
748 run->SetHistoricMetadataSaving(false);
750
751 // Checking if the run satisfies the metadata rule defined (if any)
752 // If it doesnt we skip this run
753 if (!run->EvaluateMetadataMember(graph.metadataRule)) {
754 delete run;
755 continue;
756 }
757
758 // We reject runs with unexpected zero y-data
759 Double_t yVal = StringToDouble(run->GetMetadataMember(graph.yVariable));
760 if (yVal == 0 && skipZeroData) {
761 RESTWarning
762 << "Ignoring zero data. This message could be disabled with variable skipZeroData"
763 << RESTendl;
764 delete run;
765 continue;
766 }
767
768 // Populating map/vector data
769 if (plot.xVariable == "timestamp") {
770 Double_t startTimeStamp = run->GetStartTimestamp();
771 Double_t endTimeStamp = run->GetEndTimestamp();
772
773 Double_t meanTime = (endTimeStamp + startTimeStamp) / 2.;
774 xData.push_back(meanTime);
775 yData.push_back(yVal);
776 } else {
777 Double_t xVal = StringToDouble(run->GetMetadataMember(plot.xVariable));
778 if (dataMap.find(xVal) == dataMap.end()) {
779 dataMap[xVal] = yVal;
780 dataMapN[xVal] = 1;
781 } else {
782 dataMap[xVal] += yVal;
783 dataMapN[xVal]++;
784 }
785 }
786 delete run;
787 }
788
789 // dataMap will contain data only in case is not "timestamp"
790 for (auto const& x : dataMap) {
791 xData.push_back(x.first);
792 yData.push_back(dataMap[x.first] / dataMapN[x.first]);
793 }
794
795 // In case of problems we output this
796 if (xData.size() == 0) {
797 RESTWarning << "TRestMetadataPlot: no input file matches condition for graph: " << graph.name
798 << RESTendl;
799 RESTWarning << "This graph is empty and it will not be plotted" << RESTendl;
800 plot.graphs.erase(plot.graphs.begin() + i);
801 i--;
802 }
803
804 if (xData.size() == 1) {
805 RESTWarning << "TRestMetadataPlot: Only 1-point for graph: " << graph.name << RESTendl;
806 RESTWarning << "X: " << xData[0] << " Y: " << yData[0] << RESTendl;
807 }
808
809 for (unsigned int nn = 0; nn < xData.size(); nn++)
810 RESTDebug << "X: " << xData[nn] << " Y: " << yData[nn] << RESTendl;
811
812 // adjust the graph
813 TGraph* gr_temp = new TGraph(xData.size(), &xData[0], &yData[0]);
814 gr_temp->SetName(graph.name.c_str());
815 gr_temp->SetTitle(plot.title.c_str());
816
817 gr_temp->GetXaxis()->SetTitle(plot.labelX.c_str());
818 gr_temp->GetYaxis()->SetTitle(plot.labelY.c_str());
819 // Removed to avoid Gitlab SJTU pipeline failing.
820 // Probably due to ROOT version?
821 // gr_temp->GetXaxis()->SetMaxDigits(4);
822
823 gr_temp->GetXaxis()->SetLabelSize(fTicksScaleX * gr_temp->GetXaxis()->GetLabelSize());
824 gr_temp->GetYaxis()->SetLabelSize(fTicksScaleY * gr_temp->GetYaxis()->GetLabelSize());
825 gr_temp->GetXaxis()->SetTitleSize(fLabelScaleX * gr_temp->GetXaxis()->GetTitleSize());
826 gr_temp->GetYaxis()->SetTitleSize(fLabelScaleY * gr_temp->GetYaxis()->GetTitleSize());
827 gr_temp->GetXaxis()->SetTitleOffset(fLabelOffsetX * gr_temp->GetXaxis()->GetTitleOffset());
828 gr_temp->GetYaxis()->SetTitleOffset(fLabelOffsetY * gr_temp->GetYaxis()->GetTitleOffset());
829 // gr_temp->GetXaxis()->SetNdivisions(-5);
830
831 gr_temp->SetLineColor(graph.lineColor);
832 gr_temp->SetLineWidth(graph.lineWidth);
833 gr_temp->SetLineStyle(graph.lineStyle);
834 gr_temp->SetFillColor(graph.fillColor);
835 gr_temp->SetFillStyle(graph.fillStyle);
836
837 gr_temp->SetDrawOption(graph.drawOption.c_str());
838 gr_temp->SetMarkerStyle(graph.markerStyle);
839 gr_temp->SetMarkerSize(graph.markerSize);
840 gr_temp->SetMarkerColor(graph.markerColor);
841
842 if (plot.timeDisplay) gr_temp->GetXaxis()->SetTimeDisplay(1);
843
844 graphCollectionPlot.push_back(gr_temp);
845 graphCollectionAll.push_back(gr_temp);
846 }
847
848 if (graphCollectionPlot.size() == 0) {
849 RESTWarning << "TRestMetadataPlot: pad empty for the plot: " << plot.name << RESTendl;
850 continue;
851 }
852
853 // draw to the pad
854 Double_t minValue_Pad = 0;
855 Double_t maxValue_Pad = 0;
856 for (unsigned int i = 0; i < graphCollectionPlot.size(); i++) {
857 TGraph* gr = graphCollectionPlot[i];
858 // need to draw the max graph first, in order to prevent data hidden problem
859 Double_t maxValue = TMath::MaxElement(gr->GetN(), gr->GetY());
860 Double_t minValue = TMath::MinElement(gr->GetN(), gr->GetY());
861 if (i == 0) {
862 maxValue_Pad = maxValue;
863 minValue_Pad = minValue;
864 } else {
865 if (maxValue > maxValue_Pad) maxValue_Pad = maxValue;
866 if (minValue < minValue_Pad) minValue_Pad = minValue;
867 }
868 }
869
870 // We add some margin to the automatically identified ranges
871 if (minValue_Pad > 0)
872 minValue_Pad *= 0.8;
873 else
874 minValue_Pad *= 1.2;
875
876 if (maxValue_Pad > 0)
877 maxValue_Pad *= 1.2;
878 else
879 maxValue_Pad *= 0.8;
880
881 // If ranges have beend defined we override the automatic ranges
882 if (!(plot.yRange.X() == -1 && plot.yRange.Y() == -1)) {
883 minValue_Pad = plot.yRange.X();
884 maxValue_Pad = plot.yRange.Y();
885 }
886
887 for (unsigned int i = 0; i < graphCollectionPlot.size(); i++) {
888 // draw the remaining histo
889 if (!(plot.xRange.X() == -1 && plot.xRange.Y() == -1))
890 graphCollectionPlot[i]->GetXaxis()->SetLimits(plot.xRange.X(), plot.xRange.Y());
891 graphCollectionPlot[i]->GetHistogram()->SetMinimum(minValue_Pad);
892 graphCollectionPlot[i]->GetHistogram()->SetMaximum(maxValue_Pad);
893
894 graphCollectionPlot[i]->Draw(plot.graphs[i].drawOption.c_str());
895 }
896
897 // save histogram to root file
898 for (unsigned int i = 0; i < graphCollectionPlot.size(); i++) {
899 if (fRun != nullptr) {
900 fOutputRootFile->cd();
901 graphCollectionPlot[i]->Write();
902 }
903 }
904
905 // draw legend
906 if (plot.legendOn) {
907 TLegend* legend = new TLegend(fLegendX1, fLegendY1, fLegendX2, fLegendY2);
908 for (unsigned int i = 0; i < graphCollectionPlot.size(); i++)
909 legend->AddEntry(graphCollectionPlot[i], (TString)plot.graphs[i].title, fLegendOption);
910 legend->Draw("same");
911 }
912
913 // save pad
914 targetPad->Update();
915 if (plot.save != "") {
916 SavePlotToPDF(plot.save, n + 1);
917 }
918
919 fCombinedCanvas->Update();
920 }
921
922 // Preview plot. User can make some changes before saving
923 if (StringToBool(GetParameter("previewPlot", "TRUE"))) {
924 GetChar();
925 }
926
927 // Save canvas to a PDF file
928 TRestRun* run = new TRestRun();
929 run->SetHistoricMetadataSaving(false);
931
933 delete run;
934 if (fCanvasSave != "") fCombinedCanvas->Print(fCanvasSave);
935
936 // If the extension of the canvas save file is ROOT we store also the histograms
937 if (TRestTools::isRootFile((string)fCanvasSave)) {
938 TFile* f = new TFile(fCanvasSave, "UPDATE");
939 f->cd();
940 for (unsigned int n = 0; n < graphCollectionAll.size(); n++) graphCollectionAll[n]->Write();
941 f->Close();
942 }
943
944 // Save this class to the root file
945 if (fRun != nullptr && fOutputRootFile != nullptr) {
946 fOutputRootFile->cd();
947 this->Write();
948 fRun->CloseFile();
949 }
950}
951
956void TRestMetadataPlot::SaveCanvasToPDF(TString fileName) { fCombinedCanvas->Print(fileName); }
957
962void TRestMetadataPlot::SavePlotToPDF(TString fileName, Int_t n) {
963 // gErrorIgnoreLevel = 10;
964 fCombinedCanvas->SetBatch(kTRUE);
965
966 if (n == 0) {
967 fCombinedCanvas->Print(fileName);
968 fCombinedCanvas->SetBatch(kFALSE);
969 return;
970 }
971
972 TPad* pad = (TPad*)fCombinedCanvas->GetPad(n);
973
974 TCanvas* c = new TCanvas(fPlots[n - 1].name.c_str(), fPlots[n - 1].name.c_str(), 800, 600);
975 pad->DrawClone();
976
977 c->Print(fileName);
978
979 delete c;
980
981 fCombinedCanvas->SetBatch(kFALSE);
982
983 return;
984}
985
991void TRestMetadataPlot::SaveGraphToPDF(TString fileName, Int_t nPlot, Int_t nGraph) {
992 string name = fPlots[nPlot].graphs[nGraph].name;
993 TGraph* graph = (TGraph*)gPad->GetPrimitive(name.c_str());
994
995 TCanvas* c = new TCanvas(name.c_str(), name.c_str(), 800, 600);
996
997 graph->Draw();
998
999 c->Print(fileName);
1000
1001 delete c;
1002 return;
1003}
A helper class to draw the evolution or correlation of metadata information from a set of REST files.
Double_t fLabelOffsetX
A label offset to be applied in the x-label (not tested)
Double_t fTicksScaleY
A label ticks scale to be applied in the y-label (not tested)
TCanvas * fCombinedCanvas
Output canvas.
TString fCanvasSave
A std::string to define the output filename where to store the canvas.
std::vector< Plot_Info_Set > fPlots
A std::vector with the defined plots.
Double_t fLabelScaleX
A label title scale to be applied in the x-label (not tested)
void SaveCanvasToPDF(TString fileName)
A method to execute the generation of an output file with the contents of the TCanvas as it is....
void InitFromConfigFile() override
Initialization of TRestMetadataPlot members through a RML file.
void SaveGraphToPDF(TString fileName, Int_t nPlot=0, Int_t nGraph=0)
A method to execute the generation of a particular graph from a plot inside the canvas using the inde...
TString fLegendOption
The legend drawing option.
void AddFileFromEnv()
We can add input file from parameter "inputFile".
std::vector< Panel_Info > fPanels
A std::vector with the defined panels.
TRestRun * fRun
TRestRun to handle output file.
Double_t fLegendY1
The Y1 legend position.
void SavePlotToPDF(TString fileName, Int_t n=0)
A method to execute the generation of a plot inside the canvas using the index of the plot....
Int_t fNFiles
The total number of files for plotting added to this class.
void AddFile(TString fileName)
It creates a new TRestRun object extracted from the fileName, and it adds it to the list of input fil...
Graph_Info_Set SetupGraphFromConfigFile(TiXmlElement *ele, Plot_Info_Set info)
It fills the components of a Graph_Info_set object using the definition inside a <graph element.
void AddFileFromExternalRun()
We can add input file from process's output file.
void Initialize() override
Initialization of TRestMetadataPlot data members.
Double_t fLegendY2
The Y2 legend position.
Double_t fLegendX1
The X1 legend position.
void GenerateCanvas()
The main method of this class, collecting the input files, producing the TGraphs and generating the p...
std::vector< std::string > fPlotNamesCheck
A std::vector to double check that there are no repeated graph names.
TRestMetadataPlot()
Default constructor.
Double_t fLabelScaleY
A label title scale to be applied in the y-label (not tested)
Double_t fTicksScaleX
A label ticks scale to be applied in the x-label (not tested)
TVector2 fCanvasSize
The size of the canvas window in pixels.
std::vector< std::string > fRunInputFileName
To keep a list of files used.
Double_t fLabelOffsetY
A label offset to be applied in the y-label (not tested)
TVector2 fCanvasDivisions
The number of canvas divisions on X and Y.
Double_t fLegendX2
The X2 legend position.
virtual ~TRestMetadataPlot()
Default destructor.
Int_t GetPlotIndex(TString plotName)
It returns the index of the array correspoding to the plot with the given plotName.
A base class for any REST metadata class.
Definition: TRestMetadata.h:74
endl_t RESTendl
Termination flag object for TRestStringOutput.
TiXmlElement * GetElement(std::string eleDeclare, TiXmlElement *e=nullptr)
Get an xml element from a given parent element, according to its declaration.
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
std::string GetFieldValue(std::string parName, TiXmlElement *e)
Returns the field value of an xml element which has the specified name.
void SetSectionName(std::string sName)
set the section name, clear the section content
TRestManager * fHostmgr
All metadata classes can be initialized and managed by TRestManager.
std::string fConfigFileName
Full name of the rml file.
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
overwriting the write() method with fStore considered
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
TiXmlElement * fElement
Saving the sectional element together with global element.
Data provider and manager in REST.
Definition: TRestRun.h:18
void OpenInputFile(int i)
Open the i th file in the file list.
Definition: TRestRun.cxx:314
void CloseFile()
Close both input file and output file, setting trees to nullptr also.
Definition: TRestRun.cxx:1155
TFile * FormOutputFile()
Create a new TFile as REST output file. Writing metadata objects into it.
Definition: TRestRun.cxx:1036
TString FormFormat(const TString &filenameFormat)
Form output file name according to file info list, proc info list and run data.
Definition: TRestRun.cxx:940
std::string ReplaceMetadataMembers(const std::string &instr, Int_t precision=8)
It will replace the data members contained inside the string given as input. The data members in the ...
Definition: TRestRun.cxx:1652
Bool_t EvaluateMetadataMember(const std::string &instr)
It will evaluate the expression given including the data member from the corresponding metadata class...
Definition: TRestRun.cxx:1768
@ REST_Debug
+show the defined debug messages
static std::vector< std::string > GetFilesMatchingPattern(std::string pattern, bool unlimited=false)
Returns a list of files whose name match the pattern string. Key word is "*". e.g....
Definition: TRestTools.cxx:976
static bool isRootFile(const std::string &filename)
Returns true if the filename has *.root* extension.
Definition: TRestTools.cxx:733
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Double_t StringToDouble(std::string in)
Gets a double from a string.
std::string ToUpper(std::string in)
Convert string to its upper case. Alternative of TString::ToUpper.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
TVector2 StringTo2DVector(std::string in)
Gets a 2D-vector from a string.
std::string RemoveWhiteSpaces(std::string in)
Returns the input string removing all white spaces.
std::string ToDateTimeString(time_t time)
Format time_t into string.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace any occurences of thisSring by byThisString inside string in.
This structure is used to register the values from a <graph definition inside the RML.
Int_t lineStyle
The line style to be assigned to the corresponding TGraph.
Int_t markerSize
The marker size to be assigned to the corresponding TGraph.
Int_t markerColor
The marker color to be assigned to the corresponding TGraph.
Int_t lineWidth
The line width to be assigned to the corresponding TGraph.
Int_t markerStyle
The marker style to be assigned to the corresponding TGraph.
std::string name
The name to be used for the corresponding ROOT TGraph object.
Int_t fillColor
The fill color to be assigned to the corresponding TGraph.
std::string drawOption
The option to be passed to the Draw method.
Int_t lineColor
The line color to be assigned to the corresponding TGraph.
std::string title
The title to be used inside TLegend object.
Int_t fillStyle
The fill style to be assigned to the corresponding TGraph.
std::string yVariable
The metadata class and data member definition to be plotted.
std::string metadataRule
An optional rule to be used for run selection.
This structure is used to register the values from a <panel definition inside the RML.
Float_t font_size
The font size to be used in the panel labels.
std::vector< std::string > label
The std::string containing the text to be drawn in the panel.
std::vector< Float_t > posY
The y-position of labels used inside the panel.
std::vector< Float_t > posX
The x-position of labels used inside the panel.
This structure is used to register the values from a <plot definition inside the RML.
std::string xVariable
The corresponding metadata variable to be used in the X-axis.
std::string name
The name that will be used for the TGraph object.
std::string labelY
The label or title to be given to the y-axis.
std::string labelX
The label or title to be given to the x-axis.
TVector2 xRange
The user defined range in the x-axis.
std::string title
A title that will be visible in top of the plot.
Bool_t timeDisplay
It true a time/date calendar format will be used on the x-axis.
Bool_t legendOn
It true a legend will be shown on the corresponding plot.
std::vector< Graph_Info_Set > graphs
A std::vector containing the properties of the graphs inside the plot.
std::string save
The filename where the file will be saved.
Bool_t logX
It true a logarithmic scale will be used on the x-axis.
Bool_t logY
It true a logarithmic scale will be used on the y-axis.
TVector2 yRange
The user defined range in the y-axis.