From d9e494ec81e8627307ae398c74302565e32736f3 Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Wed, 26 Oct 2022 20:13:20 +0200 Subject: [PATCH] L1: added writer for reconstructable MC tracks --- macro/run/run_reco.C | 2 + reco/L1/CbmL1.cxx | 13 +++++- reco/L1/CbmL1.h | 38 ++++++++++++++--- reco/L1/CbmL1Performance.cxx | 83 +++++++++++++++++++++++++++++++++++- 4 files changed, 128 insertions(+), 8 deletions(-) diff --git a/macro/run/run_reco.C b/macro/run/run_reco.C index bbb6675c92..5c3a90adc3 100644 --- a/macro/run/run_reco.C +++ b/macro/run/run_reco.C @@ -381,7 +381,9 @@ void run_reco(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice = // L1 tracking auto l1 = (debugWithMC) ? new CbmL1("L1", 2, 3, 0) : new CbmL1("L1", 0); + // L1 configuration file (optional) //l1->SetInputConfigName(TString(gSystem->Getenv("VMCWORKDIR")) + "/reco/L1/L1Algo/L1ConfigExample.yaml"); + if (debugWithMC) { l1->SetOutputMcTracksNtupleFilename("mcTracksNtuple"); } // --- Material budget file names TString mvdGeoTag; diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index 96179436bb..ca0d359f2e 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -49,6 +49,7 @@ #include "TGeoManager.h" #include "TGeoNode.h" #include "TMatrixD.h" +#include "TNtuple.h" #include "TProfile2D.h" #include "TROOT.h" #include "TRandom3.h" @@ -1180,6 +1181,7 @@ void CbmL1::Reconstruct(CbmEvent* event) EfficienciesPerformance(); HistoPerformance(); TrackFitPerformance(); + if (fsMcTracksOutputFilename.size()) { DumpMCTracksToNtuple(); } // TimeHist(); /// WriteSIMDKFData(); } @@ -1228,6 +1230,13 @@ void CbmL1::Finish() outfile->Delete(); } + if (fpMcTracksOutFile) { + fpMcTracksOutFile->cd(); + fpMcTracksTree->Write(); + fpMcTracksOutFile->Close(); + fpMcTracksOutFile->Delete(); + } + gFile = currentFile; gDirectory = curr; fpAlgo->Finish(); @@ -1500,6 +1509,7 @@ void CbmL1::WriteSIMDKFData() } } +// --------------------------------------------------------------------------------------------------------------------- // NOTE: this function should be called before fInitManager.SendParameters(fpAlgo) std::vector<L1Material> CbmL1::ReadMaterialBudget(L1DetectorID detectorID) { @@ -1544,7 +1554,8 @@ std::vector<L1Material> CbmL1::ReadMaterialBudget(L1DetectorID detectorID) return result; } - +// --------------------------------------------------------------------------------------------------------------------- +// double CbmL1::boundedGaus(double sigma) { assert(sigma > 0. && std::isfinite(sigma)); diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 1bccc2849e..f3b5edc187 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -69,6 +69,7 @@ class CbmMCDataObject; class CbmEvent; class TProfile2D; +class TNtuple; /// TODO: SZh 21.09.2022: Replace instances of this class with L1Hit class CbmL1HitStore { @@ -266,6 +267,11 @@ public: /// \param filename Name of the input tracking configuration file void SetOutputConfigName(const char* filename) { fInitManager.SetOutputConfigName(std::string(filename)); } + /// \brief Sets output file for MC tracks ntuple + /// If the filename is empty string, ntuple is not filled + /// \param filename Name of the output file name + void SetOutputMcTracksNtupleFilename(const char* filename) { fsMcTracksOutputFilename = std::string(filename); } + /// Sets flag: to correct input hits on MC or not /// \param flag: true - hits will be corrected on MC information void SetCorrectHitsOnMC(bool flag) { fIfCorrectHitsOnMC = flag; } @@ -399,11 +405,29 @@ private: void InputPerformance(); // Build histograms about input data, like hit pulls, etc. void TimeHist(); - /// Reconstruction Performance - void TrackMatch(); // Procedure for match Reconstructed and MC Tracks. Should be called before Performances - void EfficienciesPerformance(); // calculate efficiencies - void TrackFitPerformance(); // pulls & residuals. Can be called only after Performance() - void HistoPerformance(); // fill some histograms and calculate efficiencies + // ******************************** + // ** Reconstruction Performance ** + // ******************************** + + + /// Matches reconstructed and MC tracks + /// \note Should be called before Performances + void TrackMatch(); + + /// Calculates tracking efficiencies (counters) + void EfficienciesPerformance(); + + /// Builds pulls and residuals + /// \note Should be called only after CbmL1::Performance() + void TrackFitPerformance(); + + /// Fills performance histograms + void HistoPerformance(); + + /// Writes MC tracks to ntuple + /// \note Executed only if the filename for MC tracks ntuple output is defined + void DumpMCTracksToNtuple(); + // ** STandAlone Package service-functions ** @@ -636,13 +660,15 @@ private: static const int fNGhostHistos = 9; TH1F* fGhostHisto[fNGhostHistos] {nullptr}; + TFile* fpMcTracksOutFile = nullptr; ///< File to save MC-tracks ntuple + TNtuple* fpMcTracksTree = nullptr; ///< Ntuple to save MC-tracks + std::string fsMcTracksOutputFilename = ""; ///< Name of file to save MC-tracks ntuple int fFindParticlesMode {0}; // 0 - don't run FindParticles // 1 - run, all MC particle is reco-able // 2 - run, MC particle is reco-able if created from reco-able tracks // 3 - run, MC particle is reco-able if created from reconstructed tracks - std::unordered_map<L1DetectorID, TString> fMatBudgetFileName {}; ///< Map for material budget file names vs. detectorID diff --git a/reco/L1/CbmL1Performance.cxx b/reco/L1/CbmL1Performance.cxx index ed597abe04..3bfd392054 100644 --- a/reco/L1/CbmL1Performance.cxx +++ b/reco/L1/CbmL1Performance.cxx @@ -37,13 +37,17 @@ #include "CbmTrdHit.h" #include "CbmTrdPoint.h" +#include "FairRunAna.h" #include "FairTrackParam.h" // for vertex pulls +#include "TFile.h" #include "TH1.h" #include "TH2.h" #include "TMath.h" +#include "TNtuple.h" #include "TProfile.h" -#include <TFile.h> + +#include <boost/filesystem.hpp> #include <iostream> #include <list> @@ -2244,3 +2248,80 @@ void CbmL1::InputPerformance() } // void CbmL1::InputPerformance() + +// --------------------------------------------------------------------------------------------------------------------- +// +void CbmL1::DumpMCTracksToNtuple() +{ + if (!fpMcTracksTree) { + auto* currentDir = gDirectory; + auto* currentFile = gFile; + + + // Get prefix and directory + boost::filesystem::path p = (FairRunAna::Instance()->GetUserOutputFileName()).Data(); + std::string dir = p.parent_path().string(); + if (dir.empty()) dir = "."; + std::string filename = dir + "/" + fsMcTracksOutputFilename + "." + p.filename().string(); + std::cout << "\033[1;31mSAVING A TREE: " << filename << "\033[0m\n"; + + fpMcTracksOutFile = new TFile(filename.c_str(), "RECREATE"); + fpMcTracksOutFile->cd(); + fpMcTracksTree = new TNtuple("t", "McTracks", "motherId:pdg:p:q:zv:s:x0:y0:z0:x1:y1:z1:x2:y2:z2"); + // motherID - id of mother particle (< 0, if primary) + // pdg - PDG code of particle + // p - absolute value of track momentum [GeV/c] + // q - charge of track [e] + // zv - z-component of track vertex [cm] + // s - global index of station + // x0, y0, z0 - position of the left MC point in a triplet [cm] + // x1, y1, z1 - position of the middle MC point in a triplet [cm] + // x2, y2, z2 - position of the right MC point in a triplet [cm] + + gFile = currentFile; + gDirectory = currentDir; + } + + struct ReducedMcPoint { + int s; ///< global active index of tracking station + float x; ///< x-component of point position [cm] + float y; ///< y-component of point position [cm] + float z; ///< z-component of point position [cm] + bool operator<(const ReducedMcPoint& other) { return s < other.s; } + }; + + for (const auto& tr : fvMCTracks) { + // Use only reconstructable tracks + if (!tr.IsReconstructable()) { continue; } + + std::vector<ReducedMcPoint> vPoints; + vPoints.reserve(tr.Points.size()); + for (unsigned int iP = 0; iP < tr.Points.size(); ++iP) { + const auto& point = fvMCPoints[tr.Points[iP]]; + vPoints.emplace_back(ReducedMcPoint {point.iStation, float(point.x), float(point.y), float(point.z)}); + } + + std::sort(vPoints.begin(), vPoints.end()); + for (unsigned int i = 0; i + 2 < vPoints.size(); ++i) { + // Condition to collect only triplets without gaps in stations + // TODO: SZh 20.10.2022 Add cases for jump iterations + if (vPoints[i + 1].s == vPoints[i].s + 1 && vPoints[i + 2].s == vPoints[i].s + 2) { + fpMcTracksTree->Fill(tr.mother_ID, ///< index of mother particle + tr.pdg, ///< PDG code + tr.p, ///< absolute value of track momentum [GeV/c] + tr.q, ///< charge of track [e] + tr.z, ///< z-position of track vertex [cm] + vPoints[i].s, ///< global index of active tracking station + vPoints[i].x, ///< x-component of the left MC point in a triplet [cm] + vPoints[i].y, ///< y-component of the left MC point in a triplet [cm] + vPoints[i].z, ///< z-component of the left MC point in a triplet [cm] + vPoints[i + 1].x, ///< x-component of the middle MC point in a triplet [cm] + vPoints[i + 1].y, ///< y-component of the middle MC point in a triplet [cm] + vPoints[i + 1].z, ///< z-component of the middle MC point in a triplet [cm] + vPoints[i + 2].x, ///< x-component of the right MC point in a triplet [cm] + vPoints[i + 2].y, ///< y-component of the right MC point in a triplet [cm] + vPoints[i + 2].z); ///< z-component of the right MC point in a triplet [cm] + } + } + } +} -- GitLab