ATLAS Offline Software
Loading...
Searching...
No Matches
MuonValR4::RootVisualizationService Class Reference

Implementation of the IRootVisualization service. More...

#include <RootVisualizationService.h>

Inheritance diagram for MuonValR4::RootVisualizationService:
Collaboration diagram for MuonValR4::RootVisualizationService:

Classes

struct  PlotsPerClient
 Helper struct to group all plots that are belonging to a client of the service. More...

Public Types

using PlotPtr_t = std::shared_ptr<detail::DrawCanvasObject>
using PlotVec_t = std::vector<PlotPtr_t>

Public Member Functions

virtual StatusCode registerClient (const ClientToken &token) override final
virtual std::shared_ptr< ICanvasObjectprepareCanvas (const EventContext &ctx, const ClientToken &token, const std::string &canvasName) override final
virtual StatusCode finalize () override final
virtual StatusCode initialize () override final

Private Types

using StorageMap_t = std::map<ClientToken, PlotsPerClient>

Private Member Functions

void paintObjects (const ClientToken &token, PlotVec_t &&toDraw)

Private Attributes

Gaudi::Property< double > m_canvasExtraScale {this, "CanvasExtraScale" , 1.5}
 Extra safety margin to zoom out from the Canvas.
Gaudi::Property< bool > m_quadCanvas {this, "QuadraticCanas", true}
 Ensure that the canvas has the same interval sizes in x & y.
Gaudi::Property< unsigned > m_canvasWidth {this, "CanvasWidth", 800}
 Width of all drawn Canvases.
Gaudi::Property< unsigned > m_canvasHeight {this, "CanvasHeight", 600}
 Height of all drawn Canvases.
Gaudi::Property< std::string > m_outDir {this, "outputDir" , "./Displays/"}
 Directory into which all plots are written to.
Gaudi::Property< std::string > m_outRootFileName {this, "outputROOTFile", "AllDisplays.root"}
 Name of the ROOT file into which the output Canvases are written (needs root to be in the list of outputFormats of the client tokens)
StorageMap_t m_storage {}
std::unique_ptr< TFile > m_outFile {}
 File into which all Canvases are saved if root is defined as extension.
std::mutex m_storageMutex {}
std::mutex m_canvasMutex {}

Detailed Description

Implementation of the IRootVisualization service.

Definition at line 18 of file RootVisualizationService.h.

Member Typedef Documentation

◆ PlotPtr_t

◆ PlotVec_t

◆ StorageMap_t

using MuonValR4::RootVisualizationService::StorageMap_t = std::map<ClientToken, PlotsPerClient>
private

Definition at line 62 of file RootVisualizationService.h.

Member Function Documentation

◆ finalize()

StatusCode MuonValR4::RootVisualizationService::finalize ( )
finaloverridevirtual

Definition at line 191 of file RootVisualizationService.cxx.

191 {
192 ATH_MSG_DEBUG("Finalize the visualization service. Dump all canvases that not have yet been drawn");
193 for (auto& [token, dataHolder] : m_storage) {
194 if (!dataHolder.elementsDrawn) {
195 paintObjects(token, std::move(dataHolder.toDraw));
196 }
197 dataHolder.toDraw.clear();
198 }
199 m_outFile.reset();
200 return StatusCode::SUCCESS;
201 }
#define ATH_MSG_DEBUG(x)
std::unique_ptr< TFile > m_outFile
File into which all Canvases are saved if root is defined as extension.
void paintObjects(const ClientToken &token, PlotVec_t &&toDraw)

◆ initialize()

StatusCode MuonValR4::RootVisualizationService::initialize ( )
finaloverridevirtual

Definition at line 34 of file RootVisualizationService.cxx.

34 {
35 gROOT->SetStyle("ATLAS");
36 TStyle* plotStyle = gROOT->GetStyle("ATLAS");
37 plotStyle->SetOptTitle(0);
38 plotStyle->SetHistLineWidth(1.);
39 plotStyle->SetPalette(kViridis);
40
41 return StatusCode::SUCCESS;
42 }

◆ paintObjects()

