From 637b7dec02e1a1d9edc2414bce7c2b9d85c4324f Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Fri, 22 Sep 2023 03:00:10 +0200 Subject: [PATCH] CA QA: Automatic plot for tracking setup --- core/qa/CbmQaTask.cxx | 17 +++++ core/qa/CbmQaTask.h | 13 +++- macro/mcbm/mcbm_qa.C | 1 + reco/L1/CbmL1.cxx | 1 + reco/L1/CbmL1.h | 1 + reco/L1/CbmL1Performance.cxx | 1 + reco/L1/qa/CbmCaInputQaSetup.cxx | 119 +++++++++++++++++++++++++------ reco/L1/qa/CbmCaInputQaSetup.h | 18 ++++- reco/L1/qa/CbmCaOutputQa.cxx | 10 ++- 9 files changed, 156 insertions(+), 25 deletions(-) diff --git a/core/qa/CbmQaTask.cxx b/core/qa/CbmQaTask.cxx index ecc17172a5..130638f4f2 100644 --- a/core/qa/CbmQaTask.cxx +++ b/core/qa/CbmQaTask.cxx @@ -17,6 +17,8 @@ #include "TAxis.h" #include "TCanvas.h" #include "TF1.h" +#include "TPad.h" +#include "TPaveText.h" #include "TString.h" #include <array> @@ -137,3 +139,18 @@ bool CbmQaTask::CheckRange(TH1* h, double meanMax, double rmsMin, double rmsMax) } return res; } + +// --------------------------------------------------------------------------------------------------------------------- +// +void CbmQaTask::PutSetupNameOnPad(double xMin, double yMin, double xMax, double yMax) +{ + if (gPad) { + gPad->cd(); + auto* paveText = new TPaveText(xMin, yMin, xMax, yMax, "NDC"); + paveText->AddText(fsSetupName.c_str()); + paveText->SetBorderSize(0); + paveText->SetTextSize(0.04); + paveText->SetFillStyle(0); + paveText->Draw("same"); + } +} diff --git a/core/qa/CbmQaTask.h b/core/qa/CbmQaTask.h index cfd3ea35cc..f09f820141 100644 --- a/core/qa/CbmQaTask.h +++ b/core/qa/CbmQaTask.h @@ -58,6 +58,9 @@ public: CbmQaTask& operator=(const CbmQaTask&) = delete; CbmQaTask& operator=(CbmQaTask&&) = delete; + /// @brief Gets name of the setup + const std::string& GetSetupName() const { return fsSetupName; } + /// Returns flag, whether MC information is used or not in the task bool IsMCUsed() const { return fbUseMC; } @@ -73,6 +76,10 @@ public: /// FairTask: Defines action of the task in the end of run void Finish(); + /// @brief Sets name of the setup + void SetSetupName(const char* setup) { fsSetupName = setup; } + +protected: ClassDef(CbmQaTask, 0); protected: @@ -104,7 +111,6 @@ protected: /// Get current event number int GetEventNumber() const { return fNofEvents.GetVal(); } - // *********************** // ** Utility functions ** // *********************** @@ -132,12 +138,17 @@ protected: /// \return False, if variable exits the range bool CheckRange(TH1* h, double meanMax, double rmsMin, double rmsMax); + /// @brief Puts setup title on the canvas + void PutSetupNameOnPad(double xMin, double yMin, double xMax, double yMax); + private: /// @brief De-initializes this task void DeInitBase(); bool fbUseMC = false; ///< Flag, if MC is used + std::string fsSetupName = ""; ///< Name of the setup (to draw on the canvases) + TParameter<int> fNofEvents {"nEvents", 0}; ///< Number of processed events }; diff --git a/macro/mcbm/mcbm_qa.C b/macro/mcbm/mcbm_qa.C index 1a67d7523f..1e1274db87 100644 --- a/macro/mcbm/mcbm_qa.C +++ b/macro/mcbm/mcbm_qa.C @@ -251,6 +251,7 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", pCaInputQaSetup->SetDetectorFlag(L1DetectorID::kTrd, bUseTrd); pCaInputQaSetup->SetDetectorFlag(L1DetectorID::kTof, bUseTof); pCaInputQaSetup->ReadParameters(caParFile.Data()); + pCaInputQaSetup->SetSetupName(setupName.Data()); run->AddTask(pCaInputQaSetup); auto* pCaOutputQa = new cbm::ca::OutputQa(verbose, bUseMC); diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index 61a2f307a9..5113d5e38d 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -663,6 +663,7 @@ InitStatus CbmL1::Init() fMonitor.SetKeyName(EMonitorKey::kEvent, "N events"); fMonitor.SetKeyName(EMonitorKey::kRecoTrack, "N reco tracks"); fMonitor.SetKeyName(EMonitorKey::kRecoHit, "N hits"); + fMonitor.SetKeyName(EMonitorKey::kGhostTrack, "N ghosts"); fMonitor.SetKeyName(EMonitorKey::kDiscardedHitMvd, "N discarded hits in MVD"); fMonitor.SetKeyName(EMonitorKey::kDiscardedHitSts, "N discarded hits in STS"); fMonitor.SetKeyName(EMonitorKey::kDiscardedHitMuch, "N discarded hits in MUCH"); diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 8ed28ff156..2da65db31d 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -264,6 +264,7 @@ public: kEvent, ///< Number of processed events kRecoTrack, ///< Number of reconstructed tracks kRecoHit, ///< Number of reconstructed hits + kGhostTrack, ///< Number of ghost tracks kDiscardedHitMvd, ///< Number of discarded hits in MVD kDiscardedHitSts, ///< Number of discarded hits in STS kDiscardedHitMuch, ///< Number of discarded hits in MuCh diff --git a/reco/L1/CbmL1Performance.cxx b/reco/L1/CbmL1Performance.cxx index 0e73bf2bdc..bd3cf8d243 100644 --- a/reco/L1/CbmL1Performance.cxx +++ b/reco/L1/CbmL1Performance.cxx @@ -875,6 +875,7 @@ void CbmL1::HistoPerformance() // TODO: check if works correctly. Change vHitFa // fill ghost histos if (prtra->IsGhost()) { + fMonitor.Increment(EMonitorKey::kGhostTrack); h_ghost_purity->Fill(100 * prtra->GetMaxPurity()); if (fabs(prtra->T[4]) > 1.e-10) { h_ghost_mom->Fill(fabs(1.0 / prtra->T[4])); diff --git a/reco/L1/qa/CbmCaInputQaSetup.cxx b/reco/L1/qa/CbmCaInputQaSetup.cxx index f2f8a1844a..2fb7f88ad9 100644 --- a/reco/L1/qa/CbmCaInputQaSetup.cxx +++ b/reco/L1/qa/CbmCaInputQaSetup.cxx @@ -13,6 +13,8 @@ #include "FairRootManager.h" +#include "TAxis.h" + #include "L1InitManager.h" using cbm::ca::InputQaSetup; @@ -52,11 +54,98 @@ void InputQaSetup::FillHistograms() if (fvbUseDet[L1DetectorID::kTof]) { this->FillHistogramsDet<L1DetectorID::kTof>(); } } +// --------------------------------------------------------------------------------------------------------------------- +// +InitStatus InputQaSetup::InitCanvases() +{ + // Tracking setup by hits + { + auto* canv = MakeQaObject<CbmQaCanvas>("c_setup_hits", "Setup by hits", 1000, 1000); + canv->Divide(1, 2, 0.000001, 0.000001); + canv->cd(1); + gPad->SetLogz(); + gPad->SetBottomMargin(0.000001); + gPad->SetRightMargin(0.05); + gPad->SetTitle(""); + auto* ph_hit_xz = dynamic_cast<TH2F*>(fph_hit_xz.back()->Clone("h_hit_xz_clone")); + ph_hit_xz->SetTitle(";z [cm];x [cm]"); + ph_hit_xz->Draw("col"); + this->PutSetupNameOnPad(0.08, 0.83, 0.50, 0.89); + canv->cd(2); + gPad->SetLogz(); + gPad->SetTopMargin(0.000001); + gPad->SetRightMargin(0.05); + gPad->SetTitle(""); + auto* ph_hit_yz = dynamic_cast<TH2F*>(fph_hit_yz.back()->Clone("h_hit_yz_clone")); + ph_hit_yz->SetTitle(";z [cm];y [cm]"); + ph_hit_yz->Draw("col"); + this->PutSetupNameOnPad(0.08, 0.93, 0.50, 0.99); + + + auto LoBinEdge = [](TAxis* pAxis, double val) { return pAxis->GetBinLowEdge(pAxis->FindBin(val)); }; + auto UpBinEdge = [](TAxis* pAxis, double val) { return pAxis->GetBinUpEdge(pAxis->FindBin(val)); }; + + for (int iDet = 0; iDet < static_cast<int>(fvpDetInterface.size()); ++iDet) { + if (!fvbUseDet[iDet]) { continue; } + int nSt = fvpDetInterface[iDet]->GetNtrackingStations(); + for (int iSt = 0; iSt < nSt; ++iSt) { + int iStActive = fpParameters->GetStationIndexActive(iSt, static_cast<L1DetectorID>(iDet)); + Color_t boxColor = (iStActive == -1) ? kGray + 1 : kOrange + 2; + const char* detName = Form("%s-%d", fvpDetInterface[iDet]->GetDetectorName().c_str(), iSt); + { + double zMin = LoBinEdge(fph_hit_xz.back()->GetXaxis(), fvZmin[iDet][iSt]); + double zMax = UpBinEdge(fph_hit_xz.back()->GetXaxis(), fvZmax[iDet][iSt]); + double xMin = LoBinEdge(fph_hit_xz.back()->GetYaxis(), fvXmin[iDet][iSt]); + double xMax = UpBinEdge(fph_hit_xz.back()->GetYaxis(), fvXmax[iDet][iSt]); + canv->cd(1); + auto* pBox = new TBox(zMin, xMin, zMax, xMax); + pBox->SetFillStyle(0); + pBox->SetLineWidth(2); + pBox->SetLineColor(boxColor); + pBox->Draw("same"); + auto* pText = new TText(zMin, xMax, detName); + pText->SetTextColor(boxColor); + pText->SetTextSize(0.035); + pText->SetTextAngle(45); + pText->Draw("same"); + } + { + double zMin = LoBinEdge(fph_hit_yz.back()->GetXaxis(), fvZmin[iDet][iSt]); + double zMax = UpBinEdge(fph_hit_yz.back()->GetXaxis(), fvZmax[iDet][iSt]); + double yMin = LoBinEdge(fph_hit_yz.back()->GetYaxis(), fvYmin[iDet][iSt]); + double yMax = UpBinEdge(fph_hit_yz.back()->GetYaxis(), fvYmax[iDet][iSt]); + canv->cd(2); + auto* pBox = new TBox(zMin, yMin, zMax, yMax); + pBox->SetFillStyle(0); + pBox->SetLineWidth(2); + pBox->SetLineColor(boxColor); + pBox->Draw("same"); + auto* pText = new TText(zMin, yMax, detName); + pText->SetTextSize(0.035); + pText->SetTextColor(boxColor); + pText->SetTextAngle(45); + pText->Draw("same"); + } + } + } + } + return kSUCCESS; +} + // --------------------------------------------------------------------------------------------------------------------- // InitStatus InputQaSetup::InitDataBranches() try { LOG(info) << fName << ": initializing... "; + // Tracking parameters + { + fpParameters = std::make_unique<L1Parameters>(); + + L1InitManager manager; + manager.ReadParametersObject(fsParametersFilename.c_str()); + manager.SendParameters(*fpParameters); + LOG(info) << "CA tracking parameters object: " << fsParametersFilename << '\n' << fpParameters->ToString(1); + } auto pFairManager = FairRootManager::Instance(); assert(pFairManager); @@ -68,7 +157,16 @@ try { fvpBrHits.fill(nullptr); auto InitDetInterface = [&](CbmTrackingDetectorInterfaceBase* ifs, L1DetectorID detID) { - if (fvbUseDet[detID]) { fvpDetInterface[detID] = ifs; } + if (fvbUseDet[detID]) { + fvpDetInterface[detID] = ifs; + int nSt = ifs->GetNtrackingStations(); + fvXmin[detID].resize(nSt, std::numeric_limits<double>::max()); + fvXmax[detID].resize(nSt, std::numeric_limits<double>::lowest()); + fvYmin[detID].resize(nSt, std::numeric_limits<double>::max()); + fvYmax[detID].resize(nSt, std::numeric_limits<double>::lowest()); + fvZmin[detID].resize(nSt, std::numeric_limits<double>::max()); + fvZmax[detID].resize(nSt, std::numeric_limits<double>::lowest()); + } }; auto InitHitBranch = [&](const char* brName, L1DetectorID detID) { @@ -153,22 +251,3 @@ InitStatus InputQaSetup::InitHistograms() return kSUCCESS; } - - -// --------------------------------------------------------------------------------------------------------------------- -// -void InputQaSetup::ReadParameters(const char* filename) -{ - fpParameters = std::make_unique<L1Parameters>(); - - L1InitManager manager; - manager.ReadParametersObject(filename); - manager.SendParameters(*fpParameters); - LOG(info) << "CA tracking parameters object: " << filename << '\n' << fpParameters->ToString(1); -} - - -// --------------------------------------------------------------------------------------------------------------------- -// -// --------------------------------------------------------------------------------------------------------------------- -// diff --git a/reco/L1/qa/CbmCaInputQaSetup.h b/reco/L1/qa/CbmCaInputQaSetup.h index ee06e67daf..31dc283356 100644 --- a/reco/L1/qa/CbmCaInputQaSetup.h +++ b/reco/L1/qa/CbmCaInputQaSetup.h @@ -50,17 +50,16 @@ namespace cbm::ca /// @brief Reads defined parameters object from file /// @param filename Name of parameter file /// @note TEMPORARY FUNCTION, A SEPARATE PARAMETERS INITIALIZATION CLASS IS TO BE USED - void ReadParameters(const char* filename); + void ReadParameters(const char* filename) { fsParametersFilename = filename; } /// @brief Sets detector flag void SetDetectorFlag(L1DetectorID detID, bool flag = true) { fvbUseDet[detID] = flag; } - protected: /// @brief Checks results of the QA and returns a success flag bool Check(); /// @brief Initializes canvases - InitStatus InitCanvases() { return kSUCCESS; }; + InitStatus InitCanvases(); /// @brief Initializes data branches InitStatus InitDataBranches(); @@ -96,7 +95,14 @@ namespace cbm::ca CbmMCEventList* fpMCEventList = nullptr; ///< Pointer to MC event list CbmMCDataObject* fpMCEventHeader = nullptr; ///< Pointer to MC event header std::unique_ptr<L1Parameters> fpParameters = nullptr; ///< Pointer to CA parameters object + std::string fsParametersFilename = ""; ///< Filename for the tracking parameters + DetIdArr_t<std::vector<double>> fvXmin; + DetIdArr_t<std::vector<double>> fvXmax; + DetIdArr_t<std::vector<double>> fvYmin; + DetIdArr_t<std::vector<double>> fvYmax; + DetIdArr_t<std::vector<double>> fvZmin; + DetIdArr_t<std::vector<double>> fvZmax; // ****************** // ** Histograms ** @@ -134,6 +140,12 @@ void cbm::ca::InputQaSetup::FillHistogramsDet() auto xHit = pHit->GetX(); auto yHit = pHit->GetY(); auto zHit = pHit->GetZ(); + if (fvXmin[DetID][iStLoc] > xHit) { fvXmin[DetID][iStLoc] = xHit; } + if (fvXmax[DetID][iStLoc] < xHit) { fvXmax[DetID][iStLoc] = xHit; } + if (fvYmin[DetID][iStLoc] > yHit) { fvYmin[DetID][iStLoc] = yHit; } + if (fvYmax[DetID][iStLoc] < yHit) { fvYmax[DetID][iStLoc] = yHit; } + if (fvZmin[DetID][iStLoc] > zHit) { fvZmin[DetID][iStLoc] = zHit; } + if (fvZmax[DetID][iStLoc] < zHit) { fvZmax[DetID][iStLoc] = zHit; } fph_hit_xz[iStGeo]->Fill(zHit, xHit); fph_hit_yz[iStGeo]->Fill(zHit, yHit); diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx index 455fc60249..8c114a4fba 100644 --- a/reco/L1/qa/CbmCaOutputQa.cxx +++ b/reco/L1/qa/CbmCaOutputQa.cxx @@ -97,6 +97,8 @@ void OutputQa::EnableDebugger(const char* filename) // void OutputQa::FillHistograms() { + fMonitor.Increment(EMonitorKey::kEvent); + // ************************************************************************ // ** Fill distributions for reconstructed tracks (including ghost ones) ** // ************************************************************************ @@ -611,11 +613,12 @@ bool OutputQa::Check() aTable->SetRowName(iRow, "N ghosts"); aTable->SetCell(iRow, 0, nGhosts); aTable->SetRowName(iRow + 1, "Ghost rate"); - aTable->SetCell(iRow + 1, 0, nGhosts / fvpTrackHistograms[ETrackType::kAll]->GetNofMCTracks()); + aTable->SetCell(iRow + 1, 0, nGhosts / fMonitor.GetValue(EMonitorKey::kTrack)); } LOG(info) << '\n' << aTable->ToString(3); } + LOG(info) << '\n' << fMonitor.ToString(); return true; } @@ -635,6 +638,9 @@ InitStatus OutputQa::InitTimeSlice() nHits = fvHits.size(); nRecoTracks = fvRecoTracks.size(); + fMonitor.Increment(EMonitorKey::kTrack, nRecoTracks); + fMonitor.Increment(EMonitorKey::kHit, nHits); + // Match tracks and points // Read MC tracks and points if (IsMCUsed()) { @@ -642,6 +648,8 @@ InitStatus OutputQa::InitTimeSlice() nMCPoints = fMCData.GetNofPoints(); nMCTracks = fMCData.GetNofTracks(); fpMCModule->MatchRecoAndMC(); + fMonitor.Increment(EMonitorKey::kMcPoint, nMCPoints); + fMonitor.Increment(EMonitorKey::kMcTrack, nMCTracks); } // ****** DEBUG: BEGIN -- GitLab