From 4c853da934b82531c90005da15c4bac9536eadcb Mon Sep 17 00:00:00 2001 From: Alexandru Bercuci <abercuci@niham.nipne.ro> Date: Tue, 3 May 2022 15:36:10 +0200 Subject: [PATCH] extend the TrdHit Qa data class for digi signals and clusters --- reco/L1/qa/CbmTrackerInputQaTrd.cxx | 123 ++++++++++++++++----- reco/detectors/trd/qa/data/CbmTrdHitMC.cxx | 52 ++++++++- reco/detectors/trd/qa/data/CbmTrdHitMC.h | 38 ++++++- 3 files changed, 177 insertions(+), 36 deletions(-) diff --git a/reco/L1/qa/CbmTrackerInputQaTrd.cxx b/reco/L1/qa/CbmTrackerInputQaTrd.cxx index 8a38cc6143..ecc587141e 100644 --- a/reco/L1/qa/CbmTrackerInputQaTrd.cxx +++ b/reco/L1/qa/CbmTrackerInputQaTrd.cxx @@ -497,13 +497,17 @@ void CbmTrackerInputQaTrd::ResolutionQa() return; } + // construct QA object + CbmTrdHitMC* hmc = new ((*fHitsMc)[imc++]) CbmTrdHitMC(*hit); + hmc->AddCluster(cluster); + uint64_t tdigi = 0; + // custom finder of the digi matches - CbmMatch myHitMatch; for (Int_t iDigi = 0; iDigi < nClusterDigis; iDigi++) { Int_t digiIdx = cluster->GetDigi(iDigi); if (digiIdx < 0 || digiIdx >= nDigis) { - LOG(error) << "TRD cluster: digi index " << digiIdx << " out of range "; + LOG(fatal) << "TRD cluster: digi index " << digiIdx << " out of range "; return; } const CbmTrdDigi* digi = CbmDigiManager::Instance()->Get<CbmTrdDigi>(digiIdx); @@ -513,9 +517,31 @@ void CbmTrackerInputQaTrd::ResolutionQa() } if (digi->GetAddressModule() != address) { - LOG(error) << "TRD hit address " << address << " differs from its digi address " << digi->GetAddressModule(); + std::stringstream ss; + ss << "TRD hit address " << address << " differs from its digi address " << digi->GetAddressModule(); + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } + switch (digi->GetType()) { + case CbmTrdDigi::eCbmTrdAsicType::kFASP: + { + int dt; + double t, r = digi->GetCharge(t, dt); + if (!tdigi) tdigi = digi->GetTimeDAQ(); + if (t > 0) hmc->AddSignal(t, digi->GetTimeDAQ() - tdigi); + if (r > 0) hmc->AddSignal(r, digi->GetTimeDAQ() - tdigi + dt); + break; + } + case CbmTrdDigi::eCbmTrdAsicType::kSPADIC: + hmc->AddSignal(digi->GetCharge(), digi->GetTime()); + break; + default: + LOG(fatal) << "TRD digi type neither SPADIC or FASP"; + return; + } + + const CbmMatch* match = dynamic_cast<const CbmMatch*>(fDigiManager->GetMatch(ECbmModuleId::kTrd, digiIdx)); if (!match) { LOG(fatal) << "TRD digi match " << digiIdx << " not found"; @@ -529,11 +555,19 @@ void CbmTrackerInputQaTrd::ResolutionQa() { // check if the hit match is correct CbmMatch* hitMatch = dynamic_cast<CbmMatch*>(fHitMatches->At(iHit)); - if (hitMatch == nullptr) { LOG(error) << "hit match for TRD hit " << iHit << " doesn't exist"; } + if (hitMatch == nullptr) { + std::stringstream ss; + ss << "hit match for TRD hit " << iHit << " doesn't exist"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); + } else { const CbmLink& link = hitMatch->GetMatchedLink(); if ((link != bestLink) && (link.GetWeight() != bestLink.GetWeight())) { - LOG(error) << "hit match for TRD hit " << iHit << " doesn't correspond to digi matches"; + std::stringstream ss; + ss << "hit match for TRD hit " << iHit << " doesn't correspond to digi matches"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); } } } @@ -547,11 +581,17 @@ void CbmTrackerInputQaTrd::ResolutionQa() nHitPoints++; int iE = fMcEventList->GetEventIndex(link); if (iE < 0 || iE >= nMcEvents) { - LOG(error) << "link points to a non-existing MC event"; + std::stringstream ss; + ss << "link points to a non-existing MC event"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } if (link.GetIndex() >= (int) pointNhits[iE].size()) { - LOG(error) << "link points to a non-existing MC point"; + std::stringstream ss; + ss << "link points to a non-existing MC index"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } pointNhits[iE][link.GetIndex()]++; @@ -563,19 +603,27 @@ void CbmTrackerInputQaTrd::ResolutionQa() // take corresponding MC point // skip hits from the noise digis - if (bestLink.GetIndex() < 0) { continue; } - - // construct QA object - CbmTrdHitMC* hmc = new ((*fHitsMc)[imc++]) CbmTrdHitMC(*hit); - + if (bestLink.GetIndex() < 0) { + std::stringstream ss; + ss << "hit from noise [INFO]"; + hmc->SetErrorMsg(ss.str()); + continue; + } + CbmTrdPoint* p = dynamic_cast<CbmTrdPoint*>(fMcPoints->Get(bestLink)); if (p == nullptr) { - LOG(error) << "link points to a non-existing MC point"; + std::stringstream ss; + ss << "link points to a non-existing MC point"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } if (p->GetModuleAddress() != (int) CbmTrdAddress::GetModuleAddress(address)) { - LOG(error) << "mc point module address differs from the hit module address"; + std::stringstream ss; + ss << "mc point module address differs from the hit module address"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } @@ -593,25 +641,39 @@ void CbmTrackerInputQaTrd::ResolutionQa() double staZ = pGeo->GetZ(); // module->GetZ(); //+ 410; if ((staZ < p->GetZIn() - 1.) || (staZ > p->GetZOut() + 1.)) { - LOG(error) << "TRD station " << StationIndex << ": active material Z[" << p->GetZIn() << " cm," << p->GetZOut() + std::stringstream ss; + ss << "TRD station " << StationIndex << ": active material Z[" << p->GetZIn() << " cm," << p->GetZOut() << " cm] is too far from the nominal station Z " << staZ << " cm"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } // the cut of 1 cm is choosen arbitrary and can be changed if (fabs(hit->GetZ() - staZ) > 1.) { - LOG(error) << "TRD station " << StationIndex << ": hit Z " << hit->GetZ() + std::stringstream ss; + ss << "TRD station " << StationIndex << ": hit Z " << hit->GetZ() << " cm, is too far from the nominal station Z " << staZ << " cm"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } } // residual and pull - if (nHitPoints != 1) continue; // only check residual for non-mixed hits + if (nHitPoints != 1) { + std::stringstream ss; + ss << "hit from mixed hit [INFO] nPoints=" << nHitPoints; + hmc->SetErrorMsg(ss.str()); + continue; // only check residual for non-mixed hits + } double t0 = fMcEventList->GetEventTime(bestLink); if (t0 < 0) { - LOG(error) << "MC event time doesn't exist for a TRD link"; + std::stringstream ss; + ss << "MC event time doesn't exist for a TRD link"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } @@ -632,30 +694,35 @@ void CbmTrackerInputQaTrd::ResolutionQa() y += dz * py / pz; // get particle mass + Int_t pdg(0); double mass = 0; { CbmLink mcTrackLink = bestLink; mcTrackLink.SetIndex(p->GetTrackID()); CbmMCTrack* mcTrack = dynamic_cast<CbmMCTrack*>(fMcTracks->Get(mcTrackLink)); if (!mcTrack) { - LOG(error) << "MC track " << p->GetTrackID() << " doesn't exist"; + std::stringstream ss; + ss << "MC track " << p->GetTrackID() << " doesn't exist"; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } - Int_t pdg = mcTrack->GetPdgCode(); + pdg = mcTrack->GetPdgCode(); if (pdg < 9999999 && ((TParticlePDG*) TDatabasePDG::Instance()->GetParticle(pdg))) { mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass(); } } - hmc->AddPoint(p, t0, mass); - + hmc->AddPoint(p, t0, pdg); + //std::cout << hmc->ToString() << "\n"; + constexpr double speedOfLight = 29.979246; // cm/ns TVector3 mom3; p->Momentum(mom3); t += dz / (pz * speedOfLight) * sqrt(mass * mass + mom3.Mag2()); - double du = hmc->GetDx(); //hit->GetX() - x; - double dv = hmc->GetDy(); //hit->GetY() - y; - double dt = hmc->GetDt(); //hit->GetTime() - t; + double du = hit->GetX() - x; //hmc->GetDx(); //hit->GetX() - x; + double dv = hit->GetY() - y; //hmc->GetDy(); //hit->GetY() - y; + double dt = hit->GetTime() - t; // hmc->GetDt(); //hit->GetTime() - t; double su = hit->GetDx(); double sv = hit->GetDy(); double st = hit->GetTimeError(); @@ -678,8 +745,10 @@ void CbmTrackerInputQaTrd::ResolutionQa() // pulls if ((su < 1.e-5) || (sv < 1.e-5) || (st < 1.e-5)) { - LOG(error) << "TRD hit errors are not properly set: errX " << hit->GetDx() << " errY " << hit->GetDy() << " errT " - << st; + std::stringstream ss; + ss << "TRD hit errors are not properly set: errX " << hit->GetDx() << " errY " << hit->GetDy() << " errT "; + hmc->SetErrorMsg(ss.str()); + LOG(error) << ss.str(); return; } diff --git a/reco/detectors/trd/qa/data/CbmTrdHitMC.cxx b/reco/detectors/trd/qa/data/CbmTrdHitMC.cxx index 48406d78e6..f93565e2ad 100644 --- a/reco/detectors/trd/qa/data/CbmTrdHitMC.cxx +++ b/reco/detectors/trd/qa/data/CbmTrdHitMC.cxx @@ -4,8 +4,12 @@ #include "CbmTrdHitMC.h" +#include <TDatabasePDG.h> +#include <TParticlePDG.h> #include <TVector3.h> +#include <sstream> + //_____________________________________________________________________ CbmTrdHitMC::CbmTrdHitMC() : CbmTrdHit() {} @@ -16,12 +20,26 @@ CbmTrdHitMC::CbmTrdHitMC(const CbmTrdHit& h) : CbmTrdHit(h) {} CbmTrdHitMC::~CbmTrdHitMC() {} //_____________________________________________________________________ -size_t CbmTrdHitMC::AddPoint(const CbmTrdPoint* p, double t, double m) +void CbmTrdHitMC::AddCluster(const CbmTrdCluster* c) +{ + fCluster = *c; +} + +//_____________________________________________________________________ +size_t CbmTrdHitMC::AddPoint(const CbmTrdPoint* p, double t, int id) { - fTrdPoints.push_back(std::make_tuple(CbmTrdPoint(*p), t, m)); + fTrdPoints.push_back(std::make_tuple(CbmTrdPoint(*p), t, id)); return fTrdPoints.size(); } +//_____________________________________________________________________ +size_t CbmTrdHitMC::AddSignal(double s, int t) +{ + printf("hit%dD : s(%f) t(%d)\n", (GetClassType() ? 2 : 1), s, t); + fTrdSignals.push_back(std::make_pair(s, t)); + return fTrdSignals.size(); +} + //_____________________________________________________________________ const CbmTrdPoint* CbmTrdHitMC::GetPoint(uint idx) const { @@ -54,13 +72,39 @@ double CbmTrdHitMC::GetDt() const const CbmTrdPoint* p(nullptr); if (!(p = GetPoint())) return -999; - double t0(std::get<1>(fTrdPoints[0])), mass(std::get<2>(fTrdPoints[0])); - double dz(GetZ() - p->GetZ()), t(t0 + p->GetTime()); + int pdg = std::get<2>(fTrdPoints[0]); + double t0(std::get<1>(fTrdPoints[0])), dz(GetZ() - p->GetZ()), t(t0 + p->GetTime()), mass(0); + TParticlePDG* pmc = (TParticlePDG*) TDatabasePDG::Instance()->GetParticle(pdg); + if (pdg < 9999999 && pmc) mass = pmc->Mass(); + TVector3 mom3; p->Momentum(mom3); t += dz / (p->GetPz() * speedOfLight) * sqrt(mass * mass + mom3.Mag2()); return GetTime() - t; } +//_____________________________________________________________________ +std::string CbmTrdHitMC::ToString() const +{ + std::stringstream ss; + for (auto mcp : fTrdPoints) { + ss << "Event time(ns)=" << std::get<1>(mcp) << " partId=" << std::get<2>(mcp) << "\n"; + ss << std::get<0>(mcp).ToString(); + } + + ss << "CbmTrdDigi: [" << fTrdSignals.size() << "] Signal / Relative Time\n "; + for (auto sgn : fTrdSignals) { + ss << sgn.first << "/" << sgn.second << " "; + } + ss << "\n"; + + ss << fCluster.ToString(); + + ss << CbmTrdHit::ToString(); + + if (fErrMsg != "") ss << "Error : " << fErrMsg << "\n"; + return ss.str(); +} + ClassImp(CbmTrdHitMC) diff --git a/reco/detectors/trd/qa/data/CbmTrdHitMC.h b/reco/detectors/trd/qa/data/CbmTrdHitMC.h index 015b795d2b..a2cff1f130 100644 --- a/reco/detectors/trd/qa/data/CbmTrdHitMC.h +++ b/reco/detectors/trd/qa/data/CbmTrdHitMC.h @@ -7,53 +7,81 @@ #include "CbmTrdHit.h" #include "CbmTrdPoint.h" +#include "CbmTrdCluster.h" -#include <vector> // for vector +#include <vector> // for fTrdPoints +#include <string> // for ToString /** \class CbmTrdHitMC * \brief TRD hit to MC point correlation class * \author Alexandru Bercuci <abercuci@niham.nipne.ro> * \date 02.05.2022 * - * The class + * The class packs the whole history of a TrdHit from the set of MC points generating the signals, + * to information on the digits structure in the cluster and the reconstructed observables. + * The class should be used to make error parametrization, pile-up estimations, etc. + * + * To describe main functionality ... */ class CbmTrdHitMC : public CbmTrdHit { public: /** \brief Default constructor.*/ CbmTrdHitMC(); + /** \brief Standard constructor.*/ CbmTrdHitMC(const CbmTrdHit& hit); + /** \brief Destructor. */ virtual ~CbmTrdHitMC(); + /** \brief Copy cluster details.*/ + void AddCluster(const CbmTrdCluster* c); + /** \brief Add MC points to the hit. The first time this function is called is for the best matched MC point * \param p: pointer to the point being added * \param t: time of the event to which the point belongs * \param m: mass of the particle producing the point * \return the number of points in the list */ - size_t AddPoint(const CbmTrdPoint* p, double t, double m); + size_t AddPoint(const CbmTrdPoint* p, double t, int id); + /** \brief Add signal values in the increasing order of pad index + * \param s signal from ch/pad + * \param t relative time in the cluster + * \return the number of signals in the cluster + */ + size_t AddSignal(double s, int t); - /** \brief Retrieve a MC point + /** \brief Register a MC point * \param idx index of point being requested. by default the best fit is returned. */ const CbmTrdPoint* GetPoint(uint idx = 0) const; /** \brief Calculate residuals in the bending plane.*/ double GetDx() const; + /** \brief Calculate residuals for the azimuth direction.*/ double GetDy() const; + /** \brief Calculate residuals for time.*/ double GetDt() const; + /** \brief Store error message.*/ + void SetErrorMsg(std::string msg) { fErrMsg = msg; } + + /** \brief Verbosity functionality.**/ + virtual std::string ToString() const; + private: /** \brief Copy Constructor.*/ CbmTrdHitMC(const CbmTrdHitMC&) = default; /** \brief Assignment operator.*/ CbmTrdHitMC& operator=(const CbmTrdHitMC&) = default; - std::vector<std::tuple<CbmTrdPoint, double, double>> fTrdPoints = {}; + std::string fErrMsg = ""; //< error message from the QA task + std::vector<std::pair<double, int>> fTrdSignals = {}; //< list of signal/time in cluster + std::vector<std::tuple<CbmTrdPoint, double, int>> fTrdPoints = {}; //< list of MC points together with the event time and particle PDG code producing them + CbmTrdCluster fCluster; //< data from the cluster ClassDef(CbmTrdHitMC, 1) // Hit to MC point data correlation }; -- GitLab