void MuonValR4::RootVisualizationService::paintObjects ( const ClientToken & token,
PlotVec_t && toDraw )
private

First sort the plots by the event number

The client still holds the pointer to the plot

Number the plots per event

Setup the frame

Draw the primitives

Save the single plots

Definition at line 91 of file RootVisualizationService.cxx.

92 {
93 if (toDraw.empty()){
94 return;
95 }
97 std::ranges::stable_sort(toDraw, [](const PlotPtr_t& a, const PlotPtr_t& b){
98 return a->event() < b->event();
99 });
100 std::unique_lock guard{m_canvasMutex};
101 std::unique_ptr<TCanvas> summaryCan{};
102 const std::string summaryPdfName = std::format("{:}/All{}.pdf",
103 m_outDir.value(), token.preFixName);
104 if (token.saveSummaryPlot) {
105 ATH_MSG_DEBUG("Open "<<summaryPdfName<<" to dump all canvases in a common file");
106 ensureDirectory(summaryPdfName);
107 summaryCan = std::make_unique<TCanvas>("allCan","allCan", m_canvasWidth, m_canvasHeight);
108 summaryCan->SaveAs(std::format("{:}[", summaryPdfName).c_str());
109 }
110 if (token.fileFormats.count("root") && !m_outFile) {
111 std::string outFile = std::format("{:}/{:}", m_outDir.value(),
112 m_outRootFileName.value());
114 m_outFile.reset(TFile::Open(outFile.c_str(), "RECREATE"));
115 if (!m_outFile || m_outFile->IsZombie()) {
116 THROW_EXCEPTION("Failed to create "<<outFile<<".");
117 }
118 ATH_MSG_DEBUG("Open "<<outFile<<" to save the plots in root format");
119 }
120 std::size_t currEvt{toDraw.back()->event()}, plotCount{0};
121 for (const PlotPtr_t& drawMe : toDraw) {
123 while (!drawMe.unique()) {
124 using namespace std::chrono_literals;
125 ATH_MSG_DEBUG("Wait until "<<drawMe->name()<<" is finished.");
126 std::this_thread::sleep_for(10ms);
127 }
129 if (currEvt != drawMe->event()) {
130 currEvt = drawMe->event();
131 plotCount = 0;
132 }
133 std::string plotName = std::format("{:}/{:}/{:}_{:}_{:}_{:}", m_outDir.value(),
134 token.subDirectory, token.preFixName,
135 drawMe->event(), ++plotCount,
136 removeNonAlphaNum(drawMe->name()));
137
138 auto singleCan = std::make_unique<TCanvas>("can", "can" , m_canvasWidth, m_canvasHeight);
139 singleCan->cd();
141 using enum ICanvasObject::AxisRanges;
142 ATH_MSG_VERBOSE("Crate new canvas: "<<plotName<<" ["<<drawMe->corner(xLow)<<";"<<drawMe->corner(xHigh)
143 <<"], ["<<drawMe->corner(yLow)<<";"<<drawMe->corner(yHigh)<<"].");
144 auto frameH = std::make_unique<TH2F>("frameH",
145 std::format("frame;{:};{:};{:}", drawMe->xTitle(), drawMe->yTitle(), drawMe->zTitle()).c_str(),
146 1, drawMe->corner(xLow), drawMe->corner(xHigh),
147 1, drawMe->corner(yLow), drawMe->corner(yHigh));
148 frameH->Draw("AXIS");
149
150 if (token.drawAtlas) {
151 drawMe->add(drawAtlasLabel(token.atlasLabelPos[0], token.atlasLabelPos[1], token.atlasLabel));
152 }
153 if (token.drawSqrtS) {
154 drawMe->add(drawLumiSqrtS(token.atlasLabelPos[0], token.atlasLabelPos[1] - 0.05,
155 token.sqrtSLabel, token.lumiLabel));
156 }
158 for (auto& [primitive, opt] : drawMe->primitives()) {
159 primitive->Draw(opt.c_str());
160 }
162 if (token.saveSinglePlots) {
163 for (const std::string& fileExt : token.fileFormats) {
164 if (fileExt != "root") {
165 ensureDirectory(plotName);
166 singleCan->SaveAs(std::format("{:}.{:}", plotName, fileExt).c_str());
167 }
168 }
169 }
170 if (token.fileFormats.count("root")) {
171 TDirectory* writeTo = m_outFile.get();
172 if (!token.subDirectory.empty()) {
173 writeTo = m_outFile->GetDirectory(token.subDirectory.c_str());
174 if (!writeTo) {
175 writeTo = m_outFile->mkdir(token.subDirectory.c_str());
176 }
177 }
178 writeTo->WriteObject(singleCan.get(),
179 std::format("{:}_{:}_{:}_{:}",token.preFixName,
180 drawMe->event(), plotCount,
181 removeNonAlphaNum(drawMe->name())).c_str());
182 }
183 if (summaryCan) {
184 singleCan->SaveAs(summaryPdfName.c_str());
185 }
186 }
187 if (summaryCan) {
188 summaryCan->SaveAs(std::format("{:}]", summaryPdfName).c_str());
189 }
190 }
#define ATH_MSG_VERBOSE(x)
static Double_t a
Gaudi::Property< std::string > m_outDir
Directory into which all plots are written to.
Gaudi::Property< std::string > m_outRootFileName
Name of the ROOT file into which the output Canvases are written (needs root to be in the list of out...
Gaudi::Property< unsigned > m_canvasHeight
Height of all drawn Canvases.
Gaudi::Property< unsigned > m_canvasWidth
Width of all drawn Canvases.
std::shared_ptr< detail::DrawCanvasObject > PlotPtr_t
outFile
Comment Out Those You do not wish to run.
void ensureDirectory(const std::string &path)
Ensures that the subdirectory in the path is created.
std::string removeNonAlphaNum(std::string str)
Removes all non-alpha numerical characters from a string.
std::unique_ptr< TLatex > drawLumiSqrtS(const double xPos, const double yPos, const std::string_view sqrtS="14", const std::string_view lumi="")
Create a luminosity sqrtS label.
std::unique_ptr< TLatex > drawAtlasLabel(const double xPos, const double yPos, const std::string &status="Internal")
Create a ATLAS label.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10

◆ prepareCanvas()

std::shared_ptr< ICanvasObject > MuonValR4::RootVisualizationService::prepareCanvas ( const EventContext & ctx,
const ClientToken & token,
const std::string & canvasName )
finaloverridevirtual

Definition at line 63 of file RootVisualizationService.cxx.

64 {
65 if (canvasName.empty()) {
66 THROW_EXCEPTION("The canvas name must not be empty");
67 }
68 std::unique_lock lock_guard{m_storageMutex};
69 StorageMap_t::iterator store_itr = m_storage.find(token);
70 if (store_itr == m_storage.end()) {
71 THROW_EXCEPTION("The token "<<token.preFixName<<" is unknown.");
72 }
73 PlotsPerClient& dataHolder = store_itr->second;
74 if (!dataHolder.elementsDrawn &&
75 cleanTrashed(dataHolder.toDraw) < store_itr->first.canvasLimit) {
76 const std::size_t evt = ctx.eventID().event_number();
77 ATH_MSG_VERBOSE("Provide new canvas "<<canvasName<<" for stream "<<token.preFixName
78 <<" in "<<ctx.eventID());
79 auto newCanvas = dataHolder.toDraw.emplace_back(std::make_shared<detail::DrawCanvasObject>(canvasName, evt));
81 return newCanvas;
82 } else if (!dataHolder.elementsDrawn) {
83 dataHolder.elementsDrawn = true;
84 lock_guard.unlock();
85 paintObjects(store_itr->first, std::move(dataHolder.toDraw));
86 }
87 ATH_MSG_VERBOSE("Maximum elements for "<<token.preFixName
88 <<" reached. Don't provide any new canvas");
89 return nullptr;
90 }
Gaudi::Property< bool > m_quadCanvas
Ensure that the canvas has the same interval sizes in x & y.
Gaudi::Property< double > m_canvasExtraScale
Extra safety margin to zoom out from the Canvas.
Helper struct to group all plots that are belonging to a client of the service.

◆ registerClient()

StatusCode MuonValR4::RootVisualizationService::registerClient ( const ClientToken & token)
finaloverridevirtual

Definition at line 43 of file RootVisualizationService.cxx.

43 {
44 if (token.preFixName.empty()){
45 ATH_MSG_FATAL("Prefix name must not be empty");
46 return StatusCode::FAILURE;
47 }
48 std::unique_lock guard{m_storageMutex};
49 auto insert_itr = m_storage.insert(std::make_pair(token, PlotsPerClient{}));
50 if (!insert_itr.second) {
51 ATH_MSG_FATAL("The token "<<token.preFixName<<" is already registered");
52 return StatusCode::FAILURE;
53 }
54 ATH_MSG_INFO("Registered new client "<<token.preFixName
55 <<", maximum number of plots "<<token.canvasLimit
56 <<", formats: "<<token.fileFormats<<", save single: "
57 <<(token.saveSinglePlots ? "yay" : "nay")
58 <<", save summary: "<<(token.saveSummaryPlot ? "yay" : "nay"));
59 return StatusCode::SUCCESS;
60 }
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)

