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 
239 using namespace std;
240 
241 #include <TGraph.h>
242 #include <TLegend.h>
243 #include <TStyle.h>
244 
245 #include <ctime>
246 
247 ClassImp(TRestMetadataPlot);
248 
253 
268 TRestMetadataPlot::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 
534 void 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 
579 Int_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
603  if (fNFiles == 0) AddFileFromExternalRun();
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 
956 void TRestMetadataPlot::SaveCanvasToPDF(TString fileName) { fCombinedCanvas->Print(fileName); }
957 
962 void 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 
991 void 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.