37 FairRootManager* manager = FairRootManager::Instance();
38 if (!manager) LOG(fatal) << GetName() <<
": No FairRootManager!";
43 LOG(fatal) << GetName() <<
": No RichDigi array found in CbmDigiManager!";
46 fCbmEvents =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"CbmEvent"));
47 LOG(info) << GetName() <<
": CbmEvent" << (
fCbmEvents ?
" " :
" NOT ") <<
"found.\n";
49 fRichHits =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"RichHit"));
50 if (!
fRichHits) LOG(fatal) << GetName() <<
": No RichHit array found in FairRootManager!";
52 fRichRings =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"RichRing"));
53 if (!
fRichRings) LOG(fatal) << GetName() <<
": No RichRing array found in FairRootManager!";
55 fRichProjections =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"RichProjection"));
56 if (!
fRichProjections) LOG(fatal) << GetName() <<
": No RichProjection array found in FairRootManager!";
60 auto* mcManager =
static_cast<CbmMCDataManager*
>(manager->GetObject(
"MCDataManager"));
61 if (!mcManager) LOG(fatal) << GetName() <<
": No MCDataManager!";
63 fMcTracks = mcManager->InitBranch(
"MCTrack");
64 if (!
fMcTracks) LOG(fatal) << GetName() <<
": No MCTrack array found in CbmMCDataManager!";
67 if (!
fRichPoints) LOG(fatal) << GetName() <<
": No RichPoint array found in CbmMCDataManager!";
69 fRichRingMatches =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"RichRingMatch"));
70 if (!
fRichRingMatches) LOG(fatal) << GetName() <<
": No RichRingMatch array found in FairRootManager!";
82 MakeQaObject<TH1D>(
"RichRingsPerEvent",
"RichRings per event; #RichRings / Event; Entries", 71, -0.5, 70.5);
84 MakeQaObject<TH1D>(
"RichRingTimeEvent",
"Rich ring time in event; Ring time - Event time [ns]; Entires", 30, 12., 24.);
86 MakeQaObject<TH1D>(
"RingHitsTime",
"Rich ring time - Hit times; Ring time - Hit time [ns]; Entires", 100, -5., 5.);
88 MakeQaObject<TH2D>(
"RingXY",
"Rich ring positions; x [cm]; y [cm]; Entries", 50, -130., 130.0, 20, 110., 200.);
92 MakeQaObject<TH1D>(
"RingRadius",
"Rich ring radius; Radius [cm]; Entries", 50, 0., 10.);
94 MakeQaObject<TH1D>(
"RingNumHits",
"Rich ring number of hits; #Ring hits; Entries", 51, -0.5, 50.5);
96 MakeQaObject<TH1D>(
"RingCenterX",
"Rich ring center x position; Center x [cm]; Entries", 100, -130., 130.0);
98 MakeQaObject<TH1D>(
"RingCenterY",
"Rich ring center y position; |Center y| [cm]; Entries", 50, 110., 200.);
100 MakeQaObject<TH1D>(
"RingAaxis",
"Rich ring A axis; A axis [cm]; Entries", 50, 0., 10.);
102 MakeQaObject<TH1D>(
"RingBaxis",
"Rich ring B axis; B axis [cm]; Entries", 50, 0., 10.);
108 MakeQaObject<TH1D>(
"RingChi2oNDF",
"Rich ring Chi2 over NDF; Chi2 / NDF; Entries", 40, -0.5, 3.);
113 MakeQaObject<TH1D>(
"RingRadialPosition",
"Rich ring radial position; RadialPosition [cm]; Entries", 50, 0., 150);
115 MakeQaObject<TH1D>(
"RingRadialAngle",
"Rich ring radial angle; RadialAngle [rad]; Entries", 50, 0., 3.1415);
120 MakeQaObject<TH1D>(
"RingTypes",
"Reconstructed rings for types; Ring types; Entries", 8, -1.5, 6.5);
121 const std::array<std::string, 8> tickLabels{
"Reco",
"TrueReco",
"PrimEl",
"SecEl",
"Pion",
"Other",
"Fake",
"Clone"};
122 for (std::size_t i = 0; i < tickLabels.size(); ++i) {
129 "Rich ring reconstruction purity; x [cm]; y [cm]; Purity",
130 50, -130., 130.0, 20, 110., 200.);
132 const std::array<TString, 6> typesStr{
"TrueReco",
"PrimEl",
"SecEl",
"Pion",
"Other",
"Fake"};
133 const std::array<TString, 6> typesStrFull{
"all correct reconstructed rings",
"primary electrons",
134 "seconday electrons",
"pions",
"others",
"fakes"};
140 "RingRecoEff" + typesStr.at(type),
141 "Rich ring reconstruction efficiency" + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; Ring reconstruction efficiency",
150 "RingFeatures" + typesStr.at(type) +
"/RingRadius" + typesStr.at(type),
151 "Rich ring radius " + typesStrFull.at(type) +
"; Radius [cm]; Entries",
155 "RingFeatures" + typesStr.at(type) +
"/RingNumHits" + typesStr.at(type),
156 "Rich ring number of hits " + typesStrFull.at(type) +
"; #Ring hits; Entries",
160 "RingFeatures" + typesStr.at(type) +
"/RingCenterX" + typesStr.at(type),
161 "Rich ring center x position " + typesStrFull.at(type) +
"; Center x [cm]; Entries",
165 "RingFeatures" + typesStr.at(type) +
"/RingCenterY" + typesStr.at(type),
166 "Rich ring center y position " + typesStrFull.at(type) +
"; |Center y| [cm]; Entries",
170 "RingFeatures" + typesStr.at(type) +
"/RingAaxis" + typesStr.at(type),
171 "Rich ring A axis " + typesStrFull.at(type) +
"; A axis [cm]; Entries",
175 "RingFeatures" + typesStr.at(type) +
"/RingBaxis" + typesStr.at(type),
176 "Rich ring B axis " + typesStrFull.at(type) +
"; B axis [cm]; Entries",
180 "RingFeatures" + typesStr.at(type) +
"/RingBoA" + typesStr.at(type),
181 "Rich ring B over A axis " + typesStrFull.at(type) +
"; B/A; Entries",
185 "RingFeatures" + typesStr.at(type) +
"/RingPhi" + typesStr.at(type),
186 "Rich ring phi " + typesStrFull.at(type) +
"; Phi [rad]; Entries",
190 "RingFeatures" + typesStr.at(type) +
"/RingChi2oNDF" + typesStr.at(type),
191 "Rich ring Chi2 over NDF " + typesStrFull.at(type) +
"; Chi2 / NDF; Entries",
200 "RingFeatures" + typesStr.at(type) +
"/RingRadialPosition" + typesStr.at(type),
201 "Rich ring radial position " + typesStrFull.at(type) +
"; RadialPosition [cm]; Entries",
205 "RingFeatures" + typesStr.at(type) +
"/RingRadialAngle" + typesStr.at(type),
206 "Rich ring radial angle " + typesStrFull.at(type) +
"; RadialAngle [rad]; Entries",
215 "RingFeatures" + typesStr.at(type) +
"/RingRadiusMomentum" + typesStr.at(type),
216 "Rich ring radius vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; Radius [cm]; Entries",
217 60, 0., 12., 50, 0., 10.);
220 "RingFeatures" + typesStr.at(type) +
"/RingNumHitsMomentum" + typesStr.at(type),
221 "Rich ring number of hits vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; #Ring hits; Entries",
222 60, 0., 12., 51, -0.5, 50.5);
225 "RingFeatures" + typesStr.at(type) +
"/RingCenterXMomentum" + typesStr.at(type),
226 "Rich ring center x position vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; Center x [cm]; Entries",
227 60, 0., 12., 100, -130., 130.0);
230 "RingFeatures" + typesStr.at(type) +
"/RingCenterYMomentum" + typesStr.at(type),
231 "Rich ring center y position vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; |Center y| [cm]; Entries",
232 60, 0., 12., 50, 110., 200.);
235 "RingFeatures" + typesStr.at(type) +
"/RingAaxisMomentum" + typesStr.at(type),
236 "Rich ring A axis vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; A axis [cm]; Entries",
237 60, 0., 12., 50, 0., 10.);
240 "RingFeatures" + typesStr.at(type) +
"/RingBaxisMomentum" + typesStr.at(type),
241 "Rich ring B axis vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; B axis [cm]; Entries",
242 60, 0., 12., 50, 0., 10.);
245 "RingFeatures" + typesStr.at(type) +
"/RingBoAMomentum" + typesStr.at(type),
246 "Rich ring B over A axis vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; B/A; Entries",
247 60, 0., 12., 50, 0., 1.1);
250 "RingFeatures" + typesStr.at(type) +
"/RingPhiMomentum" + typesStr.at(type),
251 "Rich ring phi vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; Phi [rad]; Entries",
252 60, 0., 12., 40, -2., 2.);
255 "RingFeatures" + typesStr.at(type) +
"/RingChi2oNDFMomentum" + typesStr.at(type),
256 "Rich ring Chi2 over NDF vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; Chi2 / NDF; Entries",
257 60, 0., 12., 40, -0.5, 3.);
265 "RingFeatures" + typesStr.at(type) +
"/RingRadialPositionMomentum" + typesStr.at(type),
266 "Rich ring radial position vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; RadialPosition [cm]; Entries",
267 60, 0., 12., 50, 0., 150);
270 "RingFeatures" + typesStr.at(type) +
"/RingRadialAngleMomentum" + typesStr.at(type),
271 "Rich ring radial angle vs momentum " + typesStrFull.at(type) +
"; p_{MC} [GeV/c]; RadialAngle [rad]; Entries",
272 60, 0., 12., 50, 0., 3.1415);
283 for (
int iRing = 0; iRing < nRichRings; ++iRing) {
290 const int nHits = ring->GetNofHits();
291 for (
int iHit = 0; iHit < nHits; ++iHit) {
317 std::array<std::map<CbmLink, int>, 2> accRingsCam{};
321 for (
int iHit = 0; iHit < nRichHits; iHit++) {
325 const std::vector<CbmLink> motherIds =
327 const bool isUpperCamera = hit->GetY() > 0.;
328 for (
const auto& motherId : motherIds)
329 (isUpperCamera ? accRingsCam[0] : accRingsCam[1])[motherId]++;
334 for (
auto& accRings : accRingsCam) {
335 for (
auto it = accRings.begin(); it != accRings.end();) {
336 auto& [link, nHits] = *it;
338 it = accRings.erase(it);
343 it = accRings.erase(it);
354 for (
Int_t iRing = 0; iRing < nRichRings; ++iRing) {
361 LOG(warn) << GetName() <<
": ringMatch not found for ring index " << iRingIndex <<
" !";
367 if (ringMatch->GetNofLinks() <= 0) {
368 LOG(warn) << GetName() <<
": Full digitizer noise ring for index " << iRingIndex
369 <<
" , this should be extremely rare!";
374 const CbmLink matchedLink{ringMatch->GetMatchedLink()};
377 LOG(warn) << GetName() <<
": mcTrack not found for matched link " << matchedLink.ToString() <<
" !";
383 const double quota{ringMatch->GetTrueOverAllHitsRatio()};
389 const bool isUpperCamera{ring->GetCenterY() > 0.};
390 std::map<CbmLink, int>& accRings = isUpperCamera ? accRingsCam[0] : accRingsCam[1];
391 if (accRings.count(matchedLink) > 0) {
392 accRings[matchedLink]++;
393 if (accRings[matchedLink] > 1) {
411 for (
const auto& accRings : accRingsCam) {
412 for (
const auto& [link, nMatchedRings] : accRings) {
414 if (!mcTrack)
continue;
447 if (
static_cast<int>(std::round(nTrueRecoRings)) !=
static_cast<int>(std::round(nSumParticleTypes))) {
448 LOG(error) <<
"nTrueRecoRings != nSumParticleTypes. This should never happen!";
450 if (
static_cast<int>(std::round(nRecoRings)) !=
static_cast<int>(std::round(nTrueRecoRings + nSumFakeClone))) {
451 LOG(error) <<
"nRecoRingsTotal != nTrueRecoRingsTotal + nSumFakeClone. This should never happen!";
454 const std::array<std::string, 4> flagNames{
"Mean efficiency all",
"Mean efficiency primary electrons",
455 "Mean efficiency secondary electrons",
"Mean efficiency pions"};
459 std::string msg = status ?
"" : Form(
"value %f < %f", val,
fRingRecoEffsMin.at(type));
466 std::string msg = status ?
"" : Form(
"value %f < %f", purity,
fRingPurityMin);
471 auto GetErrorFraction = [&](
const double meanNom,
const double errNom,
const double meanDenom,
472 const double errDenom) {
473 const double sqrtFactor =
474 std::sqrt((errNom / meanNom) * (errNom / meanNom) + (errDenom / meanDenom) * (errDenom / meanDenom));
475 return (meanNom / meanDenom) * sqrtFactor;
478 auto* pTable =
MakeQaObject<CbmQaTable>(
"table_efficiency",
"RICH ring reconstruction efficiencies and purity", 8, 1);
479 pTable->SetColWidth(30);
480 pTable->SetNamesOfCols({
" mean +/- error"});
481 pTable->SetNamesOfRows({{
"All particle efficiency"},
482 {
"Primary electron efficiency"},
483 {
"Secondary electron efficiency"},
485 {
"Other efficiency"},
493 const std::array<int, 3> rowIndex{5, 6, 7};
494 for (
int i = 0; i < 3; ++i) {
495 pTable->SetCell(rowIndex.at(i), 0,
503 LOG(info) <<
'\n' << pTable->ToString(4,
true);