34#include "TClonesArray.h"
35#include "TDatabasePDG.h"
40#include "TParameter.h"
44#include <FairRootManager.h>
51#include <TDirectory.h>
53#include <TParticlePDG.h>
64#define BINNING_CHARGE 100, 0, 300.0
65#define BINNING_LENGTH 100, 0, 2.5
66#define BINNING_CHARGE_LOG 100, 3, 10
67#define BINNING_ENERGY_LOG 100, -0.5, 4.5
68#define BINNING_ENERGY_LOG_EL 100, -0.5, 4.5
74 : FairTask(name, verbose)
169 TDirectory* oldDirectory = gDirectory;
171 fManager = FairRootManager::Instance();
173 LOG(fatal) <<
"Can not find FairRootManager";
179 LOG(fatal) <<
"Can not find Much geo scheme";
184 LOG(info) <<
"CbmMuchDigitizerQa: N Stations = " <<
fNstations;
188 LOG(fatal) <<
"Can not find Much digi manager";
199 if (!
fTimeSlice) { LOG(error) << GetName() <<
": No time slice found"; }
210 LOG(info) <<
" CbmMuchDigitizerQa: MC data read.";
213 LOG(info) <<
" CbmMuchDigitizerQa: No MC data found.";
230 gDirectory = oldDirectory;
238 fPadMinLx = std::numeric_limits<Double_t>::max();
239 fPadMinLy = std::numeric_limits<Double_t>::max();
240 fPadMaxLx = std::numeric_limits<Double_t>::min();
241 fPadMaxLy = std::numeric_limits<Double_t>::min();
244 printf(
"=========================================================\n");
245 printf(
" Station Nr.\t| Sectors\t| Channels\t| Pad min size\t\t| Pad max"
247 printf(
"---------------------------------------------------------\n");
251 Int_t nTotChannels = 0;
255 Double_t padMinLx = std::numeric_limits<Double_t>::max();
256 Double_t padMinLy = std::numeric_limits<Double_t>::max();
257 Double_t padMaxLx = std::numeric_limits<Double_t>::min();
258 Double_t padMaxLy = std::numeric_limits<Double_t>::min();
260 for (UInt_t im = 0; im < modules.size(); im++) {
263 LOG(fatal) <<
"module pointer is 0";
272 LOG(fatal) <<
"module is not a Gem module";
275 nChannels +=
module->GetNPads();
276 nSectors +=
module->GetNSectors();
278 for (UInt_t ip = 0; ip < pads.size(); ip++) {
281 LOG(fatal) <<
"pad pointer is 0";
284 if (pad->
GetDx() < padMinLx) padMinLx = pad->
GetDx();
285 if (pad->
GetDy() < padMinLy) padMinLy = pad->
GetDy();
286 if (pad->
GetDx() > padMaxLx) padMaxLx = pad->
GetDx();
287 if (pad->
GetDy() > padMaxLy) padMaxLy = pad->
GetDy();
296 nTotChannels += nChannels;
299 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,
300 padMinLy, padMaxLx, padMaxLy);
301 printf(
"%i\t\t| %i\t\t\n", iStation + 1, nChannels);
305 printf(
"-----------------------------------------------------------\n");
306 printf(
" Much total channels:\t\t| %i\t\t\n", nTotChannels);
307 printf(
"===========================================================\n");
373 Form(
"Track charge : Station %i; Charge [10^4 e]; Count", i + 1),
BINNING_CHARGE);
378 fhTrackCharge->GetXaxis()->SetTitle(
"Charge [10^{4} electrons]");
409 std::vector<TH2F*> vChargeHistos;
419 for (UInt_t i = 0; i < vChargeHistos.size(); i++) {
420 TH2F* histo = vChargeHistos[i];
422 histo->GetYaxis()->SetDecimals(kTRUE);
423 histo->GetYaxis()->SetTitleOffset(1.4);
424 histo->GetYaxis()->CenterTitle();
425 histo->GetYaxis()->SetTitle(
"Charge [10^{4} electrons]");
426 if (i < 4) { histo->GetXaxis()->SetTitle(
"Lg(E_{kin} [MeV])"); }
428 histo->GetXaxis()->SetTitle(
"Track length [cm]");
448 std::vector<TH1F*> vLengthHistos;
454 for (UInt_t i = 0; i < vLengthHistos.size(); i++) {
455 TH1F* histo = vLengthHistos[i];
456 histo->GetXaxis()->SetTitle(
"Track length [cm]");
473 Double_t rMax = station->
GetRmax();
474 Double_t rMin = station->
GetRmin();
477 new TH1F(Form(
"hPadsTotal%i", i + 1), Form(
"Number of pads vs radius: Station %i;Radius [cm]", i + 1), 100,
478 0.6 * rMin, 1.2 * rMax);
481 new TH1F(Form(
"hUsPadsFired%i", i + 1), Form(
"Number of fired pads vs radius: Station %i;Radius [cm]", i + 1),
482 100, 0.6 * rMin, 1.2 * rMax);
484 fvUsPadsFiredXY[i] =
new TH2F(Form(
"hUsPadsFiredXY%i", i + 1), Form(
"Pads fired XY : Station %i; X; Y", i + 1), 100,
485 -1.2 * rMax, 1.2 * rMax, 100, -1.2 * rMax, 1.2 * rMax);
488 new TH1F(Form(
"hPadsFired%i", i + 1), Form(
"Number of fired pads vs radius: Station %i;Radius [cm]", i + 1), 100,
489 0.6 * rMin, 1.2 * rMax);
492 Form(
"Pad occupancy vs radius: Station %i;Radius [cm];Occupancy, %%", i + 1), 100,
493 0.6 * rMin, 1.2 * rMax);
504 new TH2F(
"hNpadsVsS",
"Number of fired pads per particle vs average pad area", 50, 0, 5, 15, 0.5, 15.5);
521 for (UInt_t ip = 0; ip < pads.size(); ip++) {
524 Double_t x0 = pad->
GetX();
525 Double_t y0 = pad->
GetY();
526 Double_t r0 = TMath::Sqrt(x0 * x0 + y0 * y0);
532 Double_t errors[100];
533 for (
Int_t i = 0; i < 100; i++) {
547 fFitEl->SetParameter(0, 0.511);
549 fFitEl->SetLineColor(kBlack);
552 fFitPi->SetParameter(0, 139.57);
554 fFitPi->SetLineColor(kBlack);
557 fFitPr->SetParameter(0, 938.27);
559 fFitPr->SetLineColor(kBlack);
588 LOG(debug) <<
"Event: " <<
fNevents.GetVal();
592 TDirectory* oldDirectory = gDirectory;
606 gDirectory = oldDirectory;
616 LOG(error) <<
"Can not find Much digi manager";
620 LOG(error) <<
"Can not find Much geo scheme";
635 LOG(error) <<
" Much station " << ista <<
" for adress " << address <<
" is out of the range";
641 LOG(error) <<
" Much module " << address <<
" doesn't exist";
645 LOG(error) <<
" Much module: unknown detector type " <<
module->GetDetectorType();
650 LOG(error) <<
" Unexpected Much module type: module " << address <<
" is not a Gem module";
655 LOG(error) <<
" Much pad for adress " << address <<
" doesn't exist";
690 Double_t x0 = pad->
GetX();
691 Double_t y0 = pad->
GetY();
692 double r0 = TMath::Sqrt(x0 * x0 + y0 * y0);
703 LOG(debug) <<
" CbmMuchDigitizerQa::DigitizerQa(): Found no MC data. Skipping.";
712 std::vector<CbmLink> events =
fTimeSlice->GetMatch().GetLinks();
713 std::sort(events.begin(), events.end());
715 for (uint iLink = 0; iLink < events.size(); iLink++) {
717 int nMuchPoints =
fPoints->Size(link);
719 for (
Int_t ip = 0; ip < nMuchPoints; ip++) {
723 LOG(error) <<
" Much MC point " << ip <<
" out of " << nMuchPoints <<
" doesn't exist";
730 LOG(error) <<
" Much MC point station " << stId <<
" is out of the range";
735 Int_t trackId = point->GetTrackID();
736 if (trackId < 0 || trackId >= nMcTracks) {
737 LOG(error) <<
" Much MC point track Id " << trackId <<
" is out of the range";
743 LOG(error) <<
" MC track" << trackId <<
" is not found";
748 TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(pdgCode);
753 Double_t length = (vOut - vIn).Mag();
756 Double_t mass = particle->Mass();
757 kine =
sqrt(p.Mag2() + mass * mass) - mass;
763 if (motherId >= nMcTracks) {
764 LOG(error) <<
" MC track mother Id" << trackId <<
" is out of the range";
770 LOG(error) <<
" MC track" << trackId <<
" is not found";
786 LOG(debug) <<
" CbmMuchDigitizerQa::FillChargePerPoint()): Found no MC "
794 LOG(error) <<
"digi has no match";
800 for (
Int_t pt = 0; pt < nofLinks; pt++) {
815 LOG(debug) <<
" CbmMuchDigitizerQa::FillDigitizerPerformancePlots(): Found "
816 "no MC data. Skipping.";
819 Bool_t verbose = (fVerbose > 2);
824 printf(
"%i", iPoint);
828 Double_t kine = 1000 * (info.
GetKine());
831 if (charge <= 0)
continue;
836 LOG(error) <<
"Particle with pdg code " << pdg <<
" produces signal in Much";
840 Double_t log_kine = (kine > 0) ? TMath::Log10(kine) : -0.2;
841 Double_t log_charge = TMath::Log10(charge);
842 charge = charge / 1.e+4;
845 Double_t area = info.
GetArea() / nPads;
861 else if (pdg == 211 || pdg == -211) {
866 else if (pdg == 11 || pdg == -11) {
871 if (pdg == 2212 && length > 0.3 && length < 0.32 && kine > 1000 && kine < 1020)
894 for (
Int_t i = 0; i < 4; i++) {
896 gPad->Range(0, 0, 200, 200);
897 gPad->SetBottomMargin(0.11);
898 gPad->SetRightMargin(0.14);
899 gPad->SetLeftMargin(0.12);
914 for (
Int_t i = 0; i < 4; i++) {
916 gPad->Range(0, 0, 200, 200);
917 gPad->SetBottomMargin(0.11);
918 gPad->SetRightMargin(0.14);
919 gPad->SetLeftMargin(0.12);
963 for (
Int_t i = 0; i < 4; i++) {
966 gStyle->SetOptStat(1110);
985 for (
int iLink = 0; iLink < match.
GetNofLinks(); iLink++) {
987 int nMuchPoints =
fPoints->Size(link);
988 for (
Int_t ip = 0; ip < nMuchPoints; ip++) {
992 LOG(error) <<
" Much MC point " << ip <<
" out of " << nMuchPoints <<
" doesn't exist";
996 if (stId != 0)
continue;
998 if (layerId != 0)
continue;
999 printf(
"point %4i xin=%6.2f yin=%6.2f xout=%6.2f yout=%6.2f zin=%6.2f\n", ip, point->
GetXIn(), point->
GetYIn(),
1012 if (stId != 0)
continue;
1014 if (layerId != 0)
continue;
1016 if (!module)
continue;
1018 Double_t x0 = pad->
GetX();
1019 Double_t y0 = pad->
GetY();
1020 UInt_t charge = digi->
GetAdc();
1021 printf(
"digi %4i x0=%5.1f y0=%5.1f charge=%3i\n", i, x0, y0, charge);
1028 TDirectory* oldDirectory = gDirectory;
1032 gDirectory = oldDirectory;
1040 if (!FairRootManager::Instance() || !FairRootManager::Instance()->GetSink()) {
1041 LOG(error) <<
"No sink found";
1044 FairSink* sink = FairRootManager::Instance()->GetSink();
1045 sink->WriteObject(&
GetQa(),
nullptr);
1051 TCanvas* c =
new TCanvas(
"nMeanVsS",
"nMeanVsS", 2 * 800, 2 * 400);
1052 printf(
"===================================\n");
1053 printf(
"DigitizerQa:\n");
1057 for (
Int_t iS = 1; iS <= 10; iS++) {
1059 s[iS] = -5.25 + 0.5 * iS;
1061 for (
Int_t iN = 1; iN <= 10; iN++) {
1062 nMean[iS] += iN *
fhNpadsVsS->GetBinContent(iS, iN);
1065 if (total > 0) nMean[iS] /= total;
1066 printf(
"%f %f\n", s[iS], nMean[iS]);
1070 TGraph* gNvsS =
new TGraph(11, s, nMean);
1073 gNvsS->SetMarkerColor(4);
1074 gNvsS->SetMarkerSize(1.5);
1075 gNvsS->SetMarkerStyle(21);
1076 gNvsS->SetTitle(
"nMeanVsS");
1077 gNvsS->GetYaxis()->SetTitle(
"nMean");
1078 gNvsS->GetYaxis()->SetTitle(
"nMean");
1080 gNvsS->DrawClone(
"AP");
1087 Double_t gaz_gain_mean = 1.7e+4;
1088 Double_t scale = 1.e+6;
1089 gaz_gain_mean /= scale;
1090 Double_t mass = par[0];
1091 Double_t
x = TMath::Power(10, lg_x[0]);
1092 return gaz_gain_mean *
MPV_n_e(
x, mass);
1099 TF1 fPol6(
"fPol6",
"pol6", -5, 10);
1101 logT =
log(Tkin * 0.511 / mass);
1102 if (logT > 9.21034) logT = 9.21034;
1104 return fPol6.EvalPar(&logT,
mpv_e);
1106 else if (mass >= 0.1 && mass < 0.2) {
1107 logT =
log(Tkin * 105.658 / mass);
1108 if (logT > 9.21034) logT = 9.21034;
1110 return fPol6.EvalPar(&logT,
mpv_mu);
1113 logT =
log(Tkin * 938.272 / mass);
1114 if (logT > 9.21034) logT = 9.21034;
1116 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 CbmDigiManager * Instance()
Static instance.
void SetIndex(int32_t index)
Task class creating and managing CbmMCDataArray objects.
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)
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
static CbmMuchGeoScheme * Instance()
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
Bookkeeping of time-slice content.