Member Data Documentation

◆ m_canvasExtraScale

Gaudi::Property<double> MuonValR4::RootVisualizationService::m_canvasExtraScale {this, "CanvasExtraScale" , 1.5}
private

Extra safety margin to zoom out from the Canvas.

Definition at line 39 of file RootVisualizationService.h.

39{this, "CanvasExtraScale" , 1.5};

◆ m_canvasHeight

Gaudi::Property<unsigned> MuonValR4::RootVisualizationService::m_canvasHeight {this, "CanvasHeight", 600}
private

Height of all drawn Canvases.

Definition at line 45 of file RootVisualizationService.h.

45{this, "CanvasHeight", 600};

◆ m_canvasMutex

std::mutex MuonValR4::RootVisualizationService::m_canvasMutex {}
private

Definition at line 68 of file RootVisualizationService.h.

68{};

◆ m_canvasWidth

Gaudi::Property<unsigned> MuonValR4::RootVisualizationService::m_canvasWidth {this, "CanvasWidth", 800}
private

Width of all drawn Canvases.

Definition at line 43 of file RootVisualizationService.h.

43{this, "CanvasWidth", 800};

◆ m_outDir

Gaudi::Property<std::string> MuonValR4::RootVisualizationService::m_outDir {this, "outputDir" , "./Displays/"}
private

