CbmRoot
Loading...
Searching...
No Matches
CbmLitRadLengthQa.cxx
Go to the documentation of this file.
1/* Copyright (C) 2013-2020 GSI/JINR-LIT, Darmstadt/Dubna
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Andrey Lebedev [committer] */
4
11#include "CbmLitRadLengthQa.h"
12
13#include "CbmDrawHist.h"
14#include "CbmHistManager.h"
16#include "CbmTrdAddress.h"
17#include "CbmUtils.h"
18#include "FairRadLenPoint.h"
19#include "FairRootManager.h"
20#include "TCanvas.h"
21#include "TClonesArray.h"
22#include "TGeoManager.h"
23#include "TH1.h"
24#include "TProfile2D.h"
25#include "TRegexp.h"
26#include "boost/assign/list_of.hpp"
28
29#include <TFile.h>
30
31#include <boost/algorithm/string.hpp>
32
33#include <cstdlib>
34#include <map>
35#include <string>
36
37using boost::assign::list_of;
38using Cbm::ToString;
39using std::atoi;
40using std::map;
41using std::pair;
42using std::string;
43
44const Double_t CbmLitRadLengthQa::SILICON_RAD_LENGTH = 9.365; // cm
45
46CbmLitRadLengthQa::CbmLitRadLengthQa() : fHM(NULL), fOutputDir(""), fRadLen(NULL), fDet() {}
47
52
54{
55 fHM = new CbmHistManager();
59 return kSUCCESS;
60}
61
63{
64 static Int_t eventNo = 0;
65 eventNo++;
66 if (0 == eventNo % 10000) {
67 std::cout << "-I- CbmLitRadLengthQa::Exec: eventNo=" << eventNo << std::endl;
68 }
69
70 ExecDetector(".+", "Total");
71 //ExecDetector("/cave_1/pipevac1_0/mvdstation.+", "Mvd");
72 ExecDetector("/cave_1/sts.+", "Sts");
73 ExecDetector("/cave_1/rich.+", "Rich");
74 //ExecDetector("/cave_1/trd.+", "Trd");
75 //ExecDetector("/cave_1/much.+", "Much");
76 //ExecDetector("/cave_1/tof.+", "Tof");
77 //ExecDetector("Mvd", CbmLitRadLengthQa::GetMvdStationId);
78 //ExecDetector("Sts", CbmLitRadLengthQa::GetStsStationId);
79 //ExecDetector("Trd", CbmLitRadLengthQa::GetTrdStationId);
80 //ExecDetector("Much", CbmLitRadLengthQa::GetMuchStationId);
81 //ExecDetector("MuchAbsorber", CbmLitRadLengthQa::GetMuchAbsorberId);
82}
83
85{
86 fHM->ShrinkEmptyBinsH2ByPattern("hrl_.+_P2");
87 TDirectory* oldir = gDirectory;
88 TFile* outFile = FairRootManager::Instance()->GetOutFile();
89 if (outFile != NULL) {
90 outFile->cd();
92 }
93 gDirectory->cd(oldir->GetPath());
94
96 report->Create(fHM, fOutputDir);
97 delete report;
98 Draw();
100}
101
103{
104 FairRootManager* ioman = FairRootManager::Instance();
105 assert(ioman != NULL);
106 fRadLen = (TClonesArray*) ioman->GetObject("RadLen");
107}
108
110{
111 const Int_t nofBins = 500;
112 const Int_t nofBinsX = 500;
113 const Int_t nofBinsY = 500;
114 const Int_t nofBinsSiliconThicknessX = 500;
115 const Int_t nofBinsSiliconThicknessY = 500;
116 const Double_t minX = -250.1;
117 const Double_t maxX = 249.9;
118 const Double_t minY = -250.1;
119 const Double_t maxY = 249.9;
120 vector<string> detNames = list_of("Total")("Mvd")("Sts")("Rich")("Trd")("Much")("Tof");
121 Int_t nofDetNames = detNames.size();
122 for (Int_t iDet = 0; iDet < nofDetNames; iDet++) {
123 string detName = detNames[iDet];
124 Bool_t createHistograms = detName == "Total" || (detName == "Mvd" && fDet.GetDet(ECbmModuleId::kMvd))
125 || (detName == "Sts" && fDet.GetDet(ECbmModuleId::kSts))
126 || (detName == "Rich" && fDet.GetDet(ECbmModuleId::kRich))
127 || (detName == "Trd" && fDet.GetDet(ECbmModuleId::kTrd))
128 || (detName == "Much" && fDet.GetDet(ECbmModuleId::kMuch))
129 || (detName == "Tof" && fDet.GetDet(ECbmModuleId::kTof));
130 if (!createHistograms) continue; // Create histograms only for the detectors wich are in the setup
131 string rtname = "hrl_RadThickness_" + detName;
132 fHM->Add(rtname + "_H1", new TH1D(string(rtname + "_H1").c_str(),
133 string(rtname + "_H1;Radiation thickness [%];Entries").c_str(), nofBins, 0, 0));
134 fHM->Add(rtname + "_P2", new TProfile2D(string(rtname + "_P2").c_str(),
135 string(rtname + "_P2;X [cm];Y [cm];Radiation thickness [%]").c_str(),
136 nofBinsX, minX, maxX, nofBinsY, minY, maxY));
137 string tname = "hrl_Thickness_" + detName;
138 fHM->Add(tname + "_H1", new TH1D(string(tname + "_H1").c_str(),
139 string(tname + "_H1;Thickness [cm];Entries").c_str(), nofBins, 0, 0));
140 fHM->Add(tname + "_P2",
141 new TProfile2D(string(tname + "_P2").c_str(), string(tname + "_P2;X [cm];Y [cm];Thickness [cm]").c_str(),
142 nofBinsX, minX, maxX, nofBinsY, minY, maxY));
143 string tsname = "hrl_ThicknessSilicon_" + detName;
144 fHM->Add(tsname + "_H1", new TH1D(string(tsname + "_H1").c_str(),
145 string(tsname + "_H1;Thickness [cm];Entries").c_str(), nofBins, 0, 0));
146 fHM->Add(tsname + "_P2",
147 new TProfile2D(string(tsname + "_P2").c_str(), string(tsname + "_P2;X [cm];Y [cm];Thickness [cm]").c_str(),
148 nofBinsSiliconThicknessX, minX, maxX, nofBinsSiliconThicknessY, minY, maxY));
149 }
150
151 // Additional histograms for each station in tracking detectors
152 vector<string> trackingDetNames = list_of("Mvd")("Sts")("Trd")("Much")("MuchAbsorber");
153 Int_t nofTrackingDetNames = trackingDetNames.size();
154 for (Int_t iDet = 0; iDet < nofTrackingDetNames; iDet++) {
155 string dname = trackingDetNames[iDet];
156 Int_t nofStations = (dname == "Mvd") ? CbmLitTrackingGeometryConstructor::Instance()->GetNofMvdStations()
160 : (dname == "MuchAbsorber")
162 : 0;
163 for (Int_t iStation = 0; iStation < nofStations; iStation++) {
164 string name = "hrl_RadThickness_" + dname + "_" + ToString<Int_t>(iStation) + "_H1";
165 fHM->Add(name, new TH1D(name.c_str(), string(name + ";Radiation thickness [%];Entries").c_str(), nofBins, 0, 0));
166 name = "hrl_RadThickness_" + dname + "_" + ToString<Int_t>(iStation) + "_P2";
167 fHM->Add(name, new TProfile2D(name.c_str(), string(name + ";X [cm];Y [cm];Radiation thickness [%]").c_str(),
168 nofBinsX, minX, maxX, nofBinsY, minY, maxY));
169 name = "hrl_Thickness_" + dname + "_" + ToString<Int_t>(iStation) + "_H1";
170 fHM->Add(name, new TH1D(name.c_str(), string(name + ";Thickness [cm];Entries").c_str(), nofBins, 0, 0));
171 name = "hrl_Thickness_" + dname + "_" + ToString<Int_t>(iStation) + "_P2";
172 fHM->Add(name, new TProfile2D(name.c_str(), string(name + ";X [cm];Y [cm];Thickness [cm]").c_str(), nofBinsX,
173 minX, maxX, nofBinsY, minY, maxY));
174 name = "hrl_ThicknessSilicon_" + dname + "_" + ToString<Int_t>(iStation) + "_H1";
175 fHM->Add(name, new TH1D(name.c_str(), string(name + ";Thickness [cm];Entries").c_str(), nofBins, 0, 0));
176 name = "hrl_ThicknessSilicon_" + dname + "_" + ToString<Int_t>(iStation) + "_P2";
177 fHM->Add(name, new TProfile2D(name.c_str(), string(name + ";X [cm];Y [cm];Thickness [cm]").c_str(),
178 nofBinsSiliconThicknessX, minX, maxX, nofBinsSiliconThicknessY, minY, maxY));
179 }
180 }
181
182 // Additional histograms for MUCH absorbers
183
184
185 std::cout << fHM->ToString();
186}
187
188void CbmLitRadLengthQa::ExecDetector(const string& pathPattern, const string& detName)
189{
190 if (!(detName == "Total" || (detName == "Mvd" && fDet.GetDet(ECbmModuleId::kMvd))
191 || (detName == "Sts" && fDet.GetDet(ECbmModuleId::kSts))
192 || (detName == "Rich" && fDet.GetDet(ECbmModuleId::kRich))
193 || (detName == "Trd" && fDet.GetDet(ECbmModuleId::kTrd))
194 || (detName == "Much" && fDet.GetDet(ECbmModuleId::kMuch))
195 || (detName == "Tof" && fDet.GetDet(ECbmModuleId::kTof))))
196 return;
197
198 map<Int_t, Double_t> radThicknessOnTrack; // track ID -> sum of radiation thickness on track
199 map<Int_t, Double_t> thicknessOnTrack; // track ID -> sum of track lengthens on track
200 map<Int_t, Double_t> thicknessSiliconOnTrack; // track ID -> sum of track lengthens on track in silicon equivalent
201
202 Double_t x = 0., y = 0.;
203 Double_t r2max = std::numeric_limits<Double_t>::min();
204 for (Int_t iRL = 0; iRL < fRadLen->GetEntriesFast(); iRL++) {
205 FairRadLenPoint* point = (FairRadLenPoint*) fRadLen->At(iRL);
206
207 TVector3 pos = point->GetPosition();
208 TVector3 posOut = point->GetPositionOut();
209 TVector3 res = posOut - pos;
210 TVector3 middle = (pos + posOut) * 0.5;
211 //x = middle.X();
212 //y = middle.Y();
213
214 /* TGeoNode* nodeOut = */ gGeoManager->FindNode(posOut.X(), posOut.Y(), posOut.Z());
215 Bool_t isOutside = gGeoManager->IsOutside();
216 /* TGeoNode* node = */ gGeoManager->FindNode(middle.X(), middle.Y(), middle.Z());
217 TString path = gGeoManager->GetPath();
218 if (!isOutside && path.Contains(TRegexp(pathPattern.c_str()))) {
219 Double_t r2 = posOut.X() * posOut.X() + posOut.Y() * posOut.Y();
220 if (r2 > r2max) {
221 x = posOut.X();
222 y = posOut.Y();
223 r2max = r2;
224 }
225 const Double_t thickness = res.Mag();
226 const Double_t radThickness = 100 * thickness / point->GetRadLength();
227 const Double_t thicknessSilicon = (SILICON_RAD_LENGTH / point->GetRadLength()) * thickness;
228 radThicknessOnTrack[point->GetTrackID()] += radThickness;
229 thicknessOnTrack[point->GetTrackID()] += thickness;
230 thicknessSiliconOnTrack[point->GetTrackID()] += thicknessSilicon;
231 }
232 }
233
234 map<Int_t, Double_t>::const_iterator it;
235 for (it = radThicknessOnTrack.begin(); it != radThicknessOnTrack.end(); it++) {
236 Double_t rl = (*it).second;
237 fHM->H1("hrl_RadThickness_" + detName + "_H1")->Fill(rl);
238 fHM->P2("hrl_RadThickness_" + detName + "_P2")->Fill(x, y, rl);
239 }
240
241 for (it = thicknessOnTrack.begin(); it != thicknessOnTrack.end(); it++) {
242 Double_t tl = (*it).second;
243 fHM->H1("hrl_Thickness_" + detName + "_H1")->Fill(tl);
244 fHM->P2("hrl_Thickness_" + detName + "_P2")->Fill(x, y, tl);
245 }
246
247 for (it = thicknessSiliconOnTrack.begin(); it != thicknessSiliconOnTrack.end(); it++) {
248 Double_t tl = (*it).second;
249 fHM->H1("hrl_ThicknessSilicon_" + detName + "_H1")->Fill(tl);
250 fHM->P2("hrl_ThicknessSilicon_" + detName + "_P2")->Fill(x, y, tl);
251 }
252}
253
254void CbmLitRadLengthQa::ExecDetector(const string& detName, Int_t (*getStationId)(const TString&))
255{
256 if (!((detName == "Mvd" && fDet.GetDet(ECbmModuleId::kMvd)) || (detName == "Sts" && fDet.GetDet(ECbmModuleId::kSts))
257 || (detName == "Trd" && fDet.GetDet(ECbmModuleId::kTrd))
258 || (detName == "Much" && fDet.GetDet(ECbmModuleId::kMuch))
259 || (detName == "MuchAbsorber" && fDet.GetDet(ECbmModuleId::kMuch))))
260 return;
261
262 // track ID -> TRD station ID -> parameter
263 map<Int_t, map<Int_t, Double_t>> radThicknessOnTrack; // track ID -> sum of radiation thickness on track
264 map<Int_t, map<Int_t, Double_t>> thicknessOnTrack; // track ID -> sum of thickness on track
265 map<Int_t, map<Int_t, Double_t>> thicknessSiliconOnTrack; // track ID -> sum of thickness on track
266 map<Int_t, map<Int_t, pair<Double_t, Double_t>>>
267 xyOnTrack; // track ID -> Station ID -> (X,Y) coordinate of exit point
268 // map<Int_t, map<Int_t, Double_t> > r2maxOnTrack; // track ID -> Station ID -> maximum radius
269
270 // Double_t x, y;
271 // Double_t r2max = std::numeric_limits<Double_t>::min();
272 for (Int_t iRL = 0; iRL < fRadLen->GetEntriesFast(); iRL++) {
273 FairRadLenPoint* point = (FairRadLenPoint*) fRadLen->At(iRL);
274 Int_t trackId = point->GetTrackID();
275 //Int_t detId = point->GetDetectorID();
276
277 TVector3 pos = point->GetPosition();
278 TVector3 posOut = point->GetPositionOut();
279 TVector3 res = posOut - pos;
280 TVector3 middle = (pos + posOut) * 0.5;
281 //x = posOut.X();
282 //y = posOut.Y();
283
284 /* TGeoNode* node = */ gGeoManager->FindNode(middle.X(), middle.Y(), middle.Z());
285 TString path = gGeoManager->GetPath();
286 Int_t stationId = getStationId(path);
287
288 // Check if node exists in one of the geometry versions
289 if (stationId >= 0) {
290 // Double_t r2 = posOut.X() * posOut.X() + posOut.Y() * posOut.Y();
291 // Double_t& r2max = r2maxOnTrack[trackId][stationId];
292 // if (r2 > r2max) {
293 pair<Double_t, Double_t>& xy = xyOnTrack[trackId][stationId];
294 xy.first = posOut.X();
295 xy.second = posOut.Y();
296 // r2max = r2;
297 // }
298 const Double_t thickness = res.Mag();
299 const Double_t radThickness = 100 * thickness / point->GetRadLength();
300 const Double_t thicknessSilicon = (SILICON_RAD_LENGTH / point->GetRadLength()) * thickness;
301 radThicknessOnTrack[trackId][stationId] += radThickness;
302 thicknessOnTrack[trackId][stationId] += thickness;
303 thicknessSiliconOnTrack[trackId][stationId] += thicknessSilicon;
304 }
305 }
306
307 FillHistosDetector(radThicknessOnTrack, "hrl_RadThickness_" + detName + "_", xyOnTrack);
308 FillHistosDetector(thicknessOnTrack, "hrl_Thickness_" + detName + "_", xyOnTrack);
309 FillHistosDetector(thicknessSiliconOnTrack, "hrl_ThicknessSilicon_" + detName + "_", xyOnTrack);
310}
311
312void CbmLitRadLengthQa::FillHistosDetector(const map<Int_t, map<Int_t, Double_t>>& parMap, const string& histName,
313 map<Int_t, map<Int_t, pair<Double_t, Double_t>>>& xyOnTrack)
314{
315 map<Int_t, map<Int_t, Double_t>>::const_iterator it1;
316 for (it1 = parMap.begin(); it1 != parMap.end(); it1++) {
317 Int_t trackId = (*it1).first;
318 map<Int_t, Double_t>::const_iterator it2;
319 for (it2 = (*it1).second.begin(); it2 != (*it1).second.end(); it2++) {
320 Int_t station = (*it2).first;
321 Double_t param = (*it2).second;
322 string name = histName + ToString<Int_t>(station) + "_H1";
323 fHM->H1(name)->Fill(param);
324 name = histName + ToString<Int_t>(station) + "_P2";
325 const pair<Double_t, Double_t>& xy = xyOnTrack[trackId][station];
326 fHM->P2(name)->Fill(xy.first, xy.second, param);
327 }
328 }
329}
330
331Int_t CbmLitRadLengthQa::GetMvdStationId(const TString& /*nodePath*/)
332{
333 std::cout << "-W- CbmLitRadLengthQa::GetMvdStationId: function not implemented\n";
334 return 0;
335}
336
337Int_t CbmLitRadLengthQa::GetStsStationId(const TString& nodePath)
338{
339 Int_t station = 0;
340 Bool_t nodeExists = false;
341 if (nodePath.Contains(TRegexp("/cave_1/STS_v[0-9][0-9][a-z]_0/Station[0-9][0-9]_.+"))) { // sts_v12x
342 station = std::atoi(string((gGeoManager->GetPath() + 26), 2).c_str()); // 26-27th element is station number
343 nodeExists = true;
344 }
345 return (nodeExists) ? (station - 1) : -1;
346}
347
348Int_t CbmLitRadLengthQa::GetTrdStationId(const TString& nodePath)
349{
350 Int_t layerId = -1;
351 if (nodePath.Contains(TRegexp("/cave_1/trd_v13[a-z]_0/layer[0-9][0-9]_[0-9][0-9][0-9][0-9][0-9]/"
352 "module[0-9]_.+"))) { // trd_v13x NEW
353 layerId = std::atoi(string(nodePath.Data() + 24, 2).c_str()) - 1;
354 }
355 else if (nodePath.Contains(TRegexp("/cave_1/trd_v13[a-z]_[0-9][a-z]_0/"
356 "layer[0-9][0-9]_[0-9][0-9][0-9][0-9][0-"
357 "9]/module[0-9]_.+"))) { // trd_v13x NEW
358 layerId = std::atoi(string(nodePath.Data() + 27, 2).c_str()) - 1;
359 }
360 return layerId;
361}
362
363Int_t CbmLitRadLengthQa::GetMuchStationId(const TString& nodePath)
364{
365 Int_t station = 0;
366 Int_t layer = 0;
367 Bool_t nodeExists = false;
368 if (nodePath.Contains(TRegexp("/cave_1/much_0/muchstation[0-9][0-9]_0/"
369 "muchstation[0-9][0-9]layer[0-9]_0/.+"))) { // much_v11x
370 station = std::atoi(string(gGeoManager->GetPath() + 42, 2).c_str()); // 42-43th elements are station number
371 layer = std::atoi(string(1, *(gGeoManager->GetPath() + 49)).c_str()); // 49th element is layer number
372 nodeExists = true;
373 }
374 return (nodeExists)
376 : -1;
377}
378
379Int_t CbmLitRadLengthQa::GetMuchAbsorberId(const TString& nodePath)
380{
381 Int_t absorberId = -1;
382 if (nodePath.Contains(TRegexp("/cave_1/much_0/muchabsorber[0-9][0-9]_0"))) { // much_v11x
383 absorberId = std::atoi(string(gGeoManager->GetPath() + 27, 2).c_str()) - 1; // 42-43th elements are station number
384 }
385 return absorberId;
386}
387
398
400{
401 string pattern = (detName == "Mvd" || detName == "Sts" || detName == "Trd" || detName == "Much")
402 ? "hrl_ThicknessSilicon_" + detName + "_.+_P2"
403 : "hrl_ThicknessSilicon_" + detName + "_P2";
404 vector<TH1*> histos = fHM->H1Vector(pattern);
405 if (histos.empty()) return;
406 TFile* oldFile = gFile;
407 TDirectory* oldDirectory = gDirectory;
408 TFile* file = new TFile(string(fOutputDir + "/" + boost::algorithm::to_lower_copy(detName) + ".silicon.root").c_str(),
409 "RECREATE");
410 for (vector<TH1*>::const_iterator it = histos.begin(); it != histos.end(); it++) {
411 (*it)->Write();
412 }
413 if (detName == "Much") {
414 vector<TH1*> histos1 = fHM->H1Vector("hrl_ThicknessSilicon_MuchAbsorber_.+_P2");
415 for (vector<TH1*>::const_iterator it = histos1.begin(); it != histos1.end(); it++) {
416 (*it)->Write();
417 }
418 }
419 file->Close();
420 delete file;
421 gFile = oldFile;
422 gDirectory = oldDirectory;
423}
std::string ToString(ECbmModuleId modId)
Definition CbmDefs.cxx:70
@ kMvd
Micro-Vertex Detector.
@ kTrd
Transition Radiation Detector.
@ kTof
Time-of-flight Detector.
@ kSts
Silicon Tracking System.
@ kMuch
Muon detection system.
@ kRich
Ring-Imaging Cherenkov Detector.
Helper functions for drawing 1D and 2D histograms and graphs.
Histogram manager.
Create report for radiation length QA.
ClassImp(CbmLitRadLengthQa)
FairTask for estimation of radiation length in the detector.
Tracking geometry constructor.
Helper class to convert unique channel ID back and forth.
Histogram manager.
void ShrinkEmptyBinsH2ByPattern(const std::string &pattern)
Shrink empty bins in H2.
std::vector< TH1 * > H1Vector(const std::vector< std::string > &names) const
Return vector of pointers to TH1 histogram.
TProfile2D * P2(const std::string &name) const
Return pointer to TProfile2D.
void WriteToFile()
Write all objects to current opened file.
void Add(const std::string &name, TNamed *object)
Add new named object to manager.
std::string ToString() const
Return string representation of class.
TH1 * H1(const std::string &name) const
Return pointer to TH1 histogram.
void DetermineSetup()
Determines detector presence using TGeoManager.
bool GetDet(ECbmModuleId detId) const
Return detector presence in setup.
Create report for radiation length QA.
virtual InitStatus Init()
Derived from FairTask.
void CreateHistograms()
Create histograms.
static Int_t GetMuchAbsorberId(const TString &nodePath)
Return MUCH absorber ID by path to the node or -1 in case node does not exists.
virtual ~CbmLitRadLengthQa()
Destructor.
void ReadDataBranches()
Read data branches.
virtual void Finish()
Derived from FairTask.
static Int_t GetMvdStationId(const TString &nodePath)
Return MVD station ID by path to the node or -1 in case node does not exists.
TClonesArray * fRadLen
void SaveMaterialBudgetToFile()
Save silicon equivalent histograms to a separate files for each detector.
virtual void Exec(Option_t *opt)
Derived from FairTask.
CbmLitDetectorSetup fDet
static Int_t GetMuchStationId(const TString &nodePath)
Return MUCH station ID by path to the node or -1 in case node does not exists.
static const Double_t SILICON_RAD_LENGTH
CbmLitRadLengthQa()
Constructor.
CbmHistManager * fHM
void ExecDetector(const string &pathPattern, const string &detName)
Execute total radiation length for a particular detector.
void SaveDetectorMaterialBudgetToFile(const string &detName)
static Int_t GetStsStationId(const TString &nodePath)
Return STS station ID by path to the node or -1 in case node does not exists.
void FillHistosDetector(const map< Int_t, map< Int_t, Double_t > > &parMap, const string &histName, map< Int_t, map< Int_t, pair< Double_t, Double_t > > > &xyOnTrack)
static Int_t GetTrdStationId(const TString &nodePath)
Return TRD station ID by path to the node or -1 in case node does not exists.
Int_t GetNofStsStations()
Return number of stations in STS.
static CbmLitTrackingGeometryConstructor * Instance()
Return pointer to singleton object.
Int_t ConvertMuchToAbsoluteStationNr(Int_t station, Int_t layer)
Int_t GetNofMvdStations()
Return number of stations in MVD.
Int_t GetNofMuchStations()
Return number of stations in MUCH.
Int_t GetNofMuchAbsorbers()
Return number of MUCH absorbers.
Int_t GetNofTrdStations()
Return number of stations in TRD.
Base class for simulation reports.
void Create(CbmHistManager *histManager, const std::string &outputDir)
Main function which creates report data.
std::string ToString(const T &value)
Definition CbmUtils.h:26