From c84cbb2e13071ea84c1f3b9812f5c5df7650dd0b Mon Sep 17 00:00:00 2001 From: Dominik Smith <d.smith@gsi.de> Date: Wed, 21 Oct 2020 13:12:21 +0200 Subject: [PATCH] Cleaned up CbmMuchTransportQa. Added CbmMuchDigitizerQa. --- macro/run/run_qa.C | 1 + reco/detectors/much/CMakeLists.txt | 4 +- reco/detectors/much/CbmMuchRecoLinkDef.h | 1 - sim/detectors/much/CMakeLists.txt | 3 + sim/detectors/much/CbmMuchSimLinkDef.h | 2 + sim/detectors/much/qa/CbmMuchDigitizerQa.cxx | 1012 +++++++++++++++++ sim/detectors/much/qa/CbmMuchDigitizerQa.h | 199 ++++ .../detectors/much/qa}/CbmMuchPointInfo.cxx | 0 .../detectors/much/qa}/CbmMuchPointInfo.h | 0 sim/detectors/much/qa/CbmMuchTransportQa.cxx | 473 ++++---- sim/detectors/much/qa/CbmMuchTransportQa.h | 62 +- 11 files changed, 1507 insertions(+), 250 deletions(-) create mode 100644 sim/detectors/much/qa/CbmMuchDigitizerQa.cxx create mode 100644 sim/detectors/much/qa/CbmMuchDigitizerQa.h rename {reco/detectors/much => sim/detectors/much/qa}/CbmMuchPointInfo.cxx (100%) rename {reco/detectors/much => sim/detectors/much/qa}/CbmMuchPointInfo.h (100%) diff --git a/macro/run/run_qa.C b/macro/run/run_qa.C index dffdca3721..3aa12ef371 100644 --- a/macro/run/run_qa.C +++ b/macro/run/run_qa.C @@ -157,6 +157,7 @@ void run_qa(Int_t nEvents = 0, if (CbmSetup::Instance()->IsActive(ECbmModuleId::kMuch)) { run->AddTask(new CbmMuchTransportQa()); + run->AddTask(new CbmMuchDigitizerQa()); } // ------------------------------------------------------------------------ diff --git a/reco/detectors/much/CMakeLists.txt b/reco/detectors/much/CMakeLists.txt index e9ef35f9ec..b900b0c7a0 100644 --- a/reco/detectors/much/CMakeLists.txt +++ b/reco/detectors/much/CMakeLists.txt @@ -4,6 +4,7 @@ ${CMAKE_CURRENT_SOURCE_DIR} ${CBMDETECTORBASE_DIR}/much ${CBMROOT_SOURCE_DIR}/reco/base +${CBMROOT_SOURCE_DIR}/sim/detectors/much/qa ${CBMBASE_DIR} @@ -33,7 +34,6 @@ set(SRCS CbmMuchFindHitsGem.cxx CbmMuchHitFinderQa.cxx CbmMuchHitProducerIdeal.cxx -CbmMuchPointInfo.cxx CbmMuchFindTracks.cxx CbmMuchMatchTracks.cxx @@ -43,7 +43,7 @@ CbmMuchTrackFinderIdeal.cxx set(LINKDEF CbmMuchRecoLinkDef.h) Set(LIBRARY_NAME CbmMuchReco) Set(DEPENDENCIES - CbmMuchBase CbmRecoBase CbmBase CbmData Base + CbmMuchBase CbmMuchSim CbmRecoBase CbmBase CbmData Base ) GENERATE_LIBRARY() diff --git a/reco/detectors/much/CbmMuchRecoLinkDef.h b/reco/detectors/much/CbmMuchRecoLinkDef.h index bb4cd67f13..e6c3fb6852 100644 --- a/reco/detectors/much/CbmMuchRecoLinkDef.h +++ b/reco/detectors/much/CbmMuchRecoLinkDef.h @@ -9,7 +9,6 @@ #pragma link C++ class CbmMuchHitFinderQa + ; #pragma link C++ class CbmMuchHitProducerIdeal + ; #pragma link C++ class CbmMuchMatchTracks + ; -#pragma link C++ class CbmMuchPointInfo + ; #pragma link C++ class CbmMuchTrackFinderIdeal + ; #endif diff --git a/sim/detectors/much/CMakeLists.txt b/sim/detectors/much/CMakeLists.txt index 3b2bb90cea..6c83a88aa2 100644 --- a/sim/detectors/much/CMakeLists.txt +++ b/sim/detectors/much/CMakeLists.txt @@ -9,6 +9,7 @@ ${CBMBASE_DIR} ${CBMBASE_DIR}/utils ${CBMROOT_SOURCE_DIR}/sim/transport/base +${CBMROOT_SOURCE_DIR}/core/data/base ${CBMROOT_SOURCE_DIR}/core/qa ${CBMDATA_DIR} @@ -40,6 +41,8 @@ CbmMuchReadoutBuffer.cxx CbmMuchSignal.cxx qa/CbmMuchTransportQa.cxx +qa/CbmMuchPointInfo.cxx +qa/CbmMuchDigitizerQa.cxx ) set(LINKDEF CbmMuchSimLinkDef.h) diff --git a/sim/detectors/much/CbmMuchSimLinkDef.h b/sim/detectors/much/CbmMuchSimLinkDef.h index f2b5951cf5..67b350f261 100644 --- a/sim/detectors/much/CbmMuchSimLinkDef.h +++ b/sim/detectors/much/CbmMuchSimLinkDef.h @@ -13,5 +13,7 @@ #pragma link C++ class CbmMuchReadoutBuffer + ; #pragma link C++ class CbmMuchSignal + ; #pragma link C++ class CbmMuchTransportQa + ; +#pragma link C++ class CbmMuchPointInfo + ; +#pragma link C++ class CbmMuchDigitizerQa + ; #endif diff --git a/sim/detectors/much/qa/CbmMuchDigitizerQa.cxx b/sim/detectors/much/qa/CbmMuchDigitizerQa.cxx new file mode 100644 index 0000000000..2df89e438c --- /dev/null +++ b/sim/detectors/much/qa/CbmMuchDigitizerQa.cxx @@ -0,0 +1,1012 @@ +/// \file CbmMuchDigitizerQa.cxx +/// \brief Implementation of the CbmMuchDigitizerQa class +/// \author Sergey Gorbunov <se.gorbunov@gsi.de> +/// \author Eugeny Kryshen +/// \author Vikas Singhal +/// \author Ekata Nandy +/// \author Dominik Smith +/// \date 21.10.2020 + +#include "CbmMuchDigitizerQa.h" +using std::cout; +using std::endl; +using std::vector; + +#define BINNING_CHARGE 100, 0, 300.0 +#define BINNING_LENGTH 100, 0, 2.5 +#define BINNING_CHARGE_LOG 100, 3, 10 +#define BINNING_ENERGY_LOG 100, -0.5, 4.5 +#define BINNING_ENERGY_LOG_EL 100, -0.5, 4.5 + +// ------------------------------------------------------------------------- +CbmMuchDigitizerQa::CbmMuchDigitizerQa(const char* name, Int_t verbose) + : FairTask(name, verbose) + , fGeoScheme(CbmMuchGeoScheme::Instance()) + , fDigiManager(CbmDigiManager::Instance()) + , fPointInfos(new TClonesArray("CbmMuchPointInfo", 10)) + , fOutFolder("MuchDigiQA", "MuchDigitizerQA") + , fvUsPadsFiredR() + , fvUsPadsFiredXY() + , fvMcPointCharge() + , fvPadsTotalR() + , fvPadsFiredR() + , fvPadOccupancyR() {} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +CbmMuchDigitizerQa::~CbmMuchDigitizerQa() { DeInit(); } +// ------------------------------------------------------------------------- + +void CbmMuchDigitizerQa::DeInit() { + for (int i = 0; i < fNstations; i++) { + delete fvUsPadsFiredR[i]; + delete fvUsPadsFiredXY[i]; + delete fvMcPointCharge[i]; + delete fvPadsTotalR[i]; + delete fvPadsFiredR[i]; + delete fvPadOccupancyR[i]; + } + fvUsPadsFiredR.clear(); + fvUsPadsFiredXY.clear(); + fvMcPointCharge.clear(); + fvPadsTotalR.clear(); + fvPadsFiredR.clear(); + fvPadOccupancyR.clear(); + + fNstations = 0; + fOutFolder.Clear(); +} + +// ------------------------------------------------------------------------- +InitStatus CbmMuchDigitizerQa::Init() { + + TDirectory* oldDirectory = gDirectory; + FairRootManager* fManager = FairRootManager::Instance(); + fMCTracks = (TClonesArray*) fManager->GetObject("MCTrack"); + fPoints = (TClonesArray*) fManager->GetObject("MuchPoint"); + // Reading Much Digis from CbmMuchDigiManager which are stored as vector + fDigiManager = CbmDigiManager::Instance(); + fDigiManager->Init(); + + histFolder = fOutFolder.AddFolder("hist", "Histogramms"); + fNstations = fGeoScheme->GetNStations(); + printf("Init: fNstations = %i\n", fNstations); + + //fVerbose = 3; + InitCounters(); + InitCanvases(); + InitChargeHistos(); + InitLengthHistos(); + InitPadHistos(); + FillTotalPadsHistos(); + InitChannelPadInfo(); + InitFits(); + + gDirectory = oldDirectory; + return kSUCCESS; +} + +void CbmMuchDigitizerQa::InitCounters() { + + fNall = new Int_t[fNstations]; + fNpr = new Int_t[fNstations]; + fNpi = new Int_t[fNstations]; + fNel = new Int_t[fNstations]; + fNmu = new Int_t[fNstations]; + fNka = new Int_t[fNstations]; + fNprimary = new Int_t[fNstations]; + fNsecondary = new Int_t[fNstations]; + + for (Int_t i = 0; i < fNstations; i++) { + fNall[i] = 0; + fNpr[i] = 0; + fNpi[i] = 0; + fNel[i] = 0; + fNmu[i] = 0; + fNka[i] = 0; + fNprimary[i] = 0; + fNsecondary[i] = 0; + } + fPointsTotal = 0; + fPointsUnderCounted = 0; + fPointsOverCounted = 0; +} + +void CbmMuchDigitizerQa::InitChannelPadInfo() { + + fPadMinLx = std::numeric_limits<Double_t>::max(); + fPadMinLy = std::numeric_limits<Double_t>::max(); + fPadMaxLx = std::numeric_limits<Double_t>::min(); + fPadMaxLy = std::numeric_limits<Double_t>::min(); + + if (fVerbose > 2) { + printf("=========================================================\n"); + printf(" Station Nr.\t| Sectors\t| Channels\t| Pad min size\t\t| Pad max" + "length\t \n"); + printf("---------------------------------------------------------\n"); + } + + Int_t nTotSectors = 0; + Int_t nTotChannels = 0; + for (Int_t iStation = 0; iStation < fNstations; iStation++) { + Int_t nChannels = GetNChannels(iStation); + Int_t nSectors = GetNSectors(iStation); + Double_t padMinLx = GetMinPadSize(iStation).X(); + Double_t padMinLy = GetMinPadSize(iStation).Y(); + Double_t padMaxLx = GetMaxPadSize(iStation).X(); + Double_t padMaxLy = GetMaxPadSize(iStation).Y(); + if (fPadMinLx > padMinLx) fPadMinLx = padMinLx; + if (fPadMinLy > padMinLy) fPadMinLy = padMinLy; + if (fPadMaxLx < padMaxLx) fPadMaxLx = padMaxLx; + if (fPadMaxLy < padMaxLy) fPadMaxLy = padMaxLy; + nTotSectors += nSectors; + nTotChannels += nChannels; + + if (fVerbose > 2) { + 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, + padMinLy, + padMaxLx, + padMaxLy); + printf("%i\t\t| %i\t\t\n", iStation + 1, nChannels); + } + } + printf("-----------------------------------------------------------\n"); + printf(" Total:\t\t| %i\t\t\n", nTotChannels); + printf("===========================================================\n"); +} + +void CbmMuchDigitizerQa::InitCanvases() { + + fCanvCharge = + new CbmQaCanvas("cMcPointCharge", "MC point charge", 2 * 800, 2 * 400); + fCanvCharge->Divide2D(3); + + fCanvStationCharge = new CbmQaCanvas( + "cMcPointChargeVsStation", "MC point charge per station", 2 * 800, 2 * 400); + fCanvStationCharge->Divide2D(fNstations); + + fCanvChargeVsEnergy = new CbmQaCanvas("cMcPointChargeVsEnergy", + "MC point charge vs particle Energy", + 2 * 800, + 2 * 400); + fCanvChargeVsEnergy->Divide2D(4); + + fCanvChargeVsLength = new CbmQaCanvas("cMcPointChargeVsLength", + "MC point charge vs track length", + 2 * 800, + 2 * 400); + fCanvChargeVsLength->Divide2D(4); + + fCanvTrackLength = + new CbmQaCanvas("cTrackLength", "track length", 2 * 800, 2 * 400); + fCanvTrackLength->Divide2D(4); + + fCanvNpadsVsArea = + new CbmQaCanvas("cNpadsVsArea", "N pads Vs Area", 2 * 800, 2 * 400); + + fCanvUsPadsFiredXY = new CbmQaCanvas( + "cPadsFiredXY", "Number of pads fired vs XY", 2 * 800, 2 * 400); + fCanvUsPadsFiredXY->Divide2D(fNstations); + + fCanvPadOccupancyR = new CbmQaCanvas( + "cPadOccupancyR", "Pad occupancy [%] vs radius", 2 * 800, 2 * 400); + fCanvPadOccupancyR->Divide2D(fNstations); + + fCanvPadsTotalR = + new CbmQaCanvas("cPadsTotalR", "Total pads vs radius", 2 * 800, 2 * 400); + fCanvPadsTotalR->Divide2D(fNstations); + + fOutFolder.Add(fCanvCharge); + fOutFolder.Add(fCanvStationCharge); + fOutFolder.Add(fCanvChargeVsEnergy); + fOutFolder.Add(fCanvChargeVsLength); + fOutFolder.Add(fCanvTrackLength); + fOutFolder.Add(fCanvNpadsVsArea); + fOutFolder.Add(fCanvUsPadsFiredXY); + fOutFolder.Add(fCanvPadOccupancyR); + fOutFolder.Add(fCanvPadsTotalR); +} + +void CbmMuchDigitizerQa::InitChargeHistos() { + + fhMcPointCharge = + new TH1F("hCharge", "Charge distribution from tracks", BINNING_CHARGE); + fhMcPointCharge->GetXaxis()->SetTitle("Charge [10^{4} electrons]"); + + fhMcPointChargeLog = new TH1F( + "hChargeLog", "Charge (log.) distribution from tracks", BINNING_CHARGE_LOG); + fhMcPointChargeLog->GetXaxis()->SetTitle("Charge [Lg(Number of electrons)]"); + + fhMcPointChargePr_1GeV_3mm = + new TH1F("hChargePr_1GeV_3mm", "Charge for 1 GeV protons", BINNING_CHARGE); + fhMcPointChargePr_1GeV_3mm->GetXaxis()->SetTitle("Charge [10^{4} electrons]"); + + fhMcPointChargeVsTrackEnergyLog = + new TH2F("hChargeEnergyLog", + "Charge vs energy (log.) for all tracks", + BINNING_ENERGY_LOG, + BINNING_CHARGE); + + fhMcPointChargeVsTrackEnergyLogPi = + new TH2F("hChargeEnergyLogPi", + "Charge vs energy (log.) for pions", + BINNING_ENERGY_LOG, + BINNING_CHARGE); + + fhMcPointChargeVsTrackEnergyLogPr = + new TH2F("hChargeEnergyLogPr", + "Charge vs energy (log.) for protons", + BINNING_ENERGY_LOG, + BINNING_CHARGE); + + fhMcPointChargeVsTrackEnergyLogEl = + new TH2F("hChargeEnergyLogEl", + "Charge vs energy (log.) for electrons", + BINNING_ENERGY_LOG_EL, + BINNING_CHARGE); + + fhMcPointChargeVsTrackLength = new TH2F("hChargeTrackLength", + "Charge vs length for all tracks", + BINNING_LENGTH, + BINNING_CHARGE); + + fhMcPointChargeVsTrackLengthPi = new TH2F("hChargeTrackLengthPi", + "Charge vs length for pions", + BINNING_LENGTH, + BINNING_CHARGE); + + fhMcPointChargeVsTrackLengthPr = new TH2F("hChargeTrackLengthPr", + "Charge vs length for proton", + BINNING_LENGTH, + BINNING_CHARGE); + + fhMcPointChargeVsTrackLengthEl = new TH2F("hChargeTrackLengthEl", + "Charge vs length for electrons", + BINNING_LENGTH, + BINNING_CHARGE); + std::vector<TH2F*> vChargeHistos; + vChargeHistos.push_back(fhMcPointChargeVsTrackEnergyLog); + vChargeHistos.push_back(fhMcPointChargeVsTrackEnergyLogPi); + vChargeHistos.push_back(fhMcPointChargeVsTrackEnergyLogPr); + vChargeHistos.push_back(fhMcPointChargeVsTrackEnergyLogEl); + vChargeHistos.push_back(fhMcPointChargeVsTrackLength); + vChargeHistos.push_back(fhMcPointChargeVsTrackLengthPi); + vChargeHistos.push_back(fhMcPointChargeVsTrackLengthPr); + vChargeHistos.push_back(fhMcPointChargeVsTrackLengthEl); + + for (UInt_t i = 0; i < vChargeHistos.size(); i++) { + TH2F* histo = vChargeHistos[i]; + histo->SetStats(0); + histo->GetYaxis()->SetDecimals(kTRUE); + histo->GetYaxis()->SetTitleOffset(1.4); + histo->GetYaxis()->CenterTitle(); + histo->GetYaxis()->SetTitle("Charge [10^{4} electrons]"); + if (i < 4) { + histo->GetXaxis()->SetTitle("Lg(E_{kin} [MeV])"); + } else { + histo->GetXaxis()->SetTitle("Track length [cm]"); + } + histFolder->Add(histo); + } +} + +void CbmMuchDigitizerQa::InitLengthHistos() { + + fhTrackLength = new TH1F("hTrackLength", "Track length", BINNING_LENGTH); + + fhTrackLengthPi = + new TH1F("hTrackLengthPi", "Track length for pions", BINNING_LENGTH); + + fhTrackLengthPr = + new TH1F("hTrackLengthPr", "Track length for protons", BINNING_LENGTH); + + fhTrackLengthEl = + new TH1F("hTrackLengthEl", "Track length for electrons", BINNING_LENGTH); + + std::vector<TH1F*> vLengthHistos; + vLengthHistos.push_back(fhTrackLength); + vLengthHistos.push_back(fhTrackLengthPi); + vLengthHistos.push_back(fhTrackLengthPr); + vLengthHistos.push_back(fhTrackLengthEl); + + for (UInt_t i = 0; i < vLengthHistos.size(); i++) { + TH1F* histo = vLengthHistos[i]; + histo->GetXaxis()->SetTitle("Track length [cm]"); + histFolder->Add(histo); + } +} + +void CbmMuchDigitizerQa::InitPadHistos() { + + fvMcPointCharge.resize(fNstations); + fvPadsTotalR.resize(fNstations); + fvUsPadsFiredR.resize(fNstations); + fvUsPadsFiredXY.resize(fNstations); + fvPadsFiredR.resize(fNstations); + fvPadOccupancyR.resize(fNstations); + + for (Int_t i = 0; i < fNstations; i++) { + CbmMuchStation* station = fGeoScheme->GetStation(i); + Double_t rMax = station->GetRmax(); + Double_t rMin = station->GetRmin(); + + fvMcPointCharge[i] = new TH1F( + Form("hMcPointCharge%i", i + 1), + Form("MC point charge : Station %i; Charge [10^4 e]; Count", i + 1), + BINNING_CHARGE); + + fvPadsTotalR[i] = + new TH1F(Form("hPadsTotal%i", i + 1), + Form("Number of pads vs radius: Station %i;Radius [cm]", i + 1), + 100, + 0.6 * rMin, + 1.2 * rMax); + + fvUsPadsFiredR[i] = new TH1F( + Form("hUsPadsFired%i", i + 1), + Form("Number of fired pads vs radius: Station %i;Radius [cm]", i + 1), + 100, + 0.6 * rMin, + 1.2 * rMax); + + fvUsPadsFiredXY[i] = + new TH2F(Form("hUsPadsFiredXY%i", i + 1), + Form("Pads fired XY : Station %i; X; Y", i + 1), + 100, + -1.2 * rMax, + 1.2 * rMax, + 100, + -1.2 * rMax, + 1.2 * rMax); + + fvPadsFiredR[i] = new TH1F( + Form("hPadsFired%i", i + 1), + Form("Number of fired pads vs radius: Station %i;Radius [cm]", i + 1), + 100, + 0.6 * rMin, + 1.2 * rMax); + + fvPadOccupancyR[i] = new TH1F( + Form("hOccupancy%i", i + 1), + Form("Pad occupancy vs radius: Station %i;Radius [cm];Occupancy, %%", + i + 1), + 100, + 0.6 * rMin, + 1.2 * rMax); + + histFolder->Add(fvMcPointCharge[i]); + histFolder->Add(fvPadsTotalR[i]); + histFolder->Add(fvUsPadsFiredXY[i]); + histFolder->Add(fvPadsFiredR[i]); + histFolder->Add(fvPadOccupancyR[i]); + } + fhNpadsVsS = new TH2F("hNpadsVsS", + "Number of fired pads vs pad area:area:n pads", + 10, + -5, + 0, + 10, + 0.5, + 10.5); + histFolder->Add(fhNpadsVsS); +} + +void CbmMuchDigitizerQa::FillTotalPadsHistos() { + + vector<CbmMuchModule*> modules = fGeoScheme->GetModules(); + for (vector<CbmMuchModule*>::iterator im = modules.begin(); + im != modules.end(); + im++) { + CbmMuchModule* mod = (*im); + if (mod->GetDetectorType() == 4 + || mod->GetDetectorType() == 3) { // modified for rpc + CbmMuchModuleGem* module = (CbmMuchModuleGem*) mod; + vector<CbmMuchPad*> pads = module->GetPads(); + for (UInt_t ip = 0; ip < pads.size(); ip++) { + CbmMuchPad* pad = pads[ip]; + Int_t stationId = CbmMuchAddress::GetStationIndex(pad->GetAddress()); + Double_t x0 = pad->GetX(); + Double_t y0 = pad->GetY(); + Double_t r0 = TMath::Sqrt(x0 * x0 + y0 * y0); + fvPadsTotalR[stationId]->Fill(r0); + } + } + } + + Double_t errors[100]; + for (Int_t i = 0; i < 100; i++) { + errors[i] = 0; + } + for (Int_t i = 0; i < fNstations; i++) { + //fvPadsTotalR[i]->Sumw2(); + fvPadsTotalR[i]->SetError(errors); + } +} + +void CbmMuchDigitizerQa::InitFits() { + + fFitEl = new TF1("fit_el", LandauMPV, -0.5, 4.5, 1); + fFitEl->SetParameter(0, 0.511); + fFitEl->SetLineWidth(2); + fFitEl->SetLineColor(kBlack); + + fFitPi = new TF1("fit_pi", LandauMPV, -0.5, 4.5, 1); + fFitPi->SetParameter(0, 139.57); + fFitPi->SetLineWidth(2); + fFitPi->SetLineColor(kBlack); + + fFitPr = new TF1("fit_pr", LandauMPV, -0.5, 4.5, 1); + fFitPr->SetParameter(0, 938.27); + fFitPr->SetLineWidth(2); + fFitPr->SetLineColor(kBlack); +} + +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +void CbmMuchDigitizerQa::SetParContainers() { + // Get run and runtime database + + // The code currently does not work, + // CbmMuchGeoScheme::Instance() must be initialised outside. + // - Sergey + + // FairRuntimeDb* db = FairRuntimeDb::instance(); + // if ( ! db ) Fatal("SetParContainers", "No runtime database"); + // Get MUCH geometry parameter container + // CbmGeoMuchPar *fGeoPar = (CbmGeoMuchPar*) + // db->getContainer("CbmGeoMuchPar"); TObjArray *stations = + // fGeoPar->GetStations(); cout<<"\n\n SG: stations: + // "<<stations->GetEntriesFast()<<endl; + // TString geoTag; + // CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kMuch, geoTag); + // bool mcbmFlag = geoTag.Contains("mcbm", TString::kIgnoreCase); + // CbmMuchGeoScheme::Instance()->Init(stations, mcbmFlag); +} +// ------------------------------------------------------------------------- + +// -------------------------------------------------------------------------x +void CbmMuchDigitizerQa::Exec(Option_t*) { + + fNevents++; + LOG(info) << "Event: " << fNevents; + TDirectory* oldDirectory = gDirectory; + + OccupancyQa(); + DigitizerQa(); + DrawCanvases(); + if (fVerbose > 1) { + PrintFrontLayerPoints(); + PrintFrontLayerDigis(); + } + gDirectory = oldDirectory; + return; +} +// ------------------------------------------------------------------------- + +void CbmMuchDigitizerQa::PrintFrontLayerPoints() { + for (int i = 0; i < fPoints->GetEntriesFast(); i++) { + CbmMuchPoint* point = (CbmMuchPoint*) fPoints->At(i); + Int_t stId = CbmMuchAddress::GetStationIndex(point->GetDetectorID()); + if (stId != 0) continue; + Int_t layerId = CbmMuchAddress::GetLayerIndex(point->GetDetectorID()); + if (layerId != 0) continue; + printf("point %4i xin=%6.2f yin=%6.2f xout=%6.2f yout=%6.2f zin=%6.2f\n", + i, + point->GetXIn(), + point->GetYIn(), + point->GetXOut(), + point->GetYOut(), + point->GetZIn()); + } +} +// ------------------------------------------------------------------------- + +void CbmMuchDigitizerQa::PrintFrontLayerDigis() { + for (Int_t i = 0; i < fDigiManager->GetNofDigis(ECbmModuleId::kMuch); i++) { + CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(i); + UInt_t address = digi->GetAddress(); + Int_t stId = CbmMuchAddress::GetStationIndex(address); + if (stId != 0) continue; + Int_t layerId = CbmMuchAddress::GetLayerIndex(address); + if (layerId != 0) continue; + CbmMuchModuleGem* module = + (CbmMuchModuleGem*) fGeoScheme->GetModuleByDetId(address); + if (!module) continue; + CbmMuchPad* pad = module->GetPad(address); + Double_t x0 = pad->GetX(); + Double_t y0 = pad->GetY(); + UInt_t charge = digi->GetAdc(); + printf("digi %4i x0=%5.1f y0=%5.1f charge=%3i\n", i, x0, y0, charge); + } +} +// ------------------------------------------------------------------------- + +void CbmMuchDigitizerQa::DrawCanvases() { + + fCanvCharge->cd(1); + fhMcPointCharge->DrawCopy("", ""); + fCanvCharge->cd(2); + fhMcPointChargeLog->DrawCopy("", ""); + fCanvCharge->cd(3); + fhMcPointChargePr_1GeV_3mm->DrawCopy("", ""); + + for (Int_t i = 0; i < 4; i++) { + fCanvTrackLength->cd(i + 1); + gPad->SetLogy(); + gStyle->SetOptStat(1110); + } + fCanvTrackLength->cd(1); + fhTrackLength->DrawCopy("", ""); + fCanvTrackLength->cd(2); + fhTrackLengthPi->DrawCopy("", ""); + fCanvTrackLength->cd(3); + fhTrackLengthPr->DrawCopy("", ""); + fCanvTrackLength->cd(4); + fhTrackLengthEl->DrawCopy("", ""); + + for (Int_t i = 0; i < 4; i++) { + fCanvChargeVsEnergy->cd(i + 1); + gPad->Range(0, 0, 200, 200); + gPad->SetBottomMargin(0.11); + gPad->SetRightMargin(0.14); + gPad->SetLeftMargin(0.12); + gPad->SetLogz(); + } + fCanvChargeVsEnergy->cd(1); + fhMcPointChargeVsTrackEnergyLog->DrawCopy("colz", ""); + fCanvChargeVsEnergy->cd(2); + fhMcPointChargeVsTrackEnergyLogPi->DrawCopy("colz", ""); + fFitPi->DrawCopy("same"); + fCanvChargeVsEnergy->cd(3); + fhMcPointChargeVsTrackEnergyLogPr->DrawCopy("colz", ""); + fFitPr->DrawCopy("same"); + fCanvChargeVsEnergy->cd(4); + fhMcPointChargeVsTrackEnergyLogEl->DrawCopy("colz", ""); + fFitEl->DrawCopy("same"); + + for (Int_t i = 0; i < 4; i++) { + fCanvChargeVsLength->cd(i + 1); + gPad->Range(0, 0, 200, 200); + gPad->SetBottomMargin(0.11); + gPad->SetRightMargin(0.14); + gPad->SetLeftMargin(0.12); + gPad->SetLogz(); + } + fCanvChargeVsLength->cd(1); + fhMcPointChargeVsTrackLength->DrawCopy("colz", ""); + fCanvChargeVsLength->cd(2); + fhMcPointChargeVsTrackLengthPi->DrawCopy("colz", ""); + fCanvChargeVsLength->cd(3); + fhMcPointChargeVsTrackLengthPr->DrawCopy("colz", ""); + fCanvChargeVsLength->cd(4); + fhMcPointChargeVsTrackLengthEl->DrawCopy("colz", ""); + + for (Int_t i = 0; i < fNstations; i++) { + *fvPadsFiredR[i] = *fvUsPadsFiredR[i]; + //fvPadsFiredR[i]->Sumw2(); + fvPadsFiredR[i]->Scale(1. / fNevents); + fvPadOccupancyR[i]->Divide(fvPadsFiredR[i], fvPadsTotalR[i]); + fvPadOccupancyR[i]->Scale(100.); + + fCanvStationCharge->cd(i + 1); + fvMcPointCharge[i]->DrawCopy("", ""); + fCanvPadOccupancyR->cd(i + 1); + fvPadOccupancyR[i]->DrawCopy("", ""); + fCanvPadsTotalR->cd(i + 1); + fvPadsTotalR[i]->DrawCopy("", ""); + fCanvUsPadsFiredXY->cd(i + 1); + fvUsPadsFiredXY[i]->DrawCopy("colz", ""); + } + fCanvNpadsVsArea->cd(); + fhNpadsVsS->DrawCopy("colz", ""); +} + +// ------------------------------------------------------------------------- +void CbmMuchDigitizerQa::FinishTask() { + + printf("FinishTask\n"); + cout << "\n\n SG: Finish task!" << endl; + + TDirectory* oldDirectory = gDirectory; + bool oldBatchMode = gROOT->IsBatch(); + + if (!FairRootManager::Instance() || !FairRootManager::Instance()->GetSink()) { + cout << "No sink found" << endl; + return; + } + // gROOT->SetBatch(kTRUE); + gROOT->SetBatch(kFALSE); + gStyle->SetPaperSize(20, 20); + + if (fVerbose > 1) { + OutputNvsS(); + PrintCounters(); + } + FairSink* sink = FairRootManager::Instance()->GetSink(); + sink->WriteObject(&fOutFolder, nullptr); + gDirectory = oldDirectory; + gROOT->SetBatch(oldBatchMode); +} +// ------------------------------------------------------------------------- + +void CbmMuchDigitizerQa::OutputNvsS() { + TCanvas* c = new TCanvas("nMeanVsS", "nMeanVsS", 2 * 800, 2 * 400); + printf("===================================\n"); + printf("DigitizerQa:\n"); + + Double_t nMean[11]; + Double_t s[11]; + for (Int_t iS = 1; iS <= 10; iS++) { + nMean[iS] = 0; + s[iS] = -5.25 + 0.5 * iS; + Double_t total = 0; + for (Int_t iN = 1; iN <= 10; iN++) { + nMean[iS] += iN * fhNpadsVsS->GetBinContent(iS, iN); + total += fhNpadsVsS->GetBinContent(iS, iN); + } + if (total > 0) nMean[iS] /= total; + printf("%f %f\n", s[iS], nMean[iS]); + } + c->cd(); + + TGraph* gNvsS = new TGraph(11, s, nMean); + //gNvsS->SetLineColor(2); + //gNvsS->SetLineWidth(4); + gNvsS->SetMarkerColor(4); + gNvsS->SetMarkerSize(1.5); + gNvsS->SetMarkerStyle(21); + gNvsS->SetTitle("nMeanVsS"); + gNvsS->GetYaxis()->SetTitle("nMean"); + gNvsS->GetYaxis()->SetTitle("nMean"); + //gNvsS->DrawClone("ALP"); + gNvsS->DrawClone("AP"); + fOutFolder.Add(c); +} + +void CbmMuchDigitizerQa::PrintCounters() { + + printf("All tracks: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNall[i]); + printf("\n"); + printf("------------;"); + for (Int_t i = 0; i < fNstations; i++) + printf("---------"); + printf("\n"); + printf("Primary: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNprimary[i]); + printf("\n"); + printf("Secondary: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNsecondary[i]); + printf("\n"); + printf("-------------"); + for (Int_t i = 0; i < fNstations; i++) + printf("---------"); + printf("\n"); + printf("Protons: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNpr[i]); + printf("\n"); + printf("Pions: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNpi[i]); + printf("\n"); + printf("Electrons: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNel[i]); + printf("\n"); + printf("Muons: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNmu[i]); + printf("\n"); + printf("Kaons: ;"); + for (Int_t i = 0; i < fNstations; i++) + printf("%8i;", fNka[i]); + printf("\n"); +} + +// ------------------------------------------------------------------------- +Double_t CbmMuchDigitizerQa::LandauMPV(Double_t* lg_x, Double_t* par) { + Double_t gaz_gain_mean = 1.7e+4; + Double_t scale = 1.e+6; + gaz_gain_mean /= scale; + Double_t mass = par[0]; // mass in MeV + Double_t x = TMath::Power(10, lg_x[0]); + return gaz_gain_mean * MPV_n_e(x, mass); +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +void CbmMuchDigitizerQa::DigitizerQa() { + TVector3 vIn; // in position of the track + TVector3 vOut; // out position of the track + TVector3 p; // track momentum + fPointInfos->Clear(); + + for (Int_t i = 0; i < fPoints->GetEntriesFast(); i++) { + CbmMuchPoint* point = (CbmMuchPoint*) fPoints->At(i); + Int_t stId = CbmMuchAddress::GetStationIndex(point->GetDetectorID()); + + // Check if the point corresponds to a certain MC Track + Int_t trackId = point->GetTrackID(); + if (trackId < 0) { + new ((*fPointInfos)[i]) CbmMuchPointInfo(0, 0, 0, 0, 0); + continue; + } + CbmMCTrack* mcTrack = (CbmMCTrack*) fMCTracks->At(trackId); + if (!mcTrack) { + new ((*fPointInfos)[i]) CbmMuchPointInfo(0, 0, 0, 0, 0); + continue; + } + + Int_t motherId = mcTrack->GetMotherId(); + Int_t pdgCode = mcTrack->GetPdgCode(); + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(pdgCode); + if (!particle || pdgCode == 22 || // photons + pdgCode == 2112) // neutrons + { + new ((*fPointInfos)[i]) CbmMuchPointInfo(0, 0, 0, 0, 0); + continue; + } + + if (CbmMuchAddress::GetLayerIndex(point->GetDetectorID()) == 0) { + UpdateParticleCounters(stId, pdgCode, motherId); + } + + Double_t mass = particle->Mass(); + point->PositionIn(vIn); + point->PositionOut(vOut); + point->Momentum(p); + Double_t length = (vOut - vIn).Mag(); // Track length + Double_t kine = sqrt(p.Mag2() + mass * mass) - mass; // Kinetic energy + // Get mother pdg code + Int_t motherPdg = 0; + CbmMCTrack* motherTrack = NULL; + if (motherId != -1) motherTrack = (CbmMCTrack*) fMCTracks->At(motherId); + if (motherTrack) motherPdg = motherTrack->GetPdgCode(); + new ((*fPointInfos)[i]) + CbmMuchPointInfo(pdgCode, motherPdg, kine, length, stId); + } + FillChargePerPoint(); + FillDigitizerPerformancePlots(); +} +// ------------------------------------------------------------------------- + +void CbmMuchDigitizerQa::UpdateParticleCounters(Int_t stId, + Int_t pdgCode, + Int_t motherId) { + + fNall[stId]++; + if (pdgCode == 2212) + fNpr[stId]++; + else if (pdgCode == -211 || pdgCode == 211) + fNpi[stId]++; + else if (pdgCode == -11 || pdgCode == 11) + fNel[stId]++; + else if (pdgCode == -13 || pdgCode == 13) + fNmu[stId]++; + else if (pdgCode == -321 || pdgCode == 321) + fNka[stId]++; + + if (motherId == -1) + fNprimary[stId]++; + else + fNsecondary[stId]++; +} + +void CbmMuchDigitizerQa::FillChargePerPoint() { + for (Int_t i = 0; i < fDigiManager->GetNofDigis(ECbmModuleId::kMuch); i++) { + CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(i); + assert(digi); + CbmMatch* match = + (CbmMatch*) fDigiManager->GetMatch(ECbmModuleId::kMuch, i); + assert(match); + CbmMuchModule* module = fGeoScheme->GetModuleByDetId(digi->GetAddress()); + assert(module); + if (!module) continue; + Double_t area = 0; + if (module->GetDetectorType() != 4 && module->GetDetectorType() != 3) + continue; /// rpc + LOG(debug) << GetName() << " Processing MuchDigi " << i << " at address " + << digi->GetAddress() << " Module number " + << module->GetDetectorType(); + + CbmMuchModuleGem* module1 = (CbmMuchModuleGem*) module; + assert(module1); + CbmMuchPad* pad = module1->GetPad(digi->GetAddress()); + assert(pad); + area = pad->GetDx() * pad->GetDy(); + Int_t nofLinks = match->GetNofLinks(); + for (Int_t pt = 0; pt < nofLinks; pt++) { + Int_t pointId = match->GetLink(pt).GetIndex(); + Int_t charge = match->GetLink(pt).GetWeight(); + CbmMuchPointInfo* info = (CbmMuchPointInfo*) fPointInfos->At(pointId); + if (info->GetPdgCode() == 0) continue; + info->AddCharge(charge); + info->AddArea(area); + } + } +} + +void CbmMuchDigitizerQa::FillDigitizerPerformancePlots() { + Bool_t verbose = (fVerbose > 2); + for (Int_t i = 0; i < fPointInfos->GetEntriesFast(); i++) { + CbmMuchPointInfo* info = (CbmMuchPointInfo*) fPointInfos->At(i); + if (verbose) { + printf("%i", i); + info->Print(); + } + Double_t length = info->GetLength(); + Double_t kine = 1000 * (info->GetKine()); + Double_t charge = info->GetCharge(); + Int_t pdg = info->GetPdgCode(); + if (pdg == 0) continue; + if (charge <= 0) continue; + Double_t log_kine = TMath::Log10(kine); + Double_t log_charge = TMath::Log10(charge); + charge = charge / 1.e+4; // measure charge in 10^4 electrons + + Int_t nPads = info->GetNPads(); + Double_t area = info->GetArea() / nPads; + // printf("%f %i\n",TMath::Log2(area),nPads); + fhNpadsVsS->Fill(TMath::Log2(area), nPads); + fhMcPointCharge->Fill(charge); + fvMcPointCharge[info->GetStationId()]->Fill(charge); + fhMcPointChargeLog->Fill(log_charge); + fhMcPointChargeVsTrackEnergyLog->Fill(log_kine, charge); + fhMcPointChargeVsTrackLength->Fill(length, charge); + fhTrackLength->Fill(length); + + if (pdg == 2212) { + fhMcPointChargeVsTrackEnergyLogPr->Fill(log_kine, charge); + fhMcPointChargeVsTrackLengthPr->Fill(length, charge); + fhTrackLengthPr->Fill(length); + } else if (pdg == 211 || pdg == -211) { + fhMcPointChargeVsTrackEnergyLogPi->Fill(log_kine, charge); + fhMcPointChargeVsTrackLengthPi->Fill(length, charge); + fhTrackLengthPi->Fill(length); + } else if (pdg == 11 || pdg == -11) { + fhMcPointChargeVsTrackEnergyLogEl->Fill(log_kine, charge); + fhMcPointChargeVsTrackLengthEl->Fill(length, charge); + fhTrackLengthEl->Fill(length); + } + if (pdg == 2212 && length > 0.3 && length < 0.32 && kine > 1000 + && kine < 1020) + fhMcPointChargePr_1GeV_3mm->Fill(charge); + } +} + +// ------------------------------------------------------------------------- +void CbmMuchDigitizerQa::OccupancyQa() { + // Filling occupancy plots + for (Int_t i = 0; i < fDigiManager->GetNofDigis(ECbmModuleId::kMuch); i++) { + CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(i); + assert(digi); + UInt_t address = digi->GetAddress(); + CbmMuchModule* module = fGeoScheme->GetModuleByDetId(address); + if (!module) continue; + Double_t r0 = 0; + if (module->GetDetectorType() != 4 && module->GetDetectorType() != 3) + continue; + CbmMuchModuleGem* module1 = (CbmMuchModuleGem*) module; + CbmMuchPad* pad = module1->GetPad( + address); // fGeoScheme->GetPadByDetId(detectorId, channelId); + assert(pad); + Double_t x0 = pad->GetX(); + Double_t y0 = pad->GetY(); + r0 = TMath::Sqrt(x0 * x0 + y0 * y0); + fvUsPadsFiredR[CbmMuchAddress::GetStationIndex(address)]->Fill(r0); + fvUsPadsFiredXY[CbmMuchAddress::GetStationIndex(address)]->Fill(x0, y0); + } +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +Int_t CbmMuchDigitizerQa::GetNChannels(Int_t iStation) { + Int_t nChannels = 0; + vector<CbmMuchModule*> modules = fGeoScheme->GetModules(iStation); + for (UInt_t im = 0; im < modules.size(); im++) { + CbmMuchModule* mod = modules[im]; + if (mod->GetDetectorType() != 4 && mod->GetDetectorType() != 3) continue; + CbmMuchModuleGem* module = (CbmMuchModuleGem*) mod; + if (!module) continue; + nChannels += module->GetNPads(); + } + return nChannels; +} + +// ------------------------------------------------------------------------- +Int_t CbmMuchDigitizerQa::GetNSectors(Int_t iStation) { + Int_t nSectors = 0; + vector<CbmMuchModule*> modules = fGeoScheme->GetModules(iStation); + for (UInt_t im = 0; im < modules.size(); im++) { + CbmMuchModule* mod = modules[im]; + if (mod->GetDetectorType() != 4 && mod->GetDetectorType() != 3) continue; + CbmMuchModuleGem* module = (CbmMuchModuleGem*) mod; + if (!module) continue; + nSectors += module->GetNSectors(); + } + return nSectors; +} + +// ------------------------------------------------------------------------- +TVector2 CbmMuchDigitizerQa::GetMinPadSize(Int_t iStation) { + Double_t padMinLx = std::numeric_limits<Double_t>::max(); + Double_t padMinLy = std::numeric_limits<Double_t>::max(); + vector<CbmMuchModule*> modules = fGeoScheme->GetModules(iStation); + for (UInt_t im = 0; im < modules.size(); im++) { + CbmMuchModule* mod = modules[im]; + if (mod->GetDetectorType() != 1) continue; + CbmMuchModuleGem* module = (CbmMuchModuleGem*) mod; + vector<CbmMuchPad*> pads = module->GetPads(); + for (UInt_t ip = 0; ip < pads.size(); ip++) { + CbmMuchPad* pad = pads[ip]; + if (pad->GetDx() < padMinLx) padMinLx = pad->GetDx(); + if (pad->GetDy() < padMinLy) padMinLy = pad->GetDy(); + } + } + return TVector2(padMinLx, padMinLy); +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +TVector2 CbmMuchDigitizerQa::GetMaxPadSize(Int_t iStation) { + Double_t padMaxLx = std::numeric_limits<Double_t>::min(); + Double_t padMaxLy = std::numeric_limits<Double_t>::min(); + vector<CbmMuchModule*> modules = fGeoScheme->GetModules(iStation); + for (UInt_t im = 0; im < modules.size(); im++) { + CbmMuchModule* mod = modules[im]; + if (mod->GetDetectorType() != 1) continue; + CbmMuchModuleGem* module = (CbmMuchModuleGem*) mod; + vector<CbmMuchPad*> pads = module->GetPads(); + for (UInt_t ip = 0; ip < pads.size(); ip++) { + CbmMuchPad* pad = pads[ip]; + if (pad->GetDx() > padMaxLx) padMaxLx = pad->GetDx(); + if (pad->GetDy() > padMaxLy) padMaxLy = pad->GetDy(); + } + } + return TVector2(padMaxLx, padMaxLy); +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +Double_t CbmMuchDigitizerQa::MPV_n_e(Double_t Tkin, Double_t mass) { + Double_t logT; + TF1 fPol6("fPol6", "pol6", -5, 10); + if (mass < 0.1) { + logT = log(Tkin * 0.511 / mass); + if (logT > 9.21034) logT = 9.21034; + if (logT < min_logT_e) logT = min_logT_e; + return fPol6.EvalPar(&logT, mpv_e); + } else if (mass >= 0.1 && mass < 0.2) { + logT = log(Tkin * 105.658 / mass); + if (logT > 9.21034) logT = 9.21034; + if (logT < min_logT_mu) logT = min_logT_mu; + return fPol6.EvalPar(&logT, mpv_mu); + } else { + logT = log(Tkin * 938.272 / mass); + if (logT > 9.21034) logT = 9.21034; + if (logT < min_logT_p) logT = min_logT_p; + return fPol6.EvalPar(&logT, mpv_p); + } +} + +void CbmMuchDigitizerQa::DivideCanvas2D(TCanvas* c, int nPads) { + // divide canvas into nPads in 2D + if (!c || nPads < 1) { return; } + int rows = (int) sqrt(nPads); + int cols = nPads / rows; + if (cols * rows < nPads) { cols++; } + c->Divide(cols, rows); +} + +// ------------------------------------------------------------------------- + +ClassImp(CbmMuchDigitizerQa) diff --git a/sim/detectors/much/qa/CbmMuchDigitizerQa.h b/sim/detectors/much/qa/CbmMuchDigitizerQa.h new file mode 100644 index 0000000000..aad04643d6 --- /dev/null +++ b/sim/detectors/much/qa/CbmMuchDigitizerQa.h @@ -0,0 +1,199 @@ +/// \file CbmMuchDigitizerQa.h +/// \brief Definition of the CbmMuchDigitizerQa class +/// \author Sergey Gorbunov <se.gorbunov@gsi.de> +/// \author Eugeny Kryshen +/// \author Vikas Singhal +/// \author Ekata Nandy +/// \date 25.09.2020 + +#ifndef CbmMuchDigitizerQa_H +#define CbmMuchDigitizerQa_H + +#include "CbmDigiManager.h" +#include "CbmGeoMuchPar.h" +#include "CbmMCTrack.h" +#include "CbmMatch.h" +#include "CbmMuchAddress.h" +#include "CbmMuchDigi.h" +#include "CbmMuchGeoScheme.h" +#include "CbmMuchModuleGem.h" +#include "CbmMuchPad.h" +#include "CbmMuchPoint.h" +#include "CbmMuchPointInfo.h" +#include "CbmMuchRecoDefs.h" +#include "CbmMuchSector.h" +#include "CbmMuchStation.h" +#include "CbmQaCanvas.h" +#include "FairLogger.h" +#include "FairRootFileSink.h" +#include "FairRootManager.h" +#include "FairRun.h" +#include "FairRuntimeDb.h" +#include "FairTask.h" +#include "Riostream.h" +#include "TArrayI.h" +#include "TCanvas.h" +#include "TClonesArray.h" +#include "TDatabasePDG.h" +#include "TF1.h" +#include "TFile.h" +#include "TGraph.h" +#include "TH1.h" +#include "TH2.h" +#include "TObjArray.h" +#include "TParticlePDG.h" +#include "TString.h" +#include "TStyle.h" +#include <algorithm> +#include <cassert> +#include <map> +#include <vector> + +class CbmMuchGeoScheme; + +/// QA for the MUCH detector after a "digitization" step of the simulation. +/// The class reimplements corresponding QA checks from old CbmMuchHitFinderQa class +/// made by E. Kryshen & V. Singhal & E. Nandy +/// +class CbmMuchDigitizerQa : public FairTask { + +public: + CbmMuchDigitizerQa(const char* name = "MuchHitFinderQa", Int_t verbose = 1); + virtual ~CbmMuchDigitizerQa(); + virtual InitStatus Init(); + virtual void Exec(Option_t* option); + virtual void FinishTask(); + virtual void SetParContainers(); + static void DivideCanvas2D(TCanvas* c, int nPads); + +protected: + /* DigitizerQa - analysis of digitizer performance - charge distributions + * for tracks. Track length distrivutions. Statistics on particle types + */ + void DigitizerQa(); + + /* Occupance analysis - all pads,fired pads, + * and fired/all distributions as functions of radius + */ + void OccupancyQa(); + +private: + Int_t GetNChannels(Int_t iStation); + Int_t GetNSectors(Int_t iStation); + TVector2 GetMinPadSize(Int_t iStation); + TVector2 GetMaxPadSize(Int_t iStation); + static Double_t LandauMPV(Double_t* x, Double_t* par); + static Double_t MPV_n_e(Double_t Tkin, Double_t mass); + + CbmMuchDigitizerQa(const CbmMuchDigitizerQa&); + CbmMuchDigitizerQa& operator=(const CbmMuchDigitizerQa&); + + TFolder* histFolder; + void InitCounters(); + void InitCanvases(); + void InitChargeHistos(); + void InitLengthHistos(); + void InitPadHistos(); + void InitChannelPadInfo(); + void InitFits(); + void DeInit(); + + void FillTotalPadsHistos(); + void DrawCanvases(); + void PrintCounters(); + void OutputNvsS(); + + void UpdateParticleCounters(Int_t stId, Int_t pdgCode, Int_t motherId); + void FillChargePerPoint(); + void FillDigitizerPerformancePlots(); + + void PrintFrontLayerPoints(); + void PrintFrontLayerDigis(); + + // geometry + CbmMuchGeoScheme* fGeoScheme = nullptr; + Int_t fNstations = 0; + CbmDigiManager* fDigiManager = nullptr; + + // containers + TClonesArray* fPoints = nullptr; + TClonesArray* fDigis = nullptr; + TClonesArray* fDigiMatches = nullptr; + TClonesArray* fMCTracks = nullptr; + TClonesArray* fPointInfos = nullptr; /// temporary additional information + + TFolder fOutFolder; /// output folder with histos and canvases + Int_t fNevents = 0; /// number of processed events + + // internal unscaled histograms, need to be scaled at the output + std::vector<TH1F*> fvUsPadsFiredR; // fired pads vs R, per station + std::vector<TH2F*> fvUsPadsFiredXY; // fired pads vs XY, per station + + // output histograms + TH1F* fhMcPointCharge = nullptr; /// MC point charge + TH1F* fhMcPointChargeLog = nullptr; /// MC point charge log scale + TH1F* fhMcPointChargePr_1GeV_3mm = + nullptr; /// MC point charge for selected protons + + TH1F* fhTrackLength = nullptr; + TH1F* fhTrackLengthPi = nullptr; + TH1F* fhTrackLengthPr = nullptr; + TH1F* fhTrackLengthEl = nullptr; + + TH2F* fhMcPointChargeVsTrackEnergyLog = nullptr; + TH2F* fhMcPointChargeVsTrackEnergyLogPi = nullptr; + TH2F* fhMcPointChargeVsTrackEnergyLogPr = nullptr; + TH2F* fhMcPointChargeVsTrackEnergyLogEl = nullptr; + TH2F* fhMcPointChargeVsTrackLength = nullptr; + TH2F* fhMcPointChargeVsTrackLengthPi = nullptr; + TH2F* fhMcPointChargeVsTrackLengthPr = nullptr; + TH2F* fhMcPointChargeVsTrackLengthEl = nullptr; + TH2F* fhNpadsVsS = nullptr; + + std::vector<TH1F*> fvMcPointCharge; // MC point charge per station + std::vector<TH1F*> fvPadsTotalR; // number of pads vs R, per station + std::vector<TH1F*> fvPadsFiredR; // fired pads vs R, per station + std::vector<TH1F*> fvPadOccupancyR; // pad occupancy vs R, per station + + // output canvaces with histogramm collections + CbmQaCanvas* fCanvCharge = nullptr; + CbmQaCanvas* fCanvStationCharge = nullptr; + CbmQaCanvas* fCanvChargeVsEnergy = nullptr; + CbmQaCanvas* fCanvChargeVsLength = nullptr; + CbmQaCanvas* fCanvTrackLength = nullptr; + CbmQaCanvas* fCanvNpadsVsArea = nullptr; + CbmQaCanvas* fCanvUsPadsFiredXY = nullptr; + CbmQaCanvas* fCanvPadOccupancyR = nullptr; + CbmQaCanvas* fCanvPadsTotalR = nullptr; + + TF1* fFitEl = nullptr; + TF1* fFitPi = nullptr; + TF1* fFitPr = nullptr; + + Int_t fSignalPoints = 0; // Number of signal MC points + Int_t fnPadSizesX = 0; + Int_t fnPadSizesY = 0; + + Int_t* fNall = nullptr; // number of all tracks at the first station + Int_t* fNpr = nullptr; // number of protons at the first station + Int_t* fNpi = nullptr; // number of pions at the first station + Int_t* fNel = nullptr; // number of electrons at the first station + Int_t* fNmu = nullptr; // number of muons at the first station + Int_t* fNka = nullptr; // number of kaons at the first station + Int_t* fNprimary = nullptr; // number of primary tracks at the first station + Int_t* fNsecondary = + nullptr; // number of secondary tracks at the first station + + Int_t fPointsTotal = 0; + Int_t fPointsUnderCounted = 0; + Int_t fPointsOverCounted = 0; + + Double_t fPadMinLx = 0.; + Double_t fPadMinLy = 0.; + Double_t fPadMaxLx = 0.; + Double_t fPadMaxLy = 0.; + + ClassDef(CbmMuchDigitizerQa, 0) +}; + +#endif diff --git a/reco/detectors/much/CbmMuchPointInfo.cxx b/sim/detectors/much/qa/CbmMuchPointInfo.cxx similarity index 100% rename from reco/detectors/much/CbmMuchPointInfo.cxx rename to sim/detectors/much/qa/CbmMuchPointInfo.cxx diff --git a/reco/detectors/much/CbmMuchPointInfo.h b/sim/detectors/much/qa/CbmMuchPointInfo.h similarity index 100% rename from reco/detectors/much/CbmMuchPointInfo.h rename to sim/detectors/much/qa/CbmMuchPointInfo.h diff --git a/sim/detectors/much/qa/CbmMuchTransportQa.cxx b/sim/detectors/much/qa/CbmMuchTransportQa.cxx index 772ea6349a..1db69c4ca2 100644 --- a/sim/detectors/much/qa/CbmMuchTransportQa.cxx +++ b/sim/detectors/much/qa/CbmMuchTransportQa.cxx @@ -4,41 +4,10 @@ /// \author Eugeny Kryshen /// \author Vikas Singhal /// \author Ekata Nandy -/// \date 25.09.2020 +/// \author Dominik Smith +/// \date 21.10.2020 #include "CbmMuchTransportQa.h" - -#include "FairLogger.h" -#include "FairRootFileSink.h" -#include "FairRootManager.h" -#include "FairRun.h" -#include "FairRuntimeDb.h" - -#include "CbmGeoMuchPar.h" -#include "CbmMuchGeoScheme.h" -#include "CbmMuchStation.h" - -#include "CbmMuchPoint.h" - -#include "CbmMCTrack.h" -#include "TDatabasePDG.h" -#include "TParticlePDG.h" - -#include "TString.h" - -#include "TClonesArray.h" - -#include "CbmQaCanvas.h" -#include "TH1.h" -#include "TH2.h" -#include "TLegend.h" -#include "TPie.h" -#include "TPieSlice.h" -#include "TStyle.h" - -#include <cassert> -#include <vector> - ClassImp(CbmMuchTransportQa); // ------------------------------------------------------------------------- @@ -55,18 +24,15 @@ CbmMuchTransportQa::CbmMuchTransportQa(const char* name, Int_t verbose) , fvMcPointPrimRatio() {} // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- CbmMuchTransportQa::~CbmMuchTransportQa() { DeInit(); } // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- void CbmMuchTransportQa::DeInit() { fPoints = nullptr; fMcTracks = nullptr; - fOutFolder.Clear(); fhNevents.SetVal(0); @@ -82,14 +48,14 @@ void CbmMuchTransportQa::DeInit() { for (uint i = 0; i < fvMcPointXY.size(); i++) { SafeDelete(fvMcPointXY[i]); } - fvMcPointXY.clear(); for (uint i = 0; i < fvMcPointPhiZ.size(); i++) { SafeDelete(fvMcPointPhiZ[i]); } - fvMcPointPhiZ.clear(); for (uint i = 0; i < fvMcPointRZ.size(); i++) { SafeDelete(fvMcPointRZ[i]); } + fvMcPointXY.clear(); + fvMcPointPhiZ.clear(); fvMcPointRZ.clear(); for (uint i = 0; i < fvMcPointPRatio.size(); i++) { @@ -98,7 +64,6 @@ void CbmMuchTransportQa::DeInit() { for (uint i = 0; i < fvMcPointPrimRatio.size(); i++) { SafeDelete(fvMcPointPrimRatio[i]); } - SafeDelete(fhNtracks); SafeDelete(fhFractionPrim); SafeDelete(fhFractionSec); @@ -110,14 +75,13 @@ void CbmMuchTransportQa::DeInit() { fvUsNtra.clear(); fvFraction.clear(); - fvMcPointPRatio.clear(); fvMcPointPrimRatio.clear(); SafeDelete(fCanvStationXY); SafeDelete(fCanvStationPhiZ); SafeDelete(fCanvStationRZ); - + SafeDelete(fCanvUsNtra); SafeDelete(fCanvStationPRatio); SafeDelete(fCanvStationPrimRatio); @@ -131,109 +95,118 @@ void CbmMuchTransportQa::DeInit() { InitStatus CbmMuchTransportQa::Init() { TDirectory* oldDirectory = gDirectory; - FairRootManager* manager = FairRootManager::Instance(); + fMcTracks = (TClonesArray*) manager->GetObject("MCTrack"); + fPoints = (TClonesArray*) manager->GetObject("MuchPoint"); + fNstations = CbmMuchGeoScheme::Instance()->GetNStations(); + histFolder = fOutFolder.AddFolder("hist", "Histogramms"); + if (!manager) { LOG(error) << "No FairRootManager found"; return kERROR; } - - fMcTracks = (TClonesArray*) manager->GetObject("MCTrack"); if (!fMcTracks) { LOG(error) << "No MC tracks found"; return kERROR; } - - fPoints = (TClonesArray*) manager->GetObject("MuchPoint"); if (!fPoints) { LOG(error) << "No MC points found"; return kERROR; } - if (!CbmMuchGeoScheme::Instance()) { LOG(fatal) << "No CbmMuchGeoScheme found"; return kFATAL; } - - fNstations = CbmMuchGeoScheme::Instance()->GetNStations(); - if (fNstations == 0) { LOG(error) << "CbmMuchGeoScheme is not initialized"; return kERROR; } - - TFolder* histFolder = fOutFolder.AddFolder("hist", "Histogramms"); - + for (Int_t i = 0; i < fNstations; i++) { + CbmMuchStation* station = CbmMuchGeoScheme::Instance()->GetStation(i); + if (!station) { + LOG(fatal) << "Much station " << i << " doesn't exist"; + return kFATAL; + } + } fhNevents.SetVal(0); histFolder->Add(&fhNevents); -#define BINS_STA fNstations, 0, fNstations - - { - fvUsNtra.clear(); - std::vector<TH1F*>& v = fvUsNtra; - v.push_back(fhUsNtraAll = new TH1F("hUsNtraAll", "N tracks", BINS_STA)); - v.push_back(fhUsNtraPrim = - new TH1F("hUsNtraPrim", "N primary tracks", BINS_STA)); - v.push_back(fhUsNtraSec = - new TH1F("hUsNtraSec", "N secondary tracks", BINS_STA)); - v.push_back(fhUsNtraPr = new TH1F("hUsNtraPr", "N protons", BINS_STA)); - v.push_back(fhUsNtraPi = new TH1F("hUsNtraPi", "N pions", BINS_STA)); - v.push_back(fhUsNtraEl = new TH1F("hUsNtraEl", "N electrons", BINS_STA)); - v.push_back(fhUsNtraMu = new TH1F("hUsNtraMu", "N muons", BINS_STA)); - v.push_back(fhUsNtraKa = new TH1F("hUsNtraKa", "N kaons", BINS_STA)); - for (uint i = 0; i < fvUsNtra.size(); i++) { - TH1F* h = fvUsNtra[i]; - h->SetStats(0); - h->GetXaxis()->SetTitle("Station"); - histFolder->Add(h); - } + InitCountingHistos(); + InitFractionHistos(); + Init2dSpatialDistributionHistos(); + InitRatioPieCharts(); + InitCanvases(); + + gDirectory = oldDirectory; + return kSUCCESS; +} +// ------------------------------------------------------------------------- + +void CbmMuchTransportQa::InitCountingHistos() { + + fvUsNtra.clear(); + std::vector<TH1F*>& v = fvUsNtra; + v.push_back(fhUsNtraAll = new TH1F("hUsNtraAll", "N tracks", BINS_STA)); + v.push_back(fhUsNtraPrim = + new TH1F("hUsNtraPrim", "N primary tracks", BINS_STA)); + v.push_back(fhUsNtraSec = + new TH1F("hUsNtraSec", "N secondary tracks", BINS_STA)); + v.push_back(fhUsNtraPr = new TH1F("hUsNtraPr", "N protons", BINS_STA)); + v.push_back(fhUsNtraPi = new TH1F("hUsNtraPi", "N pions", BINS_STA)); + v.push_back(fhUsNtraEl = new TH1F("hUsNtraEl", "N electrons", BINS_STA)); + v.push_back(fhUsNtraMu = new TH1F("hUsNtraMu", "N muons", BINS_STA)); + v.push_back(fhUsNtraKa = new TH1F("hUsNtraKa", "N kaons", BINS_STA)); + for (uint i = 0; i < fvUsNtra.size(); i++) { + TH1F* h = fvUsNtra[i]; + h->SetStats(0); + h->GetXaxis()->SetTitle("Station"); + histFolder->Add(h); } +} + +void CbmMuchTransportQa::InitFractionHistos() { - { - fvFraction.clear(); - std::vector<TH1F*>& v = fvFraction; - v.push_back(fhNtracks = - new TH1F("hNtracks", "N tracks per event", BINS_STA)); - v.push_back(fhFractionPrim = new TH1F( - "hFractionPrim", "Fraction of primary tracks", BINS_STA)); - v.push_back(fhFractionSec = new TH1F( - "hFractionSec", "Fraction of secondary tracks", BINS_STA)); - v.push_back(fhFractionPr = - new TH1F("hFractionPr", "Fraction of protons", BINS_STA)); - v.push_back(fhFractionPi = - new TH1F("hFractionPi", "Fraction of pions", BINS_STA)); - v.push_back(fhFractionEl = - new TH1F("hFractionEl", "Fraction of electrons", BINS_STA)); - v.push_back(fhFractionMu = - new TH1F("hFractionMu", "Fraction of muons", BINS_STA)); - v.push_back(fhFractionKa = - new TH1F("hFractionKa", "Fraction of kaons", BINS_STA)); - - for (uint i = 0; i < fvFraction.size(); i++) { - TH1F* h = fvFraction[i]; - h->SetStats(0); - h->GetXaxis()->SetTitle("Station"); + fvFraction.clear(); + std::vector<TH1F*>& v = fvFraction; + v.push_back(fhNtracks = new TH1F("hNtracks", "N tracks per event", BINS_STA)); + v.push_back(fhFractionPrim = new TH1F( + "hFractionPrim", "Fraction of primary tracks", BINS_STA)); + v.push_back(fhFractionSec = new TH1F( + "hFractionSec", "Fraction of secondary tracks", BINS_STA)); + v.push_back(fhFractionPr = + new TH1F("hFractionPr", "Fraction of protons", BINS_STA)); + v.push_back(fhFractionPi = + new TH1F("hFractionPi", "Fraction of pions", BINS_STA)); + v.push_back(fhFractionEl = + new TH1F("hFractionEl", "Fraction of electrons", BINS_STA)); + v.push_back(fhFractionMu = + new TH1F("hFractionMu", "Fraction of muons", BINS_STA)); + v.push_back(fhFractionKa = + new TH1F("hFractionKa", "Fraction of kaons", BINS_STA)); + + for (uint i = 0; i < fvFraction.size(); i++) { + TH1F* h = fvFraction[i]; + h->SetStats(0); + h->GetXaxis()->SetTitle("Station"); + if (i == 0) { + h->GetYaxis()->SetTitle("N tracks"); + } else { h->GetYaxis()->SetTitle("%"); - histFolder->Add(h); } + histFolder->Add(h); } +} + +void CbmMuchTransportQa::Init2dSpatialDistributionHistos() { fvMcPointXY.resize(fNstations); fvMcPointPhiZ.resize(fNstations); fvMcPointRZ.resize(fNstations); - fvMcPointPRatio.resize(fNstations); - fvMcPointPrimRatio.resize(fNstations); - for (Int_t i = 0; i < fNstations; i++) { CbmMuchStation* station = CbmMuchGeoScheme::Instance()->GetStation(i); - if (!station) { - LOG(fatal) << "Much station " << i << " doesn't exist"; - return kFATAL; - } - Double_t rMax = station->GetRmax(); - Double_t rMin = station->GetRmin(); + Double_t rMax = station->GetRmax(); + Double_t rMin = station->GetRmin(); fvMcPointXY[i] = new TH2F(Form("hMcPointXY%i", i + 1), Form("MC point XY : Station %i; X; Y", i + 1), @@ -243,8 +216,6 @@ InitStatus CbmMuchTransportQa::Init() { 100, -1.2 * rMax, 1.2 * rMax); - histFolder->Add(fvMcPointXY[i]); - fvMcPointPhiZ[i] = new TH2F(Form("hMcPointPhiZ%i", i + 1), Form("MC point Phi vs Z : Station %i; Z; Phi", i + 1), @@ -254,7 +225,6 @@ InitStatus CbmMuchTransportQa::Init() { 100, -200., 200.); - histFolder->Add(fvMcPointPhiZ[i]); float dR = rMax - rMin; fvMcPointRZ[i] = new TH2F(Form("hMcPointRZ%i", i + 1), @@ -265,42 +235,53 @@ InitStatus CbmMuchTransportQa::Init() { 100, rMin - 0.1 * dR, rMax + 0.1 * dR); + histFolder->Add(fvMcPointXY[i]); + histFolder->Add(fvMcPointPhiZ[i]); histFolder->Add(fvMcPointRZ[i]); + } +} + +void CbmMuchTransportQa::InitRatioPieCharts() { + fvMcPointPRatio.resize(fNstations); + fvMcPointPrimRatio.resize(fNstations); + for (Int_t i = 0; i < fNstations; i++) { fvMcPointPRatio[i] = new TPie(Form("fvMcPointPRatio%i", i + 1), Form("McPoint Particle Ratios: Station %i", i + 1), 5); - //histFolder->Add(fvMcPointPRatio[i]); - fvMcPointPrimRatio[i] = new TPie(Form("fvMcPointPrimRatio%i", i + 1), Form("McPoint Primary/Secondary Track: Station %i", i + 1), 2); - //histFolder->Add(fvMcPointPrimRatio[i]); + histFolder->Add(fvMcPointPRatio[i]); + histFolder->Add(fvMcPointPrimRatio[i]); } +} + +void CbmMuchTransportQa::InitCanvases() { fCanvStationXY = new CbmQaCanvas("cMcPointXY", "Much: MC point XY", 2 * 400, 2 * 400); fCanvStationXY->Divide2D(fNstations); - fOutFolder.Add(fCanvStationXY); fCanvStationPhiZ = new CbmQaCanvas( "cMcPointPhiZ", "Much: MC point Phi vs Z", 2 * 800, 2 * 400); fCanvStationPhiZ->Divide2D(fNstations); - fOutFolder.Add(fCanvStationPhiZ); fCanvStationRZ = new CbmQaCanvas("cMcPointRZ", "Much: MC point R vs Z", 2 * 800, 2 * 400); fCanvStationRZ->Divide2D(fNstations); - fOutFolder.Add(fCanvStationRZ); + + fCanvUsNtra = + new CbmQaCanvas("cUsNtra", "Much: MC unscaled counts", 3 * 400, 3 * 400); + fCanvUsNtra->Divide2D(9); fCanvStationPRatio = new CbmQaCanvas( "cMcPointPRatios", "Much: MC particle ratios", 2 * 400, 2 * 400); fCanvStationPRatio->Divide2D(fNstations); - fOutFolder.Add(fCanvStationPRatio); fCanvStationPrimRatio = new CbmQaCanvas("cMcPointPrimRatios", @@ -308,14 +289,14 @@ InitStatus CbmMuchTransportQa::Init() { 2 * 400, 2 * 400); fCanvStationPrimRatio->Divide2D(fNstations); - fOutFolder.Add(fCanvStationPrimRatio); - gDirectory = oldDirectory; - - return kSUCCESS; + fOutFolder.Add(fCanvStationXY); + fOutFolder.Add(fCanvStationPhiZ); + fOutFolder.Add(fCanvStationRZ); + fOutFolder.Add(fCanvUsNtra); + fOutFolder.Add(fCanvStationPRatio); + fOutFolder.Add(fCanvStationPrimRatio); } -// ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- InitStatus CbmMuchTransportQa::ReInit() { @@ -324,7 +305,6 @@ InitStatus CbmMuchTransportQa::ReInit() { } // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- void CbmMuchTransportQa::SetParContainers() { // Get run and runtime database @@ -350,26 +330,20 @@ void CbmMuchTransportQa::SetParContainers() { void CbmMuchTransportQa::Exec(Option_t*) { LOG(info) << "Event: " << fhNevents.GetVal(); - fhNevents.SetVal(fhNevents.GetVal() + 1); - // bitmask tells which stations were crossed by mc track std::vector<UInt_t> trackStaCross(fMcTracks->GetEntriesFast(), 0); for (Int_t i = 0; i < fPoints->GetEntriesFast(); i++) { CbmMuchPoint* point = (CbmMuchPoint*) fPoints->At(i); - - if (!point) { - LOG(fatal) << "Much point " << i << " doesn't exist"; - break; - } - Int_t stId = CbmMuchAddress::GetStationIndex(point->GetDetectorID()); UInt_t stMask = (1 << stId); - - // Check if the point corresponds to a certain MC Track Int_t trackId = point->GetTrackID(); + if (!point) { + LOG(fatal) << "Much point " << i << " doesn't exist"; + break; + } // Check if the point corresponds to a certain MC Track if (trackId < 0 || trackId >= fMcTracks->GetEntriesFast()) { LOG(fatal) << "Much point " << i << ": trackId " << trackId << " doesn't belong to [0," << fMcTracks->GetEntriesFast() - 1 @@ -384,12 +358,8 @@ void CbmMuchTransportQa::Exec(Option_t*) { } Int_t motherId = mcTrack->GetMotherId(); - - // Get mass - Int_t pdgCode = mcTrack->GetPdgCode(); - + Int_t pdgCode = mcTrack->GetPdgCode(); //if (pdgCode == 0) continue; - TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(pdgCode); if (!particle) { LOG(warning) << "Particle with pdg code " << pdgCode << " doesn't exist"; @@ -404,77 +374,162 @@ void CbmMuchTransportQa::Exec(Option_t*) { } if (!(trackStaCross[trackId] & stMask)) { - fhUsNtraAll->Fill(stId); - if (motherId == -1) { - fhUsNtraPrim->Fill(stId); - } else { - fhUsNtraSec->Fill(stId); - } - switch (abs(pdgCode)) { - case 2212: // proton - fhUsNtraPr->Fill(stId); - break; - case 211: // pion - fhUsNtraPi->Fill(stId); - break; - case 11: // electron - fhUsNtraEl->Fill(stId); - break; - case 13: // muon - fhUsNtraMu->Fill(stId); - break; - case 321: // kaon - fhUsNtraKa->Fill(stId); - break; - } + FillCountingHistos(stId, motherId, pdgCode); } - trackStaCross[trackId] |= stMask; + Fill2dSpatialDistributionHistos(point, stId); + } +} - TVector3 v1; // in position of the track - TVector3 v2; // out position of the track - - point->PositionIn(v1); - point->PositionOut(v2); - - fvMcPointXY[stId]->Fill(v1.X(), v1.Y()); - fvMcPointXY[stId]->Fill(v2.X(), v2.Y()); - - fvMcPointPhiZ[stId]->Fill(v1.Z(), v1.Phi() * TMath::RadToDeg()); - fvMcPointPhiZ[stId]->Fill(v2.Z(), v2.Phi() * TMath::RadToDeg()); - - fvMcPointRZ[stId]->Fill(v1.Z(), v1.Perp()); - fvMcPointRZ[stId]->Fill(v2.Z(), v2.Perp()); +void CbmMuchTransportQa::FillCountingHistos(Int_t stId, + Int_t motherId, + Int_t pdgCode) { + fhUsNtraAll->Fill(stId); + if (motherId == -1) { + fhUsNtraPrim->Fill(stId); + } else { + fhUsNtraSec->Fill(stId); + } + switch (abs(pdgCode)) { + case 2212: // proton + fhUsNtraPr->Fill(stId); + break; + case 211: // pion + fhUsNtraPi->Fill(stId); + break; + case 11: // electron + fhUsNtraEl->Fill(stId); + break; + case 13: // muon + fhUsNtraMu->Fill(stId); + break; + case 321: // kaon + fhUsNtraKa->Fill(stId); + break; } } // ------------------------------------------------------------------------- +void CbmMuchTransportQa::Fill2dSpatialDistributionHistos(CbmMuchPoint* point, + Int_t stId) { + + TVector3 v1; // in position of the track + TVector3 v2; // out position of the track + point->PositionIn(v1); + point->PositionOut(v2); + + fvMcPointXY[stId]->Fill(v1.X(), v1.Y()); + fvMcPointXY[stId]->Fill(v2.X(), v2.Y()); + fvMcPointPhiZ[stId]->Fill(v1.Z(), v1.Phi() * TMath::RadToDeg()); + fvMcPointPhiZ[stId]->Fill(v2.Z(), v2.Phi() * TMath::RadToDeg()); + fvMcPointRZ[stId]->Fill(v1.Z(), v1.Perp()); + fvMcPointRZ[stId]->Fill(v2.Z(), v2.Perp()); +} // ------------------------------------------------------------------------- TFolder& CbmMuchTransportQa::GetQa() { TDirectory* oldDirectory = gDirectory; - fhNtracks->Reset(); fhNtracks->Add(fhUsNtraAll, 1. / fhNevents.GetVal()); - { - std::vector<Double_t> errors(fNstations, 0.); - fhUsNtraAll->SetError(errors.data()); - } + std::vector<Double_t> errors(fNstations, 0.); + fhUsNtraAll->SetError(errors.data()); for (uint i = 1; i < fvFraction.size(); i++) { fvFraction[i]->Divide(fvUsNtra[i], fhUsNtraAll); fvFraction[i]->Scale(100.); } + MakePRatioPieCharts(); + MakePrimRatioPieCharts(); + DrawCanvases(); + + gDirectory = oldDirectory; + return fOutFolder; +} +// ------------------------------------------------------------------------- + +void CbmMuchTransportQa::DrawCanvases() { + + for (Int_t i = 0; i < fNstations; i++) { + fCanvStationXY->cd(i + 1); + gStyle->SetOptStat(0); + fvMcPointXY[i]->DrawCopy("colz", ""); + + fCanvStationPhiZ->cd(i + 1); + gStyle->SetOptStat(0); + fvMcPointPhiZ[i]->DrawCopy("colz", ""); + + fCanvStationRZ->cd(i + 1); + gStyle->SetOptStat(0); + fvMcPointRZ[i]->DrawCopy("colz", ""); + + fCanvStationPRatio->cd(i + 1); + gStyle->SetOptStat(0); + fvMcPointPRatio[i]->DrawClone("nol <"); + + TLegend* PRatioPieLeg = fvMcPointPRatio[i]->MakeLegend(); + PRatioPieLeg->SetY1(.56); + PRatioPieLeg->SetY2(.86); + + fCanvStationPrimRatio->cd(i + 1); + gStyle->SetOptStat(0); + fvMcPointPrimRatio[i]->DrawClone("nol <"); + + TLegend* PrimRatioPieLeg = fvMcPointPrimRatio[i]->MakeLegend(); + PrimRatioPieLeg->SetY1(.71); + PrimRatioPieLeg->SetY2(.86); + PrimRatioPieLeg->SetX1(.40); + PrimRatioPieLeg->SetX2(.90); + + gStyle->SetOptStat(1110); + } + + fCanvUsNtra->cd(1); + gStyle->SetOptStat(0); + fhUsNtraAll->DrawCopy("colz", ""); + + fCanvUsNtra->cd(2); + gStyle->SetOptStat(0); + fhNtracks->DrawCopy("colz", ""); + + fCanvUsNtra->cd(3); + gStyle->SetOptStat(0); + fhUsNtraPrim->DrawCopy("colz", ""); + + fCanvUsNtra->cd(4); + gStyle->SetOptStat(0); + fhUsNtraSec->DrawCopy("colz", ""); + + fCanvUsNtra->cd(5); + gStyle->SetOptStat(0); + fhUsNtraPr->DrawCopy("colz", ""); + + fCanvUsNtra->cd(6); + gStyle->SetOptStat(0); + fhUsNtraPi->DrawCopy("colz", ""); + + fCanvUsNtra->cd(7); + gStyle->SetOptStat(0); + fhUsNtraEl->DrawCopy("colz", ""); + + fCanvUsNtra->cd(8); + gStyle->SetOptStat(0); + fhUsNtraMu->DrawCopy("colz", ""); + + fCanvUsNtra->cd(9); + gStyle->SetOptStat(0); + fhUsNtraKa->DrawCopy("colz", ""); +} + +void CbmMuchTransportQa::MakePRatioPieCharts() { for (Int_t i = 0; i < fNstations; i++) { - Double_t PRatios[] = {fhFractionEl->GetBinContent(i + 1), + Double_t PRatios[] = {fhFractionEl->GetBinContent(i + 1), fhFractionPr->GetBinContent(i + 1), fhFractionPi->GetBinContent(i + 1), fhFractionMu->GetBinContent(i + 1), fhFractionKa->GetBinContent(i + 1)}; - Int_t PRatiosColors[] = {4, 3, 2, 5, 6}; fvMcPointPRatio[i]->SetEntryVal(0, PRatios[0]); @@ -497,10 +552,14 @@ TFolder& CbmMuchTransportQa::GetQa() { fvMcPointPRatio[i]->SetRadius(.33); fvMcPointPRatio[i]->SetLabelsOffset(-.1); fvMcPointPRatio[i]->SetLabelFormat(""); + } +} - Double_t PrimRatios[] = {fhFractionPrim->GetBinContent(i + 1), - fhFractionSec->GetBinContent(i + 1)}; +void CbmMuchTransportQa::MakePrimRatioPieCharts() { + for (Int_t i = 0; i < fNstations; i++) { + Double_t PrimRatios[] = {fhFractionPrim->GetBinContent(i + 1), + fhFractionSec->GetBinContent(i + 1)}; Int_t PrimRatiosColors[] = {6, 4}; fvMcPointPrimRatio[i]->SetEntryVal(0, PrimRatios[0]); @@ -515,47 +574,7 @@ TFolder& CbmMuchTransportQa::GetQa() { fvMcPointPrimRatio[i]->SetLabelsOffset(-.1); fvMcPointPrimRatio[i]->SetLabelFormat(""); } - - for (Int_t i = 0; i < fNstations; i++) { - - fCanvStationXY->cd(i + 1); - gStyle->SetOptStat(0); - fvMcPointXY[i]->DrawCopy("colz", ""); - - fCanvStationPhiZ->cd(i + 1); - gStyle->SetOptStat(0); - fvMcPointPhiZ[i]->DrawCopy("colz", ""); - - fCanvStationRZ->cd(i + 1); - gStyle->SetOptStat(0); - fvMcPointRZ[i]->DrawCopy("colz", ""); - - fCanvStationPRatio->cd(i + 1); - gStyle->SetOptStat(0); - fvMcPointPRatio[i]->DrawClone("nol <"); - - TLegend* PRatioPieLeg = fvMcPointPRatio[i]->MakeLegend(); - PRatioPieLeg->SetY1(.56); - PRatioPieLeg->SetY2(.86); - - fCanvStationPrimRatio->cd(i + 1); - gStyle->SetOptStat(0); - fvMcPointPrimRatio[i]->DrawClone("nol <"); - - TLegend* PrimRatioPieLeg = fvMcPointPrimRatio[i]->MakeLegend(); - PrimRatioPieLeg->SetY1(.71); - PrimRatioPieLeg->SetY2(.86); - PrimRatioPieLeg->SetX1(.40); - PrimRatioPieLeg->SetX2(.90); - - gStyle->SetOptStat(1110); - } - - gDirectory = oldDirectory; - return fOutFolder; } -// ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- void CbmMuchTransportQa::Finish() { diff --git a/sim/detectors/much/qa/CbmMuchTransportQa.h b/sim/detectors/much/qa/CbmMuchTransportQa.h index f6232dfd20..3805faa5a1 100644 --- a/sim/detectors/much/qa/CbmMuchTransportQa.h +++ b/sim/detectors/much/qa/CbmMuchTransportQa.h @@ -4,26 +4,42 @@ /// \author Eugeny Kryshen /// \author Vikas Singhal /// \author Ekata Nandy -/// \date 25.09.2020 +/// \author Dominik Smith +/// \date 21.10.2020 #ifndef CbmMuchTransportQa_H #define CbmMuchTransportQa_H +#include "CbmGeoMuchPar.h" +#include "CbmMCTrack.h" +#include "CbmMuchGeoScheme.h" +#include "CbmMuchPoint.h" +#include "CbmMuchStation.h" +#include "CbmQaCanvas.h" +#include "FairLogger.h" +#include "FairRootFileSink.h" +#include "FairRootManager.h" +#include "FairRun.h" +#include "FairRuntimeDb.h" #include "FairTask.h" +#include "TClonesArray.h" +#include "TDatabasePDG.h" #include "TFolder.h" +#include "TH1.h" +#include "TH2.h" +#include "TLegend.h" #include "TParameter.h" +#include "TParticlePDG.h" +#include "TPie.h" +#include "TPieSlice.h" +#include "TString.h" +#include "TStyle.h" +#include <cassert> +#include <vector> -class CbmMuchGeoScheme; -class TClonesArray; -class TH1F; -class TH2F; -class TPie; -class TPieSlice; -class TLegend; -class CbmQaCanvas; +#define BINS_STA fNstations, 0, fNstations /// QA for the MUCH detector after a "transport" step of the simulation. -/// /// The class reimplements corresponding QA checks from old CbmMuchHitFinderQa class /// made by E. Kryshen & V. Singhal & E. Nandy /// @@ -32,7 +48,6 @@ class CbmMuchTransportQa : public FairTask { public: /// Constructor CbmMuchTransportQa(const char* name = "MuchHitFinderQa", Int_t verbose = 1); - /// Deactivated copy constructors CbmMuchTransportQa(const CbmMuchTransportQa&) = delete; CbmMuchTransportQa& operator=(const CbmMuchTransportQa&) = delete; @@ -52,10 +67,22 @@ public: TFolder& GetQa(); private: + void InitCountingHistos(); + void InitFractionHistos(); + void Init2dSpatialDistributionHistos(); + void InitRatioPieCharts(); + void InitCanvases(); + void FillCountingHistos(Int_t stId, Int_t motherId, Int_t pdgCode); + void Fill2dSpatialDistributionHistos(CbmMuchPoint* point, Int_t stId); + /// Reset varibles & deallocate memory. /// When not called by destructor, need to be folloed by Init(). void DeInit(); + void MakePRatioPieCharts(); + void MakePrimRatioPieCharts(); + void DrawCanvases(); + /// geometry Int_t fNstations = 0; @@ -64,11 +91,11 @@ private: TClonesArray* fMcTracks = nullptr; /// + TFolder* histFolder; /// subfolder for histograms TFolder fOutFolder; /// output folder with histos and canvases TParameter<int> fhNevents; /// number of processed events /// internal unscaled histogramms - TH1F* fhUsNtraAll = nullptr; /// number of all tracks TH1F* fhUsNtraPrim = nullptr; /// number of primary tracks TH1F* fhUsNtraSec = nullptr; /// number of secondary tracks @@ -77,11 +104,9 @@ private: TH1F* fhUsNtraEl = nullptr; /// number of electrons TH1F* fhUsNtraMu = nullptr; /// number of muons TH1F* fhUsNtraKa = nullptr; /// number of kaons - - std::vector<TH1F*> fvUsNtra; /// pointers to the above fhUsNtra* histos + std::vector<TH1F*> fvUsNtra; /// pointers to the above fhUsNtra* histos /// output histograms - std::vector<TH2F*> fvMcPointXY; /// MC point Y vs X [N stations] std::vector<TH2F*> fvMcPointPhiZ; /// MC point Phi vs Z [N stations] std::vector<TH2F*> fvMcPointRZ; /// MC point R vs Z [N stations] @@ -94,24 +119,21 @@ private: TH1F* fhFractionEl = nullptr; /// fraction of electrons TH1F* fhFractionMu = nullptr; /// fraction of muons TH1F* fhFractionKa = nullptr; /// fraction of kaons - - std::vector<TH1F*> fvFraction; /// pointers to the above histos + std::vector<TH1F*> fvFraction; /// pointers to the above histos /// output pie charts - std::vector<TPie*> fvMcPointPRatio; /// MC point particle ratio pie charts [N stations] std::vector<TPie*> fvMcPointPrimRatio; /// MC point particle ratio pie charts [N stations] // output canvaces with histogramm collections - CbmQaCanvas* fCanvStationXY = nullptr; CbmQaCanvas* fCanvStationPhiZ = nullptr; CbmQaCanvas* fCanvStationRZ = nullptr; + CbmQaCanvas* fCanvUsNtra = nullptr; // output canvaces with pie chart collections - CbmQaCanvas* fCanvStationPRatio = nullptr; CbmQaCanvas* fCanvStationPrimRatio = nullptr; -- GitLab