Directory into which all plots are written to.

Definition at line 47 of file RootVisualizationService.h.

47{this, "outputDir" , "./Displays/"};

◆ m_outFile

std::unique_ptr<TFile> MuonValR4::RootVisualizationService::m_outFile {}
private

File into which all Canvases are saved if root is defined as extension.

Definition at line 65 of file RootVisualizationService.h.

65{};

◆ m_outRootFileName

Gaudi::Property<std::string> MuonValR4::RootVisualizationService::m_outRootFileName {this, "outputROOTFile", "AllDisplays.root"}
private

Name of the ROOT file into which the output Canvases are written (needs root to be in the list of outputFormats of the client tokens)

Definition at line 50 of file RootVisualizationService.h.

50{this, "outputROOTFile", "AllDisplays.root"};

◆ m_quadCanvas

Gaudi::Property<bool> MuonValR4::RootVisualizationService::m_quadCanvas {this, "QuadraticCanas", true}
private

Ensure that the canvas has the same interval sizes in x & y.

Definition at line 41 of file RootVisualizationService.h.

41{this, "QuadraticCanas", true};

◆ m_storage

StorageMap_t MuonValR4::RootVisualizationService::m_storage {}
private

Definition at line 63 of file RootVisualizationService.h.

63{};

◆ m_storageMutex

std::mutex MuonValR4::RootVisualizationService::m_storageMutex {}
private

Definition at line 67 of file RootVisualizationService.h.

67{};

The documentation for this class was generated from the following files: