31#include "FairRootManager.h"
36#include "TParameter.h"
37#include "TPaveStats.h"
44#include <TClonesArray.h>
45#include <TGenericClassInfo.h>
50#include <boost/exception/exception.hpp>
51#include <boost/type_index/type_index_facade.hpp>
66 : FairTask(name, verbose)
71 , fOutFolder(
"MuchHitFinderQA",
"MuchHitFinderQA")
75 , fNevents(
"nEvents", 0)
76 , fSignalPoints(
"SignalPoints", 0)
77 , fSignalHits(
"SignalHits", 0)
78 , fPointsTotal(
"PointsTotal", 0)
79 , fPointsUnderCounted(
"PointsUnderCounted", 0)
80 , fPointsOverCounted(
"PointsOverCounted", 0)
147 fManager = FairRootManager::Instance();
163 TFile* oldFile = gFile;
164 TDirectory* oldDir = gDirectory;
167 LOG_IF(fatal, !f) <<
"Could not open file " <<
fGeoFileName;
173 TObjArray* stations = f->Get<TObjArray>(
"stations");
174 LOG_IF(fatal, !stations) <<
"TObjArray stations not found in file " <<
fGeoFileName;
178 LOG(fatal) <<
"Can not find FairRootManager";
182 LOG(fatal) <<
"Can not find Much digi manager";
186 LOG(fatal) <<
"Can not find Much geo scheme";
190 LOG(error) <<
"No MC tracks found";
194 LOG(error) <<
"No MC points found";
198 LOG(error) <<
"No hits found";
202 LOG(error) <<
"No hits found";
223 LOG(debug) <<
"Init(): fNstations = " <<
fNstations;
232 new TH1I(Form(
"hMCPointsInCluster%i", i + 1), Form(
"MC Points in Cluster : Station %i ", i + 1), 10, 0, 10);
234 new TH1I(Form(
"hDigisInCluster%i", i + 1), Form(
"Digis in Cluster : Station %i ", i + 1), 10, 0, 10);
236 new TH1I(Form(
"hHitsPerCluster%i", i + 1), Form(
"Hits per Cluster : Station %i ", i + 1), 10, 0, 10);
241 gStyle->SetOptStat(1);
244 fhPullX =
new TH1D(
"hPullX",
"Pull distribution X;(x_{RC} - x_{MC}) / dx_{RC}", 500, -5, 5);
245 fhPullY =
new TH1D(
"hPullY",
"Pull distribution Y;(y_{RC} - y_{MC}) / dy_{RC}", 500, -5, 5);
246 fhPullT =
new TH1D(
"hPullT",
"Pull distribution T;(t_{RC} - t_{MC}) / dt_{RC}", 120, -5, 5);
249 fhResidualX =
new TH1D(
"hResidualX",
"Residual distribution X;(x_{RC} - x_{MC})(cm)", 500, -3, 3);
250 fhResidualY =
new TH1D(
"hResidualY",
"Residual distribution Y;(y_{RC} - y_{MC})(cm)", 500, -3, 3);
251 fhResidualT =
new TH1D(
"hResidualT",
"Residual distribution T;(t_{RC} - t_{MC})(ns)", 140, -17, 17);
302 LOG(debug) <<
"Event: " <<
fNevents.GetVal();
316 printf(
" CbmMuchHitFinderQa FinishTask\n");
319 gStyle->SetPaperSize(20, 20);
327 std::vector<TH1D*> vResHistos;
335 for (UInt_t i = 0; i < vResHistos.size(); i++) {
336 TH1D* histo = vResHistos[i];
338 if (histo->GetRMS() > 0.) {
339 histo->Fit(
"gaus",
"Q");
340 auto f = histo->GetFunction(
"gaus");
343 f->SetLineColor(kRed);
350 printf(
"===================================\n");
351 printf(
"StatisticsQa:\n");
352 printf(
"Total number of points: %i\n",
fPointsTotal.GetVal());
361 FairSink* sink = FairRootManager::Instance()->GetSink();
381 std::vector<TH1D*> vPullHistos;
382 vPullHistos.push_back(
fhPullX);
383 vPullHistos.push_back(
fhPullY);
384 vPullHistos.push_back(
fhPullT);
386 for (UInt_t i = 0; i < vPullHistos.size(); i++) {
387 TH1D* histo = vPullHistos[i];
391 TPaveStats* st = (TPaveStats*) histo->FindObject(
"stats");
397 st->SetOptStat(1110);
401 histo->DrawCopy(
"",
"");
410 std::vector<TH1D*> vResHistos;
415 for (UInt_t i = 0; i < vResHistos.size(); i++) {
416 TH1D* histo = vResHistos[i];
420 TPaveStats* st = (TPaveStats*) histo->FindObject(
"stats");
426 st->SetOptStat(1110);
430 histo->DrawCopy(
"",
"");
440 Int_t nClusters =
fClusters->GetEntriesFast();
441 TArrayI hitsInCluster;
442 TArrayI pointsInCluster;
443 hitsInCluster.Set(nClusters);
444 pointsInCluster.Set(nClusters);
445 LOG(debug) <<
" start Stat QA ";
446 for (Int_t i = 0; i < nClusters; i++)
447 hitsInCluster[i] = 0;
448 for (Int_t i = 0; i < nClusters; i++)
449 pointsInCluster[i] = 0;
451 for (Int_t i = 0; i <
fHits->GetEntriesFast(); i++) {
457 hitsInCluster[clusterId]++;
460 for (Int_t i = 0; i < nClusters; i++) {
463 map<Int_t, Int_t> map_points;
473 for (Int_t digiId = 0; digiId < nDigis; digiId++) {
474 Int_t index = cluster->
GetDigi(digiId);
478 LOG(fatal) <<
"CbmMuchHitFinderQa::StatisticsQa(): Match should be "
479 "present but is null.";
483 for (Int_t iRefPoint = 0; iRefPoint < nPoints; iRefPoint++) {
485 map_points[pointId] = 1;
489 pointsInCluster[i] = map_points.size();
493 for (Int_t i = 0; i < nClusters; i++) {
501 Int_t nPts = pointsInCluster[i];
502 Int_t nHits = hitsInCluster[i];
518 for (Int_t i = 0; i <
fHits->GetEntriesFast(); i++) {
529 if (verbose) printf(
" Hit %i, station %i, layer %i ", i, iStation, iLayer);
532 Bool_t hit_unique = 1;
533 for (Int_t j = i + 1; j <
fHits->GetEntriesFast(); j++) {
536 if (hit1->
GetRefId() == clusterId) {
541 if (verbose) printf(
"hit_unique=%i", hit_unique);
543 if (verbose) printf(
"\n");
549 Bool_t point_unique = 1;
552 for (Int_t digiId = 0; digiId < cluster->
GetNofDigis(); digiId++) {
553 Int_t index = cluster->
GetDigi(digiId);
558 LOG(fatal) <<
"CbmMuchHitFinderQa::PullsQa(): Error, digi not found.";
562 LOG(fatal) <<
"CbmMuchHitFinderQa::PullsQa(): Error, index out of bounds.";
567 LOG(fatal) <<
"CbmMuchHitFinderQa::PullsQa(): Error, match not found.";
571 if (verbose) printf(
" n=%i", match->
GetNofLinks());
573 printf(
" noise hit");
585 LOG(fatal) <<
"CbmMuchHitFinderQa::PullsQa(): Error, module not found.";
593 if (!(currentLink == link)) {
599 if (verbose) printf(
" point_unique=%i", point_unique);
601 if (verbose) printf(
"\n");
612 Double_t tMC = point->GetTime();
614 Double_t xRC = hit->
GetX();
615 Double_t yRC = hit->
GetY();
616 Double_t dx = hit->
GetDx();
617 Double_t dy = hit->
GetDy();
624 LOG(error) <<
"Anomalously small dx";
628 LOG(error) <<
"Anomalously small dy";
631 fhPullX->Fill((xRC - xMC) / dx);
632 fhPullY->Fill((yRC - yMC) / dy);
633 fhPullT->Fill((tRC - tMC) / dt);
638 if (verbose) printf(
"\n");
648 Int_t nClusters =
fClusters->GetEntriesFast();
649 vector<CbmLink> vPoints;
653 for (
int iLink = 0; iLink < match.
GetNofLinks(); iLink++) {
656 for (Int_t iPoint = 0; iPoint < nMuchPoints; iPoint++) {
662 vPoints.push_back(link);
667 std::sort(vPoints.begin(), vPoints.end());
669 for (Int_t iCluster = 0; iCluster < nClusters; ++iCluster) {
672 LOG(fatal) <<
"CbmMuchHitFinderQa::ClusterDeconvQa(): Error, cluster not found.";
676 for (Int_t
id = 0;
id < nDigis; ++id) {
677 Int_t iDigi = cluster->
GetDigi(
id);
680 LOG(fatal) <<
"CbmMuchHitFinderQa::ClusterDeconvQa(): Error, match not found.";
683 for (Int_t ip = 0; ip < match->
GetNofLinks(); ++ip) {
685 auto it = find(vPoints.begin(), vPoints.end(), pointLink);
686 assert(it != vPoints.end());
687 if (it->GetWeight() > 0.)
continue;
702 if (!point)
return kFALSE;
703 Int_t iTrack = point->GetTrackID();
705 if (!track)
return kFALSE;
707 if (iTrack != 0 && iTrack != 1)
return kFALSE;
711 if (TMath::Abs(pdgCode) == 13) {
ClassImp(CbmConverterManager)
@ kMuch
Muon detection system.
Data container for MUCH clusters.
Class for pixel hits in MUCH detector.
Definition of the CbmQaCanvas class.
int32_t GetAddress() const
int32_t GetDigi(int32_t index) const
Get digi at position index.
int32_t GetNofDigis() const
Number of digis in cluster.
static Bool_t IsMatchPresent(ECbmModuleId systemId)
Presence of a digi match branch.
InitStatus Init()
Initialisation.
const Digi * Get(Int_t index) const
Get a digi object.
static CbmDigiManager * Instance()
Static instance.
const CbmMatch * GetMatch(ECbmModuleId systemId, UInt_t index) const
Get a match object.
double GetTimeError() const
int32_t GetAddress() const
void SetIndex(int32_t index)
void SetWeight(float weight)
TObject * Get(const CbmLink *lnk)
Int_t Size(Int_t fileNumber, Int_t eventNumber)
Task class creating and managing CbmMCDataArray objects.
CbmMCDataArray * InitBranch(const char *name)
int32_t GetMotherId() const
int32_t GetPdgCode() const
const CbmLink & GetLink(int32_t i) const
int32_t GetNofLinks() const
static int32_t GetLayerIndex(int32_t address)
static int32_t GetStationIndex(int32_t address)
Data container for MUCH clusters.
int32_t GetAddress() const
void Init(TObjArray *stations, Int_t flag)
Int_t GetNStations() const
CbmMuchModule * GetModuleByDetId(Int_t detId) const
TParameter< int > fPointsTotal
CbmMuchGeoScheme * fGeoScheme
CbmMuchHitFinderQa(const char *name="MuchHitFinderQa", Int_t verbose=1)
TParameter< int > fNevents
FairRootManager * fManager
CbmMCDataArray * fMCTracks
std::vector< TH1I * > fhDigisInCluster
TParameter< int > fPointsUnderCounted
TParameter< int > fSignalPoints
number of processed events
TClonesArray * fClusters
subfolder for histograms
CbmTimeSlice * fTimeSlice
CbmDigiManager * fDigiManager
CbmQaCanvas * fCanvDigisInCluster
virtual void Exec(Option_t *option)
TFolder * histFolder
output folder with histos and canvases
TParameter< int > fSignalHits
virtual ~CbmMuchHitFinderQa()
CbmQaCanvas * fCanvResidual
virtual InitStatus Init()
Bool_t IsSignalPoint(CbmLink pointLink)
std::vector< TH1I * > fhHitsPerCluster
CbmQaCanvas * fCanvPointsInCluster
virtual void FinishTask()
virtual void SetParContainers()
CbmMCDataManager * fMcManager
CbmQaCanvas * fCanvHitsPerCluster
std::vector< TH1I * > fhPointsInCluster
TParameter< int > fPointsOverCounted
void Divide2D(int nPads)
Divide canvas into nPads in 2D in a nice way.
Bookkeeping of time-slice content.
const CbmMatch & GetMatch() const