CbmRoot
Loading...
Searching...
No Matches
CbmBuildEventsQa.cxx
Go to the documentation of this file.
1/* Copyright (C) 2016-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Dominik Smith, Volker Friese [committer] */
4
10#include "CbmBuildEventsQa.h"
11
12#include "CbmDigiManager.h"
13#include "CbmEvent.h"
14#include "CbmLink.h"
15#include "CbmMatch.h"
16#include "CbmModuleList.h"
17#include "CbmQaCanvas.h"
18#include "FairRootManager.h"
19#include "TClonesArray.h"
20#include "TH1.h"
21#include "TH2.h"
22#include "TStopwatch.h"
23
24#include <Logger.h>
25
26#include <cassert>
27#include <iomanip>
28#include <iostream>
29#include <map>
30
31using namespace std;
32
33// ===== Constructor =====================================================
35 : FairTask("BuildEventsQA")
36 , fEvents(NULL)
37 , fNofEntries(0)
38 , fOutFolder("BuildEventsQA", "Build Events QA")
39{
40}
41// ===========================================================================
42
43
44// ===== Destructor ======================================================
46// ===========================================================================
47
48
49// ===== De-initialisation =============================================
51{
52 fOutFolder.Clear();
53 histFolder = nullptr;
54 SafeDelete(fhCorrectDigiRatioAll);
55 SafeDelete(fhFoundDigiRatioAll);
56
57 for (auto& p : fhMapSystemsCorrectDigi) {
58 SafeDelete(p.second);
59 }
60 for (auto& p : fhMapSystemsFoundDigi) {
61 SafeDelete(p.second);
62 }
65}
66
67// ===== Task initialisation =============================================
69{
70 DeInit();
71
72 // --- Get FairRootManager instance
73 FairRootManager* ioman = FairRootManager::Instance();
74 assert(ioman);
75
76 // --- Get input array (CbmEvent)
77 fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent"));
78 if (nullptr == fEvents) {
79 LOG(fatal) << "CbmBuildEventsQa::Init"
80 << "No CbmEvent TClonesArray found!";
81 }
82
83 // --- DigiManager instance
85 fDigiMan->Init();
86
87 // --- Check input data
88 for (ECbmModuleId system = ECbmModuleId::kMvd; system < ECbmModuleId::kNofSystems; ++system) {
89 if (fDigiMan->IsMatchPresent(system)) {
90 LOG(info) << GetName() << ": Found match branch for " << CbmModuleList::GetModuleNameCaps(system);
91 fSystems.push_back(system);
92 }
93 }
94 if (fSystems.empty()) {
95 LOG(fatal) << GetName() << ": No match branch found!";
96 return kFATAL;
97 }
98
100
101 return kSUCCESS;
102}
103// ===========================================================================
104
105
106// ==================== Init histograms ======================================
108{
109 // --- Init histogram folder
110 histFolder = fOutFolder.AddFolder("hist", "Histogramms");
111
112 // --- Init histograms
113 fhCorrectDigiRatioAll = new TH1F("fhCorrectDigiRatioAll", "Correct digis per event [pct]", 416, -2, 102);
115 new TH1F("fhCorrectDigiRatioAllNoNoise", "Correct digis per event [pct], disregarding noise", 416, -2, 102);
116 fhNoiseDigiRatioAll = new TH1F("fhNoiseDigiRatioAll", "Noise digis per event [pct]", 416, -2, 102);
117 fhFoundDigiRatioAll = new TH1F("fhFoundDigiRatioAll", "Found digis per event [pct]", 416, -2, 102);
118 fhCorrectVsFoundAll = new TH2I("fhCorrectVsFoundAll", "Correct digis [pct] vs. Found digis [pct]; Correct; Found ",
119 110, -5., 105., 110, -5., 105.);
121 new TH2I("fhCorrectVsFoundAllNoNoise", "Correct digis [pct] vs. Found digis [pct], no noise; Correct; Found ", 110,
122 -5., 105., 110, -5., 105.);
123
130
131 fCanvAllSystems = new CbmQaCanvas("cAllSystems", "", 3 * 400, 2 * 400);
134
135 for (ECbmModuleId& system : fSystems) {
136 TString moduleName = CbmModuleList::GetModuleNameCaps(system);
137 TString h1name = "fhCorrectDigiRatio" + moduleName;
138 TString h2name = "fhCorrectDigiRatioNoNoise" + moduleName;
139 TString h3name = "fhNoiseDigiRatio" + moduleName;
140 TString h4name = "fhFoundDigiRatio" + moduleName;
141 TString h5name = "fhCorrectVsFound" + moduleName;
142 TString h6name = "fhCorrectVsFoundNoNoise" + moduleName;
143
145 new TH1F(h1name, Form("Correct digis per event, %s [pct]", moduleName.Data()), 416, -2, 102);
147 new TH1F(h2name, Form("Correct digis per event, %s [pct], disregarding noise", moduleName.Data()), 416, -2, 102);
148 fhMapSystemsNoiseDigi[system] =
149 new TH1F(h3name, Form("Noise digis per event, %s [pct]", moduleName.Data()), 416, -2, 102);
150 fhMapSystemsFoundDigi[system] =
151 new TH1F(h4name, Form("Found digis per event, %s [pct]", moduleName.Data()), 416, -2, 102);
153 new TH2I(h5name, Form("Correct digis [pct] vs. Found digis [pct], %s; Correct; Found", moduleName.Data()), 110,
154 -5., 105., 110, -5., 105.);
155 fhMapSystemsCorrectVsFoundNoNoise[system] = new TH2I(
156 h6name, Form("Correct digis [pct] vs. Found digis [pct], %s, no noise; Correct; Found", moduleName.Data()), 110,
157 -5., 105., 110, -5., 105.);
158
161 histFolder->Add(fhMapSystemsNoiseDigi[system]);
162 histFolder->Add(fhMapSystemsFoundDigi[system]);
165
166 fCanvMapSystems[system] =
167 new CbmQaCanvas(Form("c%s", moduleName.Data()), Form("%s", moduleName.Data()), 3 * 400, 2 * 400);
168 fCanvMapSystems[system]->Divide2D(6);
169 fOutFolder.Add(fCanvMapSystems[system]);
170 }
171}
172// ===========================================================================
173
174
175// ===== Task execution ==================================================
177{
178 // --- Time and counters
179 TStopwatch timer;
180 timer.Start();
181
182 // --- Event loop
183 int nEvents = fEvents->GetEntriesFast();
184 for (int iEvent = 0; iEvent < nEvents; iEvent++) {
185 CbmEvent* event = (CbmEvent*) fEvents->At(iEvent);
186
187 // --- Match event to MC
188 LOG(info) << "";
189 MatchEvent(event);
190 if (event->GetMatch()->GetNofLinks() < 1) {
191 LOG(info) << "Warning: No links in this event match object. Skipping event # " << event->GetNumber();
192 continue;
193 } // if (-1 == event->GetMatch()->GetNofLinks())
194 int matchedMcEventNr = event->GetMatch()->GetMatchedLink().GetEntry();
195
196 //match to -1 only if event is pure noise
197 if (event->GetMatch()->GetNofLinks() > 1 && matchedMcEventNr == -1) {
198 matchedMcEventNr = getMatchedMcEventNoNoise(event);
199 }
200
201 LOG(info) << GetName() << ": Event " << event->GetNumber() << ", digis in event: " << event->GetNofData()
202 << ", links to MC events: " << event->GetMatch()->GetNofLinks()
203 << ", matched MC event number: " << matchedMcEventNr;
204 if (matchedMcEventNr == -1) {
205 LOG(info) << "(event is pure noise)";
206 }
207
208 LOG(info) << "Start time: " << event->GetStartTime() << ", end time: " << event->GetEndTime()
209 << ", middle time: " << (event->GetStartTime() + event->GetEndTime()) / 2.;
210
211 const std::vector<CbmLink> linkList = event->GetMatch()->GetLinks();
212 for (size_t iLink = 0; iLink < linkList.size(); iLink++) {
213 int linkedEvent = linkList.at(iLink).GetEntry();
214 float linkedWeight = linkList.at(iLink).GetWeight();
215 std::string isMatched;
216 if (linkedEvent == matchedMcEventNr) {
217 isMatched = " (matched)";
218 }
219 else {
220 isMatched = "";
221 }
222 LOG(info) << "Link " << iLink << ": MC event " << linkedEvent << " weight " << linkedWeight << isMatched;
223 }
224
225 // --- Loop over all detector systems
226 for (ECbmModuleId& system : fSystems) {
227
228 // --- Skip system if no data branch or no match match present
229 if (!fDigiMan->IsPresent(system)) continue;
230 if (!fDigiMan->IsMatchPresent(system)) continue;
231
232 // --- Counters
233 int nDigis = event->GetNofData(GetDigiType(system));
234 int nDigisNoise = 0;
235 int nDigisCorrect = 0;
236 int nLinks = 0;
237 int nLinksNoise = 0;
238 int nLinksCorrect = 0;
239
240 // --- Loop over digis in event
241 for (int iDigi = 0; iDigi < nDigis; iDigi++) {
242 unsigned int index = event->GetIndex(GetDigiType(system), iDigi);
243
244 const CbmMatch* digiMatch = fDigiMan->GetMatch(system, index);
245 assert(digiMatch);
246
247 // --- Check MC event of digi match
248 if (digiMatch->GetNofLinks()) {
249 if (digiMatch->GetMatchedLink().GetEntry() == matchedMcEventNr) nDigisCorrect++;
250 if (digiMatch->GetMatchedLink().GetEntry() == -1) nDigisNoise++;
251 }
252 else {
253 nDigisNoise++;
254 }
255
256 for (int iLink = 0; iLink < digiMatch->GetNofLinks(); iLink++) {
257 int entry = digiMatch->GetLink(iLink).GetEntry();
258 nLinks++;
259 if (entry == matchedMcEventNr) nLinksCorrect++;
260 if (entry == -1) nLinksNoise++;
261 }
262 }
263
264 // --- Counters
265 int totDigis = fDigiMan->GetNofDigis(system);
266 int totEventDigis = 0;
267
268 // --- Loop over all digis for the current system
269 for (int iDigi = 0; iDigi < totDigis; iDigi++) {
270
271 // --- Get the event number through the match object
272 const CbmMatch* match = fDigiMan->GetMatch(system, iDigi);
273 assert(match);
274 int mcEvent = -1;
275
276 if (match->GetNofLinks()) {
277 mcEvent = match->GetMatchedLink().GetEntry();
278 }
279 //digi belongs to current event
280 if (mcEvent == matchedMcEventNr) totEventDigis++;
281 }
282
283 // --- QA output
284 if (0 < nDigis) {
285 const double correctDigisPercent = 100. * Double_t(nDigisCorrect) / Double_t(nDigis);
286 const double correctDigisPercentNoNoise = 100. * Double_t(nDigisCorrect) / Double_t(nDigis - nDigisNoise);
287 const double noiseDigisPercent = 100. * Double_t(nDigisNoise) / Double_t(nDigis);
288 const double foundDigisPercent = 100. * Double_t(nDigisCorrect) / Double_t(totEventDigis);
289 const double correctLinksPercent = 100. * Double_t(nLinksCorrect) / Double_t(nLinks);
290 const double correctLinksPercentNoNoise = 100. * Double_t(nLinksCorrect) / Double_t(nLinks - nLinksNoise);
291 const double noiseLinksPercent = 100. * Double_t(nLinksNoise) / Double_t(nLinks);
292
293 LOG(info) << GetName() << ": Detector " << CbmModuleList::GetModuleNameCaps(system);
294 LOG(info) << "Correct digis " << nDigisCorrect << " / " << nDigis << " = " << correctDigisPercent << " %";
295 if (matchedMcEventNr != -1) {
296 LOG(info) << "Noise digis " << nDigisNoise << " / " << nDigis << " = " << noiseDigisPercent << " %";
297 LOG(info) << "Correct digis, disregarding noise " << nDigisCorrect << " / " << nDigis - nDigisNoise << " = "
298 << correctDigisPercentNoNoise << " %";
299 }
300 LOG(info) << "Correct digi links " << nLinksCorrect << " / " << nLinks << " = " << correctLinksPercent << " % ";
301 if (matchedMcEventNr != -1) {
302 LOG(info) << "Noise digi links " << nLinksNoise << " / " << nLinks << " = " << noiseLinksPercent << " % ";
303 LOG(info) << "Correct digi links, disregarding noise " << nLinksCorrect << " / " << nLinks - nLinksNoise
304 << " = " << correctLinksPercentNoNoise << " % ";
305 }
306 LOG(info) << "Digi percentage found " << nDigisCorrect << " / " << totEventDigis << " = " << foundDigisPercent
307 << " % ";
308
309 //fill histograms
310 if (matchedMcEventNr != -1) { //ignore events which are pure noise
311 fhCorrectDigiRatioAll->Fill(correctDigisPercent);
312 fhCorrectDigiRatioAllNoNoise->Fill(correctDigisPercentNoNoise);
313 fhNoiseDigiRatioAll->Fill(noiseDigisPercent);
314 fhFoundDigiRatioAll->Fill(foundDigisPercent);
315
316 fhCorrectVsFoundAll->Fill(correctDigisPercent, foundDigisPercent);
317 fhCorrectVsFoundAllNoNoise->Fill(correctDigisPercentNoNoise, foundDigisPercent);
318
319 fhMapSystemsCorrectDigi[system]->Fill(correctDigisPercent);
320 fhMapSystemsCorrectDigiNoNoise[system]->Fill(correctDigisPercentNoNoise);
321 fhMapSystemsNoiseDigi[system]->Fill(noiseDigisPercent);
322 fhMapSystemsFoundDigi[system]->Fill(foundDigisPercent);
323
324 fhMapSystemsCorrectVsFound[system]->Fill(correctDigisPercent, foundDigisPercent);
325 fhMapSystemsCorrectVsFoundNoNoise[system]->Fill(correctDigisPercentNoNoise, foundDigisPercent);
326 }
327 }
328 else {
329 LOG(info) << GetName() << ": Detector " << CbmModuleList::GetModuleNameCaps(system)
330 << ", no digis in this event";
331 }
332 } // systems
333 } //# events
334
335 // Timer and counters
336 fNofEntries++;
337 timer.Stop();
338
339 // --- Execution log
340 LOG(info) << "+ " << setw(20) << GetName() << ": Entry " << setw(6) << right << fNofEntries << ", real time " << fixed
341 << setprecision(6) << timer.RealTime() << " s, events: " << fEvents->GetEntriesFast();
342}
343// ===========================================================================
344
345// ===== Match event =====================================================
347{
348 const std::vector<CbmLink> linkList = event->GetMatch()->GetLinks();
349 int matchedEvent = -1;
350 float matchedWeight = 0.0;
351 for (size_t iLink = 0; iLink < linkList.size(); iLink++) {
352 const int linkedEvent = linkList.at(iLink).GetEntry();
353 const float linkedWeight = linkList.at(iLink).GetWeight();
354 if (linkedEvent != -1 && linkedWeight > matchedWeight) {
355 matchedEvent = linkedEvent;
356 matchedWeight = linkedWeight;
357 }
358 }
359 return matchedEvent;
360}
361
362// ===== Match event =====================================================
364{
365 // --- Get event match object. If present, will be cleared first. If not,
366 // --- it will be created.
367 CbmMatch* match = event->GetMatch();
368 if (!match) {
369 LOG(info) << "No match data found in event. Creating new.";
370 match = new CbmMatch();
371 event->SetMatch(match);
372 }
373 else {
374 LOG(info) << "Match data found in event. Clearing.";
375 match->ClearLinks();
376 }
377
378 // --- Loop over all detector systems
379 for (ECbmModuleId& system : fSystems) {
380
381 //Skip if reference detectors are set and current system isn't one
382 if (!fRefDetectors.empty()
383 && std::find(fRefDetectors.begin(), fRefDetectors.end(), system) == fRefDetectors.end()) {
384 continue;
385 }
386
387 // --- Loop over digis in event
388 int iNbDigis = event->GetNofData(GetDigiType(system));
389 for (int iDigi = 0; iDigi < iNbDigis; iDigi++) {
390 int index = event->GetIndex(GetDigiType(system), iDigi);
391 const CbmMatch* digiMatch = fDigiMan->GetMatch(system, index);
392 assert(digiMatch);
393
394 // --- Update event match with digi links
395 // --- N.b.: The member "index" of CbmLink has here no meaning, since
396 // --- there is only one MC event per tree entry.
397 for (int iLink = 0; iLink < digiMatch->GetNofLinks(); iLink++) {
398 int file = digiMatch->GetLink(iLink).GetFile();
399 int entry = digiMatch->GetLink(iLink).GetEntry();
400 //Double_t weight = digiMatch->GetLink(iLink).GetWeight();
401 const double weight =
402 .00001; // assign the same weight to all links, since different detectors don't use the same scale
403 // LOG(info) << "Adding link (weight, entry, file): " << weight << " "
404 // << entry << " " << file;
405 match->AddLink(weight, 0, entry, file);
406 }
407 }
408 }
409}
410// ===========================================================================
411
412
413// ===== Finish task =======================================================
415{
416 //output histograms
417 if (!FairRootManager::Instance() || !FairRootManager::Instance()->GetSink()) {
418 LOG(error) << "No sink found";
419 return;
420 }
421
422 fCanvAllSystems->cd(1);
423 fhCorrectDigiRatioAll->DrawCopy("colz", "");
424
425 fCanvAllSystems->cd(2);
426 fhCorrectDigiRatioAllNoNoise->DrawCopy("colz", "");
427
428 fCanvAllSystems->cd(3);
429 fhNoiseDigiRatioAll->DrawCopy("colz", "");
430
431 fCanvAllSystems->cd(4);
432 fhFoundDigiRatioAll->DrawCopy("colz", "");
433
434 fCanvAllSystems->cd(5);
435 fhCorrectVsFoundAll->DrawCopy("colz", "");
436
437 fCanvAllSystems->cd(6);
438 fhCorrectVsFoundAllNoNoise->DrawCopy("colz", "");
439
440 for (ECbmModuleId& system : fSystems) {
441 fCanvMapSystems[system]->cd(1);
442 fhMapSystemsCorrectDigi[system]->DrawCopy("colz", "");
443
444 fCanvMapSystems[system]->cd(2);
445 fhMapSystemsCorrectDigiNoNoise[system]->DrawCopy("colz", "");
446
447 fCanvMapSystems[system]->cd(3);
448 fhMapSystemsNoiseDigi[system]->DrawCopy("colz", "");
449
450 fCanvMapSystems[system]->cd(4);
451 fhMapSystemsFoundDigi[system]->DrawCopy("colz", "");
452
453 fCanvMapSystems[system]->cd(5);
454 fhMapSystemsCorrectVsFound[system]->DrawCopy("colz", "");
455
456 fCanvMapSystems[system]->cd(6);
457 fhMapSystemsCorrectVsFoundNoNoise[system]->DrawCopy("colz", "");
458 }
459
460 FairSink* sink = FairRootManager::Instance()->GetSink();
461 sink->WriteObject(&fOutFolder, nullptr);
462}
463// ===========================================================================
464
465
466// ===== Get digi type =====================================================
482// ===========================================================================
483
484
ClassImp(CbmConverterManager)
ECbmDataType
Definition CbmDefs.h:90
ECbmModuleId
Definition CbmDefs.h:39
@ kMvd
Micro-Vertex Detector.
@ kTrd
Transition Radiation Detector.
@ kTof
Time-of-flight Detector.
@ kPsd
Projectile spectator detector.
@ kSts
Silicon Tracking System.
@ kMuch
Muon detection system.
@ kFsd
Forward spectator detector.
@ kNofSystems
For loops over active systems.
@ kRich
Ring-Imaging Cherenkov Detector.
Definition of the CbmQaCanvas class.
TH1F * fhNoiseDigiRatioAll
correct digis per event for all detectors, disregarding noise
TH2I * fhCorrectVsFoundAll
digis found per event for all detectors
TH1F * fhFoundDigiRatioAll
noise digis per event for all detectors
void MatchEvent(CbmEvent *event)
std::map< ECbmModuleId, TH2I * > fhMapSystemsCorrectVsFoundNoNoise
int fNofEntries
Number of processed entries.
CbmQaCanvas * fCanvAllSystems
correct digis per event vs found digis per event, all detectors, disregarding noise
std::map< ECbmModuleId, CbmQaCanvas * > fCanvMapSystems
virtual InitStatus Init()
output folder with histos and canvases
ECbmDataType GetDigiType(ECbmModuleId system)
TClonesArray * fEvents
Input array (class CbmEvent)
virtual void Exec(Option_t *opt)
std::map< ECbmModuleId, TH2I * > fhMapSystemsCorrectVsFound
std::vector< ECbmModuleId > fRefDetectors
int getMatchedMcEventNoNoise(const CbmEvent *event)
std::map< ECbmModuleId, TH1F * > fhMapSystemsFoundDigi
std::vector< ECbmModuleId > fSystems
CbmDigiManager * fDigiMan
TH1F * fhCorrectDigiRatioAllNoNoise
correct digis per event for all detectors
std::map< ECbmModuleId, TH1F * > fhMapSystemsCorrectDigiNoNoise
std::map< ECbmModuleId, TH1F * > fhMapSystemsNoiseDigi
TH2I * fhCorrectVsFoundAllNoNoise
correct digis per event vs found digis per event, all detectors
TFolder fOutFolder
subfolder for histograms
std::map< ECbmModuleId, TH1F * > fhMapSystemsCorrectDigi
summary canvas
static Int_t GetNofDigis(ECbmModuleId systemId)
static Bool_t IsPresent(ECbmModuleId systemId)
Presence of a digi branch.
static Bool_t IsMatchPresent(ECbmModuleId systemId)
Presence of a digi match branch.
InitStatus Init()
Initialisation.
static CbmDigiManager * Instance()
Static instance.
const CbmMatch * GetMatch(ECbmModuleId systemId, UInt_t index) const
Get a match object.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
const CbmLink & GetLink(int32_t i) const
Definition CbmMatch.h:39
int32_t GetNofLinks() const
Definition CbmMatch.h:42
void AddLink(const CbmLink &newLink)
Definition CbmMatch.cxx:47
const CbmLink & GetMatchedLink() const
Definition CbmMatch.h:41
void ClearLinks()
Definition CbmMatch.cxx:78
static TString GetModuleNameCaps(ECbmModuleId moduleId)
void Divide2D(int nPads)
Divide canvas into nPads in 2D in a nice way.
Hash for CbmL1LinkKey.