35#include <FairRootManager.h>
40#include "TClonesArray.h"
41#include "TDatabasePDG.h"
46#include "TParameter.h"
51#include <TDirectory.h>
53#include <TParticlePDG.h>
65#define BINNING_CHARGE 100, 0, 300.0
66#define BINNING_LENGTH 100, 0, 2.5
67#define BINNING_CHARGE_LOG 100, 3, 10
68#define BINNING_ENERGY_LOG 100, -0.5, 4.5
69#define BINNING_ENERGY_LOG_EL 100, -0.5, 4.5
75 : FairTask(name, verbose)
76 , fOutFolder(
"MuchDigiQA",
"MuchDigitizerQA")
77 , fNevents(
"nEvents", 0)
170 TDirectory* oldDirectory = gDirectory;
172 fManager = FairRootManager::Instance();
174 LOG(fatal) <<
"Can not find FairRootManager";
180 LOG(fatal) <<
"Can not find Much geo scheme";
185 LOG(info) <<
"CbmMuchDigitizerQa: N Stations = " <<
fNstations;
189 LOG(fatal) <<
"Can not find Much digi manager";
200 if (!
fTimeSlice) { LOG(error) << GetName() <<
": No time slice found"; }
211 LOG(info) <<
" CbmMuchDigitizerQa: MC data read.";
214 LOG(info) <<
" CbmMuchDigitizerQa: No MC data found.";
231 gDirectory = oldDirectory;
239 fPadMinLx = std::numeric_limits<Double_t>::max();
240 fPadMinLy = std::numeric_limits<Double_t>::max();
241 fPadMaxLx = std::numeric_limits<Double_t>::min();
242 fPadMaxLy = std::numeric_limits<Double_t>::min();
245 printf(
"=========================================================\n");
246 printf(
" Station Nr.\t| Sectors\t| Channels\t| Pad min size\t\t| Pad max"
248 printf(
"---------------------------------------------------------\n");
252 Int_t nTotChannels = 0;
253 for (Int_t iStation = 0; iStation <
fNstations; iStation++) {
256 Double_t padMinLx = std::numeric_limits<Double_t>::max();
257 Double_t padMinLy = std::numeric_limits<Double_t>::max();
258 Double_t padMaxLx = std::numeric_limits<Double_t>::min();
259 Double_t padMaxLy = std::numeric_limits<Double_t>::min();
261 for (UInt_t im = 0; im < modules.size(); im++) {
264 LOG(fatal) <<
"module pointer is 0";
273 LOG(fatal) <<
"module is not a Gem module";
276 nChannels +=
module->GetNPads();
277 nSectors +=
module->GetNSectors();
278 vector<CbmMuchPad*> pads =
module->GetPads();
279 for (UInt_t ip = 0; ip < pads.size(); ip++) {
282 LOG(fatal) <<
"pad pointer is 0";
285 if (pad->
GetDx() < padMinLx) padMinLx = pad->
GetDx();
286 if (pad->
GetDy() < padMinLy) padMinLy = pad->
GetDy();
287 if (pad->
GetDx() > padMaxLx) padMaxLx = pad->
GetDx();
288 if (pad->
GetDy() > padMaxLy) padMaxLy = pad->
GetDy();
297 nTotChannels += nChannels;
300 printf(
"%i\t\t| %i\t\t| %i\t| %5.4fx%5.4f\t\t| %5.4fx%5.4f\n", iStation + 1, nSectors, nChannels, padMinLx,
301 padMinLy, padMaxLx, padMaxLy);
302 printf(
"%i\t\t| %i\t\t\n", iStation + 1, nChannels);
306 printf(
"-----------------------------------------------------------\n");
307 printf(
" Much total channels:\t\t| %i\t\t\n", nTotChannels);
308 printf(
"===========================================================\n");
374 Form(
"Track charge : Station %i; Charge [10^4 e]; Count", i + 1),
BINNING_CHARGE);
379 fhTrackCharge->GetXaxis()->SetTitle(
"Charge [10^{4} electrons]");
410 std::vector<TH2F*> vChargeHistos;
420 for (UInt_t i = 0; i < vChargeHistos.size(); i++) {
421 TH2F* histo = vChargeHistos[i];
423 histo->GetYaxis()->SetDecimals(kTRUE);
424 histo->GetYaxis()->SetTitleOffset(1.4);
425 histo->GetYaxis()->CenterTitle();
426 histo->GetYaxis()->SetTitle(
"Charge [10^{4} electrons]");
427 if (i < 4) { histo->GetXaxis()->SetTitle(
"Lg(E_{kin} [MeV])"); }
429 histo->GetXaxis()->SetTitle(
"Track length [cm]");
449 std::vector<TH1F*> vLengthHistos;
455 for (UInt_t i = 0; i < vLengthHistos.size(); i++) {
456 TH1F* histo = vLengthHistos[i];
457 histo->GetXaxis()->SetTitle(
"Track length [cm]");
474 Double_t rMax = station->
GetRmax();
475 Double_t rMin = station->
GetRmin();
478 new TH1F(Form(
"hPadsTotal%i", i + 1), Form(
"Number of pads vs radius: Station %i;Radius [cm]", i + 1), 100,
479 0.6 * rMin, 1.2 * rMax);
482 new TH1F(Form(
"hUsPadsFired%i", i + 1), Form(
"Number of fired pads vs radius: Station %i;Radius [cm]", i + 1),
483 100, 0.6 * rMin, 1.2 * rMax);
485 fvUsPadsFiredXY[i] =
new TH2F(Form(
"hUsPadsFiredXY%i", i + 1), Form(
"Pads fired XY : Station %i; X; Y", i + 1), 100,
486 -1.2 * rMax, 1.2 * rMax, 100, -1.2 * rMax, 1.2 * rMax);
489 new TH1F(Form(
"hPadsFired%i", i + 1), Form(
"Number of fired pads vs radius: Station %i;Radius [cm]", i + 1), 100,
490 0.6 * rMin, 1.2 * rMax);
493 Form(
"Pad occupancy vs radius: Station %i;Radius [cm];Occupancy, %%", i + 1), 100,
494 0.6 * rMin, 1.2 * rMax);
505 new TH2F(
"hNpadsVsS",
"Number of fired pads per particle vs average pad area", 50, 0, 5, 15, 0.5, 15.5);
517 for (vector<CbmMuchModule*>::iterator im = modules.begin(); im != modules.end(); im++) {
521 vector<CbmMuchPad*> pads =
module->GetPads();
522 for (UInt_t ip = 0; ip < pads.size(); ip++) {
525 Double_t x0 = pad->
GetX();
526 Double_t y0 = pad->
GetY();
527 Double_t r0 = TMath::Sqrt(x0 * x0 + y0 * y0);
533 Double_t errors[100];
534 for (Int_t i = 0; i < 100; i++) {
548 fFitEl->SetParameter(0, 0.511);
550 fFitEl->SetLineColor(kBlack);
553 fFitPi->SetParameter(0, 139.57);
555 fFitPi->SetLineColor(kBlack);
558 fFitPr->SetParameter(0, 938.27);
560 fFitPr->SetLineColor(kBlack);
589 LOG(debug) <<
"Event: " <<
fNevents.GetVal();
593 TDirectory* oldDirectory = gDirectory;
607 gDirectory = oldDirectory;
617 LOG(error) <<
"Can not find Much digi manager";
621 LOG(error) <<
"Can not find Much geo scheme";
636 LOG(error) <<
" Much station " << ista <<
" for adress " << address <<
" is out of the range";
642 LOG(error) <<
" Much module " << address <<
" doesn't exist";
646 LOG(error) <<
" Much module: unknown detector type " <<
module->GetDetectorType();
651 LOG(error) <<
" Unexpected Much module type: module " << address <<
" is not a Gem module";
656 LOG(error) <<
" Much pad for adress " << address <<
" doesn't exist";
691 Double_t x0 = pad->
GetX();
692 Double_t y0 = pad->
GetY();
693 double r0 = TMath::Sqrt(x0 * x0 + y0 * y0);
704 LOG(debug) <<
" CbmMuchDigitizerQa::DigitizerQa(): Found no MC data. Skipping.";
714 std::sort(events.begin(), events.end());
716 for (uint iLink = 0; iLink < events.size(); iLink++) {
720 for (Int_t ip = 0; ip < nMuchPoints; ip++) {
724 LOG(error) <<
" Much MC point " << ip <<
" out of " << nMuchPoints <<
" doesn't exist";
731 LOG(error) <<
" Much MC point station " << stId <<
" is out of the range";
736 Int_t trackId = point->GetTrackID();
737 if (trackId < 0 || trackId >= nMcTracks) {
738 LOG(error) <<
" Much MC point track Id " << trackId <<
" is out of the range";
744 LOG(error) <<
" MC track" << trackId <<
" is not found";
749 TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(pdgCode);
754 Double_t length = (vOut - vIn).Mag();
757 Double_t mass = particle->Mass();
758 kine =
sqrt(p.Mag2() + mass * mass) - mass;
764 if (motherId >= nMcTracks) {
765 LOG(error) <<
" MC track mother Id" << trackId <<
" is out of the range";
771 LOG(error) <<
" MC track" << trackId <<
" is not found";
787 LOG(debug) <<
" CbmMuchDigitizerQa::FillChargePerPoint()): Found no MC "
795 LOG(error) <<
"digi has no match";
801 for (Int_t pt = 0; pt < nofLinks; pt++) {
816 LOG(debug) <<
" CbmMuchDigitizerQa::FillDigitizerPerformancePlots(): Found "
817 "no MC data. Skipping.";
820 Bool_t verbose = (fVerbose > 2);
825 printf(
"%i", iPoint);
829 Double_t kine = 1000 * (info.
GetKine());
832 if (charge <= 0)
continue;
837 LOG(error) <<
"Particle with pdg code " << pdg <<
" produces signal in Much";
841 Double_t log_kine = (kine > 0) ? TMath::Log10(kine) : -0.2;
842 Double_t log_charge = TMath::Log10(charge);
843 charge = charge / 1.e+4;
846 Double_t area = info.
GetArea() / nPads;
862 else if (pdg == 211 || pdg == -211) {
867 else if (pdg == 11 || pdg == -11) {
872 if (pdg == 2212 && length > 0.3 && length < 0.32 && kine > 1000 && kine < 1020)
895 for (Int_t i = 0; i < 4; i++) {
897 gPad->Range(0, 0, 200, 200);
898 gPad->SetBottomMargin(0.11);
899 gPad->SetRightMargin(0.14);
900 gPad->SetLeftMargin(0.12);
915 for (Int_t i = 0; i < 4; i++) {
917 gPad->Range(0, 0, 200, 200);
918 gPad->SetBottomMargin(0.11);
919 gPad->SetRightMargin(0.14);
920 gPad->SetLeftMargin(0.12);
964 for (Int_t i = 0; i < 4; i++) {
967 gStyle->SetOptStat(1110);
986 for (
int iLink = 0; iLink < match.
GetNofLinks(); iLink++) {
989 for (Int_t ip = 0; ip < nMuchPoints; ip++) {
993 LOG(error) <<
" Much MC point " << ip <<
" out of " << nMuchPoints <<
" doesn't exist";
997 if (stId != 0)
continue;
999 if (layerId != 0)
continue;
1000 printf(
"point %4i xin=%6.2f yin=%6.2f xout=%6.2f yout=%6.2f zin=%6.2f\n", ip, point->
GetXIn(), point->
GetYIn(),
1013 if (stId != 0)
continue;
1015 if (layerId != 0)
continue;
1017 if (!module)
continue;
1019 Double_t x0 = pad->
GetX();
1020 Double_t y0 = pad->
GetY();
1021 UInt_t charge = digi->
GetAdc();
1022 printf(
"digi %4i x0=%5.1f y0=%5.1f charge=%3i\n", i, x0, y0, charge);
1029 TDirectory* oldDirectory = gDirectory;
1033 gDirectory = oldDirectory;
1041 if (!FairRootManager::Instance() || !FairRootManager::Instance()->GetSink()) {
1042 LOG(error) <<
"No sink found";
1045 FairSink* sink = FairRootManager::Instance()->GetSink();
1046 sink->WriteObject(&
GetQa(),
nullptr);
1052 TCanvas* c =
new TCanvas(
"nMeanVsS",
"nMeanVsS", 2 * 800, 2 * 400);
1053 printf(
"===================================\n");
1054 printf(
"DigitizerQa:\n");
1058 for (Int_t iS = 1; iS <= 10; iS++) {
1060 s[iS] = -5.25 + 0.5 * iS;
1062 for (Int_t iN = 1; iN <= 10; iN++) {
1063 nMean[iS] += iN *
fhNpadsVsS->GetBinContent(iS, iN);
1066 if (total > 0) nMean[iS] /= total;
1067 printf(
"%f %f\n", s[iS], nMean[iS]);
1071 TGraph* gNvsS =
new TGraph(11, s, nMean);
1074 gNvsS->SetMarkerColor(4);
1075 gNvsS->SetMarkerSize(1.5);
1076 gNvsS->SetMarkerStyle(21);
1077 gNvsS->SetTitle(
"nMeanVsS");
1078 gNvsS->GetYaxis()->SetTitle(
"nMean");
1079 gNvsS->GetYaxis()->SetTitle(
"nMean");
1081 gNvsS->DrawClone(
"AP");
1088 Double_t gaz_gain_mean = 1.7e+4;
1089 Double_t scale = 1.e+6;
1090 gaz_gain_mean /= scale;
1091 Double_t mass = par[0];
1092 Double_t
x = TMath::Power(10, lg_x[0]);
1093 return gaz_gain_mean *
MPV_n_e(
x, mass);
1100 TF1 fPol6(
"fPol6",
"pol6", -5, 10);
1102 logT =
log(Tkin * 0.511 / mass);
1103 if (logT > 9.21034) logT = 9.21034;
1105 return fPol6.EvalPar(&logT,
mpv_e);
1107 else if (mass >= 0.1 && mass < 0.2) {
1108 logT =
log(Tkin * 105.658 / mass);
1109 if (logT > 9.21034) logT = 9.21034;
1111 return fPol6.EvalPar(&logT,
mpv_mu);
1114 logT =
log(Tkin * 938.272 / mass);
1115 if (logT > 9.21034) logT = 9.21034;
1117 return fPol6.EvalPar(&logT,
mpv_p);
@ kMuch
Muon detection system.
#define BINNING_ENERGY_LOG
ClassImp(CbmMuchDigitizerQa)
#define BINNING_CHARGE_LOG
#define BINNING_ENERGY_LOG_EL
constexpr double min_logT_e
constexpr double min_logT_p
constexpr double mpv_mu[]
constexpr double min_logT_mu
Definition of the CbmQaCanvas class.
friend fvec sqrt(const fvec &a)
friend fvec log(const fvec &a)
static Int_t GetNofDigis(ECbmModuleId systemId)
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.
void SetIndex(int32_t index)
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
const std::vector< CbmLink > & GetLinks() const
static int32_t GetLayerIndex(int32_t address)
static int32_t GetStationIndex(int32_t address)
int32_t GetAddress() const
virtual void SetParContainers()
TH2F * fhTrackChargeVsTrackLengthEl
TH2F * fhTrackChargeVsTrackEnergyLogEl
CbmTimeSlice * fTimeSlice
TH1F * fhTrackChargeLog
MC point charge.
std::vector< TH1F * > fvUsPadsFiredR
number of processed events
CbmQaCanvas * fCanvStationCharge
void FillDigitizerPerformancePlots()
void FillTotalPadsHistos()
CbmQaCanvas * fCanvChargeVsEnergy
void PrintFrontLayerDigis()
void DrawChargeCanvases()
static Double_t LandauMPV(Double_t *x, Double_t *par)
TH2F * fhTrackChargeVsTrackLength
CbmMCDataManager * fMcManager
TH2F * fhTrackChargeVsTrackLengthPi
const CbmMuchPad * GetPad(UInt_t address) const
get pad from the digi address
std::vector< TH2F * > fvUsPadsFiredXY
FairRootManager * fManager
folder wich contains histogramms
CbmQaCanvas * fCanvPadOccupancyR
CbmQaCanvas * fCanvPadsTotalR
virtual void Exec(Option_t *option)
void PrintFrontLayerPoints()
std::vector< TH1F * > fvPadsFiredR
CbmMuchGeoScheme * fGeoScheme
TH2F * fhTrackChargeVsTrackEnergyLog
CbmMuchPointInfo & getPointInfo(const CbmLink &link)
map point link -> point info
void DrawLengthCanvases()
CbmMuchDigitizerQa(const char *name="MuchHitFinderQa", Int_t verbose=1)
TParameter< int > fNevents
output folder with histos and canvases
CbmQaCanvas * fCanvChargeVsLength
void FillChargePerPoint()
CbmQaCanvas * fCanvNpadsVsArea
CbmQaCanvas * fCanvTrackLength
virtual ~CbmMuchDigitizerQa()
TH2F * fhTrackChargeVsTrackEnergyLogPr
CbmMCDataArray * fMCTracks
TH1F * fhTrackLength
MC point charge for selected protons.
CbmDigiManager * fDigiManager
std::vector< TH1F * > fvPadOccupancyR
CbmQaCanvas * fCanvCharge
TH2F * fhTrackChargeVsTrackEnergyLogPi
static Double_t MPV_n_e(Double_t Tkin, Double_t mass)
TH2F * fhTrackChargeVsTrackLengthPr
std::map< CbmLink, CbmMuchPointInfo > fMcPointInfoMap
TH1F * fhTrackChargePr_1GeV_3mm
MC point charge log scale.
CbmQaCanvas * fCanvUsPadsFiredXY
virtual InitStatus Init()
TClonesArray * fDigiMatches
std::vector< TH1F * > fvPadsTotalR
std::vector< TH1F * > fvTrackCharge
CbmMuchStation * GetStation(Int_t iStation) const
std::vector< CbmMuchModule * > GetModules() const
static CbmMuchGeoScheme * Instance()
Int_t GetNStations() const
CbmMuchModule * GetModuleByDetId(Int_t detId) const
CbmMuchPad * GetPad(Int_t address)
Int_t GetDetectorType() const
void Print(Option_t *="") const
Double_t GetLength() const
void AddCharge(Int_t charge)
Int_t GetStationId() const
void PositionIn(TVector3 &pos) const
void PositionOut(TVector3 &pos) const
void Divide2D(int nPads)
Divide canvas into nPads in 2D in a nice way.
Bookkeeping of time-slice content.
const CbmMatch & GetMatch() const