diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx index e5533656fdbecb74698764942bb6441e194c270b..a16a285ef205c7e51df9dd23289d0b6c58ba087c 100644 --- a/algo/ca/TrackingChain.cxx +++ b/algo/ca/TrackingChain.cxx @@ -174,7 +174,6 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi xpu::t_add_bytes(hits.NElements() * sizeof(Hit_t)); // Assumes call from Run, for existence of timer! - ca::HitKeyIndex_t firstHitKey = fNofHitKeys; int64_t dataStreamDet = static_cast<int64_t>(DetID) << 60; // detector part of the data stream int64_t dataStream = 0; for (size_t iPartition = 0; iPartition < hits.NPartitions(); ++iPartition, ++dataStream) { @@ -201,6 +200,7 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi } double lastTime = -1e9; double prevTime = -1; + ca::HitKeyIndex_t firstHitKey = fNofHitKeys; for (size_t iPartHit = 0; iPartHit < vHits.size(); ++iPartHit) { const auto& hit = vHits[iPartHit]; int iHitExt = iOffset + iPartHit; @@ -209,6 +209,7 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi if constexpr (IsSts) { caHit.SetFrontKey(firstHitKey + hit.fFrontClusterId); caHit.SetBackKey(firstHitKey + hit.fBackClusterId); + //L_(info) << ", hit=" << iHitExt << ", f=" << hit.fFrontClusterId << ", b=" << hit.fBackClusterId; } else { caHit.SetFrontKey(firstHitKey + iHitExt); diff --git a/algo/ca/core/CMakeLists.txt b/algo/ca/core/CMakeLists.txt index 566fbed38071a4db66aa23f6268d27ff8193e949..90a19d9f5276d5dd97f5d8a885243ce57f29aaf1 100644 --- a/algo/ca/core/CMakeLists.txt +++ b/algo/ca/core/CMakeLists.txt @@ -19,6 +19,7 @@ set(SRCS ${CMAKE_CURRENT_SOURCE_DIR}/data/CaMeasurementXy.cxx ${CMAKE_CURRENT_SOURCE_DIR}/data/CaMeasurementTime.cxx ${CMAKE_CURRENT_SOURCE_DIR}/data/CaWindowData.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/data/CaTimesliceHeader.cxx ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaConfigReader.cxx ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaField.cxx ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaInitManager.cxx @@ -93,6 +94,7 @@ install( data/CaTriplet.h data/CaBranch.h data/CaWindowData.h + data/CaTimesliceHeader.h pars/CaConstants.h pars/CaField.h pars/CaInitManager.h diff --git a/algo/ca/core/data/CaHit.h b/algo/ca/core/data/CaHit.h index b013a13da058695b54f4b75b7349207c6233578c..fb0551ee784616df3f315d783dd3fd857b05314e 100644 --- a/algo/ca/core/data/CaHit.h +++ b/algo/ca/core/data/CaHit.h @@ -16,6 +16,13 @@ namespace cbm::algo::ca { + struct CaHitTimeInfo { + fscal fEventTimeMin{-std::numeric_limits<fscal>::max() / 2.}; + fscal fEventTimeMax{std::numeric_limits<fscal>::max() / 2.}; + fscal fMaxTimeBeforeHit{0.}; //< max event time for hits [0 .. hit] in the station hit array + fscal fMinTimeAfterHit{0.}; //< min event time for hits [hit ... ] in the station hit array + }; + // FIXME: Move typedefs to another header (potential problems with dependencies) using HitIndex_t = unsigned int; ///< Index of ca::Hit using HitKeyIndex_t = unsigned int; ///< Index of the hit key (e.g. front / back cluster id for STS) diff --git a/algo/ca/core/data/CaTimesliceHeader.cxx b/algo/ca/core/data/CaTimesliceHeader.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f0e543305168616814ca2a3abade895777e8c0e1 --- /dev/null +++ b/algo/ca/core/data/CaTimesliceHeader.cxx @@ -0,0 +1,25 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CaTimesliceHeader.cxx +/// \brief A structure to keep all the common information on the timeslice coming from tracking (implementation) +/// \since 15.02.2024 +/// \author Sergei Zharko <s.zharko@gsi.de> + +#pragma once + +#include "CaTimesliceHeader.h" + +#include <sstream> + +using cbm::algo::ca::TimesliceHeader; + +// --------------------------------------------------------------------------------------------------------------------- +// +std::string TimesliceHeader::ToString() const +{ + std::stringstream msg; + msg << "TimesliceHeader: start = " << fStart << " [ns], end = " << fEnd << " [ns]"; + return msg.str(); +} diff --git a/algo/ca/core/data/CaTimesliceHeader.h b/algo/ca/core/data/CaTimesliceHeader.h new file mode 100644 index 0000000000000000000000000000000000000000..7fc20004f69ae26d41daf723de0c3c49ef7f0611 --- /dev/null +++ b/algo/ca/core/data/CaTimesliceHeader.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CaTimesliceHeader.h +/// \brief A structure to keep all the common information on the timeslice coming from tracking +/// \since 15.02.2024 +/// \author Sergei Zharko <s.zharko@gsi.de> + +#pragma once + +#include <string> + +namespace cbm::algo::ca +{ + /// \class TimesliceHeader + /// \brief Structure for keeping the current information on the timeslice + class TimesliceHeader { + public: + /// \brief Accesses the end of timeslice [ns] + float& End() { return fEnd; } + float End() const { return fEnd; } + + /// \brief Accesses the start of timeslice [ns] + float& Start() { return fStart; } + float Start() const { return fStart; } + + /// \brief String representation of the contents + std::string ToString() const; + + /// \brief Converts time from ns to tau + float ConvToTau(float time) const { return (time - fStart) / (fEnd - fStart); } + + /// \brief Converts time from tau to ns + float ConvToNs(float tau) const { return fStart + tau * (fEnd - fStart); } + + private: + float fStart; ///< Start of timeslice + float fEnd; ///< End of timeslice + }; +} // namespace cbm::algo::ca diff --git a/algo/ca/core/data/CaWindowData.h b/algo/ca/core/data/CaWindowData.h index 67269e9533f11712885b8ec3d3ffcf026bf56c0a..b599ae6a03da1658eed297236b0208e01f3c5712 100644 --- a/algo/ca/core/data/CaWindowData.h +++ b/algo/ca/core/data/CaWindowData.h @@ -192,9 +192,6 @@ namespace cbm::algo::ca /// \brief Sample of reconstructed hit indices Vector<HitIndex_t> fvRecoHitIndices{"WindowData::fvRecoHitIndices"}; - /// \brief Sample of track candidates - Vector<Track> fvTrackCandidates{"WindowData::fvTrackCandidates"}; - /// \brief Map of hit indices from the time window to the time slice std::array<Vector<HitIndex_t>, kMaxNofStations> fvTsHitIndices{"WindowData::fvFullDSHitIndex"}; diff --git a/algo/ca/core/tracking/CaFramework.h b/algo/ca/core/tracking/CaFramework.h index 74b85031a249962b7dc88a1ea7d273ce42b559c8..40943de475ca7acab36411dd0e4684b0ca12f1b6 100644 --- a/algo/ca/core/tracking/CaFramework.h +++ b/algo/ca/core/tracking/CaFramework.h @@ -16,9 +16,9 @@ #include "CaParameters.h" #include "CaStation.h" #include "CaTimer.h" +#include "CaTimesliceHeader.h" #include "CaTrack.h" #include "CaTrackExtender.h" -#include "CaTrackExtraInfo.h" #include "CaTrackFinder.h" #include "CaTrackFinderWindow.h" #include "CaTrackFitter.h" @@ -59,12 +59,6 @@ namespace cbm::algo::ca using CaMaterialArray_t = std::array<ca::MaterialMap, constants::size::MaxNstations>; using Tindex = int; // TODO: Replace with ca::HitIndex_t, if suitable - struct CaHitTimeInfo { - fscal fEventTimeMin{-std::numeric_limits<fscal>::max() / 2.}; - fscal fEventTimeMax{std::numeric_limits<fscal>::max() / 2.}; - fscal fMaxTimeBeforeHit{0.}; //< max event time for hits [0 .. hit] in the station hit array - fscal fMinTimeAfterHit{0.}; //< min event time for hits [hit ... ] in the station hit array - }; /// Main class of CA track finder algorithm /// @@ -167,6 +161,8 @@ namespace cbm::algo::ca /// \return particle mass squared float GetDefaultParticleMass2() const { return fDefaultMass * fDefaultMass; } + /// \brief Gets timeslice header + const TimesliceHeader& GetTsHeader() const { return fTsHeader; } /*********************************************************************************************/ /** * ------ FUNCTIONAL PART ------ @@ -200,21 +196,22 @@ namespace cbm::algo::ca // const CbmL1MCTrack* GetMcTrackForWindowHit(int iHit) const; + /// \brief Sets number of threads void SetNofThtreads(int nThreads) { fNofThreads = nThreads; + assert(nThreads > 0); LOG(info) << "ca::Framework: number of threads is set to " << fNofThreads; } + /// \brief Gets number of threads int GetNofThreads() const { return fNofThreads; } - bool IfCollectTrackExtraInfo() const { return fbCollectTrackExtraInfo; } - private: int fNstationsBeforePipe{0}; ///< number of stations before pipe (MVD stations in CBM) int fNfieldStations{0}; ///< number of stations in the field region float fDefaultMass{constants::phys::MuonMass}; ///< mass of the propagated particle [GeV/c2] - + TimesliceHeader fTsHeader; ///< current timeslice header // *************************** // ** Member variables list ** @@ -223,11 +220,9 @@ namespace cbm::algo::ca Parameters<fvec> fParameters; ///< Object of Framework parameters class InputData fInputData; ///< Tracking input data - bool fbCollectTrackExtraInfo = true; ///< Flag, if to fill the additional track info structure - TrackingMonitorData fMonitorData{}; ///< Tracking monitor data (statistics per call) - int fNofThreads = 10; ///< Number of threads to execute the track-finder + int fNofThreads = 1; ///< Number of threads to execute the track-finder public: Vector<CaHitTimeInfo> fHitTimeInfo; @@ -242,7 +237,6 @@ namespace cbm::algo::ca double fCaRecoTime{0.}; // time of the track finder + fitter Vector<Track> fRecoTracks{"Framework::fRecoTracks"}; ///< reconstructed tracks - Vector<TrackExtraInfo> fRecoTrackExtraInfo{"Framework::fRecoTrackExtraInfo"}; ///< Extra info on tracks Vector<ca::HitIndex_t> fRecoHits{"Framework::fRecoHits"}; ///< packed hits of reconstructed tracks fvec EventTime{0.f}; diff --git a/algo/ca/core/tracking/CaTrackFinder.cxx b/algo/ca/core/tracking/CaTrackFinder.cxx index 96bc482b184e26a3a1fb912d4f68091775a2b1a1..a18dec3502e4d7a9e9ca4d94f2c01437ff50a1ff 100644 --- a/algo/ca/core/tracking/CaTrackFinder.cxx +++ b/algo/ca/core/tracking/CaTrackFinder.cxx @@ -62,10 +62,6 @@ void TrackFinder::FindTracks() for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) { fvRecoTracks[iThread].clear(); fvRecoTracks[iThread].reserve(nTracksExpected / frAlgo.GetNofThreads()); - if (frAlgo.IfCollectTrackExtraInfo()) { - fvRecoTrackExtraInfo[iThread].clear(); - fvRecoTrackExtraInfo[iThread].reserve(nTracksExpected / frAlgo.GetNofThreads()); - } fvRecoHitIndices[iThread].clear(); fvRecoHitIndices[iThread].reserve(nHitsExpected / frAlgo.GetNofThreads()); frAlgo.fvTrackFinderWindow[iThread].InitTimeslice(); @@ -213,6 +209,9 @@ void TrackFinder::FindTracks() for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) { fvWindowStartThread[iThread] = fStatTsStart + iThread * threadDuration; fvWindowEndThread[iThread] = fvWindowStartThread[iThread] + threadDuration; + if (iThread > 0) { + fvWindowStartThread[iThread] += 200; + } LOG(info) << "Thread: " << iThread << " from " << fvWindowStartThread[iThread] / 1.e6 << " ms to " << fvWindowEndThread[iThread] / 1.e6 << " ms"; } @@ -261,6 +260,11 @@ void TrackFinder::FindTracks() statNwindowsTotal += fvStatNwindows[iThread]; } + // Filling TS headear + auto& tsHeader = frAlgo.fTsHeader; + tsHeader.Start() = fStatTsStart; + tsHeader.End() = fStatTsEnd; + LOG(info) << "CA tracker: time slice finished. Reconstructed " << frAlgo.fRecoTracks.size() << " tracks with " << frAlgo.fRecoHits.size() << " hits. Processed " << statNhitsProcessedTotal << " hits in " << statNwindowsTotal << " time windows. Reco time " << frAlgo.fCaRecoTime / 1.e9 << " s"; @@ -274,26 +278,29 @@ void TrackFinder::FindTracksThread(int iThread) const int nDataStreams = frAlgo.fInputData.GetNdataStreams(); bool areUntouchedDataLeft = true; // is the whole TS processed std::vector<HitIndex_t> sliceFirstHit(nDataStreams, 0); + std::vector<HitIndex_t> sliceLastHit(nDataStreams, 0); auto& wData = frAlgo.fvWData[iThread]; // Define first hit, skip all the hits, which are before the first window for (int iStream = 0; iStream < nDataStreams; ++iStream) { sliceFirstHit[iStream] = frAlgo.fInputData.GetStreamStartIndex(iStream); - HitIndex_t caLstId = frAlgo.fInputData.GetStreamStopIndex(iStream); - HitIndex_t caFstId = sliceFirstHit[iStream]; - for (HitIndex_t caHitId = caFstId; caHitId < caLstId; ++caHitId) { + sliceLastHit[iStream] = frAlgo.fInputData.GetStreamStopIndex(iStream); + for (HitIndex_t caHitId = sliceFirstHit[iStream]; caHitId < sliceLastHit[iStream]; ++caHitId) { CaHitTimeInfo& info = frAlgo.fHitTimeInfo[caHitId]; const ca::Hit& h = frAlgo.fInputData.GetHit(caHitId); if (wData.IsHitKeyUsed(h.FrontKey()) || wData.IsHitKeyUsed(h.BackKey())) { continue; } if (info.fMaxTimeBeforeHit < fvWindowStartThread[iThread]) { - // this hit and all hits before are before the overlap sliceFirstHit[iStream] = caHitId + 1; } + if (info.fMinTimeAfterHit > fvWindowEndThread[iThread]) { + sliceLastHit[iStream] = caHitId; + } } } + fvStatNwindows[iThread] = 0; fvStatNhitsProcessed[iThread] = 0; @@ -316,14 +323,10 @@ void TrackFinder::FindTracksThread(int iThread) Timer tHitInit; tHitInit.Start(); - int nLoops1 = 0; - int nLoops2 = 0; for (int iStream = 0; iStream < nDataStreams; ++iStream) { - for (ca::HitIndex_t caHitId = sliceFirstHit[iStream]; caHitId < frAlgo.fInputData.GetStreamStopIndex(iStream); - ++caHitId) { - nLoops1++; - CaHitTimeInfo& info = frAlgo.fHitTimeInfo[caHitId]; - const ca::Hit& h = frAlgo.fInputData.GetHit(caHitId); + for (ca::HitIndex_t caHitId = sliceFirstHit[iStream]; caHitId < sliceLastHit[iStream]; ++caHitId) { + const CaHitTimeInfo& info = frAlgo.fHitTimeInfo[caHitId]; + const ca::Hit& h = frAlgo.fInputData.GetHit(caHitId); if (wData.IsHitKeyUsed(h.FrontKey()) || wData.IsHitKeyUsed(h.BackKey())) { // the hit is already reconstructed continue; @@ -344,10 +347,8 @@ void TrackFinder::FindTracksThread(int iThread) // this hit and all hits before are before the overlap sliceFirstHit[iStream] = caHitId + 1; } - //LOG(warning) << "event time " << ((float) info.fEventTimeMax )<< " " << h.ToString(); } } // else the hit has been alread processed in previous sub-slices - nLoops2++; } } fvStatNhitsProcessed[iThread] += statNwindowHits; @@ -427,14 +428,6 @@ void TrackFinder::FindTracksThread(int iThread) } else { // save the track fvRecoTracks[iThread].push_back(track); - if (frAlgo.IfCollectTrackExtraInfo()) { - auto trkInfo = TrackExtraInfo(); - trkInfo.fTimeStart = (track.fParFirst.GetTime() - fStatTsStart) / (fStatTsEnd - fStatTsStart); - trkInfo.fTimeEnd = (track.fParLast.GetTime() - fStatTsStart) / (fStatTsEnd - fStatTsStart); - trkInfo.fThreadId = iThread; - fvRecoTrackExtraInfo[iThread].push_back(trkInfo); - } - // mark the track hits as used for (int i = 0; i < track.fNofHits; i++) { int caHitId = frAlgo.fvWData[iThread].RecoHitIndex(trackFirstHit + i); @@ -475,18 +468,9 @@ void TrackFinder::Init() fvRecoHitIndices.clear(); fvRecoHitIndices.resize(frAlgo.GetNofThreads()); - if (frAlgo.IfCollectTrackExtraInfo()) { - fvRecoTrackExtraInfo.clear(); - fvRecoTrackExtraInfo.resize(frAlgo.GetNofThreads()); - } - for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) { fvRecoTracks[iThread].SetName(std::string("TrackFinder::fvRecoTracks_") + std::to_string(iThread)); fvRecoHitIndices[iThread].SetName(std::string("TrackFinder::fvRecoHitIndices_") + std::to_string(iThread)); - if (frAlgo.IfCollectTrackExtraInfo()) { - fvRecoTrackExtraInfo[iThread].SetName(std::string("TrackFinder::fvRecoTrackExtraInfo_") - + std::to_string(iThread)); - } } fWindowLength = (ca::Framework::TrackingMode::kMcbm == frAlgo.fTrackingMode) ? 500 : 10000; diff --git a/algo/ca/core/tracking/CaTrackFinder.h b/algo/ca/core/tracking/CaTrackFinder.h index 107f81a3355a6322dc592a016720aa0cb7ef2e73..f6f7c5a99752e23d651023af34d8ce817c6748c2 100644 --- a/algo/ca/core/tracking/CaTrackFinder.h +++ b/algo/ca/core/tracking/CaTrackFinder.h @@ -51,6 +51,9 @@ namespace cbm::algo::ca void FindTracksThread(int iThread); void Init(); + const auto& GetRecoTracksContainer(int iThread) const { return fvRecoTracks[iThread]; } + const auto& GetRecoHitIndicesContainer(int iThread) const { return fvRecoHitIndices[iThread]; } + private: // ------------------------------- // Private methods @@ -70,9 +73,8 @@ namespace cbm::algo::ca std::vector<int> fvStatNwindows; std::vector<int> fvStatNhitsProcessed; - std::vector<Vector<Track>> fvRecoTracks; ///< reconstructed tracks - std::vector<Vector<TrackExtraInfo>> fvRecoTrackExtraInfo; ///< Extra info on tracks - std::vector<Vector<ca::HitIndex_t>> fvRecoHitIndices; ///< packed hits of reconstructed tracks + std::vector<Vector<Track>> fvRecoTracks; ///< reconstructed tracks + std::vector<Vector<HitIndex_t>> fvRecoHitIndices; ///< packed hits of reconstructed tracks float fWindowLength = 0.; float fWindowOverlap = 15.; // ns diff --git a/algo/ca/core/tracking/CaTrackFinderWindow.cxx b/algo/ca/core/tracking/CaTrackFinderWindow.cxx index 646185bc5945c6950b87503ae124738a88d046d5..a1886d9bfd4b8fbb1f45eaa06569fff8f37fe1c1 100644 --- a/algo/ca/core/tracking/CaTrackFinderWindow.cxx +++ b/algo/ca/core/tracking/CaTrackFinderWindow.cxx @@ -427,6 +427,7 @@ void TrackFinderWindow::CaTrackFinderSlice() fvTrackCandidates.clear(); + fvTrackCandidates.reserve(frWData.Hits().size() / 10); for (const auto& h : frWData.Hits()) { fvHitKeyToTrack[h.FrontKey()] = -1; diff --git a/algo/ca/qa/CaQaBuilder.cxx b/algo/ca/qa/CaQaBuilder.cxx index a319fd510f9e7eee27296542b8a1c0ee7d3d1196..5a690e7fc776c92d1e8abbceda8ab961554b454f 100644 --- a/algo/ca/qa/CaQaBuilder.cxx +++ b/algo/ca/qa/CaQaBuilder.cxx @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2023-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Sergei Zharko [committer] */ @@ -28,6 +28,8 @@ using cbm::algo::ca::qa::Builder; // void Builder::Init() { + using fmt::format; + if (!fpSender.get()) { return; } @@ -38,23 +40,23 @@ void Builder::Init() std::array<std::string, knTrkParPoints> vsPointName = {"first", "last"}; for (int i = 0; i < knTrkParPoints; ++i) { { - auto sName = fmt::format("track_{}_theta", vsPointName[i]); - auto sTitl = fmt::format("#theta at {} hit; #theta", vsPointName[i]); + auto sName = format("track_{}_theta", vsPointName[i]); + auto sTitl = format("#theta at {} hit; #theta", vsPointName[i]); fvphTrkTheta[i] = fQaData.MakeObj<Histo1D>(62, 0., 90., sName, sTitl); } { - auto sName = fmt::format("track_{}_phi", vsPointName[i]); - auto sTitl = fmt::format("#phi at {} hit; #phi", vsPointName[i]); + auto sName = format("track_{}_phi", vsPointName[i]); + auto sTitl = format("#phi at {} hit; #phi", vsPointName[i]); fvphTrkPhi[i] = fQaData.MakeObj<Histo1D>(62, -180., 180., sName, sTitl); } { - auto sName = fmt::format("track_{}_chi2_ndf", vsPointName[i]); - auto sTitl = fmt::format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]); + auto sName = format("track_{}_chi2_ndf", vsPointName[i]); + auto sTitl = format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]); fvphTrkChi2Ndf[i] = fQaData.MakeObj<Histo1D>(100, 0., 20., sName, sTitl); } { - auto sName = fmt::format("track_{}_hit_station", vsPointName[i]); - auto sTitl = fmt::format("Station of {} hit;ID_{{sta}}", vsPointName[i]); + auto sName = format("track_{}_hit_station", vsPointName[i]); + auto sTitl = format("Station of {} hit;ID_{{sta}}", vsPointName[i]); fvphHitSta[i] = fQaData.MakeObj<Histo1D>(100, -.5, 10.5, sName, sTitl); } } @@ -125,26 +127,29 @@ void Builder::Build() } // Fill track histograms - int trkFirstHit = 0; // Index of hit in fpvRecoHits - for (auto& track : (*fpvTracks)) { - int nHits = track.fNofHits; - // Indices of hits in fpInputData->GetHits() - int iFstHit = (*fpvRecoHits)[trkFirstHit]; - int iLstHit = (*fpvRecoHits)[trkFirstHit + nHits - 1]; - - // Distributions in different track points - for (int ip = 0; ip < knTrkParPoints; ++ip) { - int iHit = (ip == 0 ? iFstHit : iLstHit); - const auto& trkPar = (ip == 0 ? track.fParFirst : track.fParLast); - const auto& hit = fpInputData->GetHit(iHit); - fvphTrkTheta[ip]->Add(trkPar.GetTheta() * 180. / Pi); - fvphTrkPhi[ip]->Add(trkPar.GetPhi() * 180. / Pi); - fvphTrkChi2Ndf[ip]->Add(trkPar.GetChiSq() / trkPar.GetNdf()); - fvphHitSta[ip]->Add(hit.Station()); + { + int trkFirstHit = 0; // Index of hit in fpvRecoHits + for (auto trkIt = fpvTracks->begin(); trkIt != fpvTracks->end(); ++trkIt) { + auto& track = *trkIt; + int nHits = track.fNofHits; + // Indices of hits in fpInputData->GetHits() + int iFstHit = (*fpvRecoHits)[trkFirstHit]; + int iLstHit = (*fpvRecoHits)[trkFirstHit + nHits - 1]; + + // Distributions in different track points + for (int ip = 0; ip < knTrkParPoints; ++ip) { + int iHit = (ip == 0 ? iFstHit : iLstHit); + const auto& trkPar = (ip == 0 ? track.fParFirst : track.fParLast); + const auto& hit = fpInputData->GetHit(iHit); + fvphTrkTheta[ip]->Add(trkPar.GetTheta() * 180. / Pi); + fvphTrkPhi[ip]->Add(trkPar.GetPhi() * 180. / Pi); + fvphTrkChi2Ndf[ip]->Add(trkPar.GetChiSq() / trkPar.GetNdf()); + fvphHitSta[ip]->Add(hit.Station()); + } + // Other distributions + fphTrkNofHits->Add(nHits); + trkFirstHit += nHits; } - // Other distributions - fphTrkNofHits->Add(nHits); - trkFirstHit += nHits; } fQaData.Send(fpSender); diff --git a/algo/ca/qa/CaQaBuilder.h b/algo/ca/qa/CaQaBuilder.h index f9a6748f953c37066da641ef9a6dd5b031de7cb1..ff3293acdbbf5c2f5587d7532322f4beaae45f9a 100644 --- a/algo/ca/qa/CaQaBuilder.h +++ b/algo/ca/qa/CaQaBuilder.h @@ -10,7 +10,7 @@ #pragma once #include "CaHit.h" // for HitIndex_t -#include "CaQaBuilder.h" +#include "CaTimesliceHeader.h" #include "CaVector.h" #include "QaData.h" @@ -84,14 +84,13 @@ namespace cbm::algo::ca::qa /// \note Call per run void RegisterParameters(const Parameters<fvec>* pParameters) { fpParameters = pParameters; } - private: QaData fQaData{"CaQa"}; ///< QA data std::shared_ptr<HistogramSender> fpSender = nullptr; ///< Histogram sender const Parameters<fvec>* fpParameters = nullptr; ///< Pointer to tracking parameters - const Vector<Track>* fpvTracks = nullptr; ///< Pointer to tracks vector const InputData* fpInputData = nullptr; ///< Pointer to input data + const Vector<Track>* fpvTracks = nullptr; ///< Pointer to tracks vector const Vector<HitIndex_t>* fpvRecoHits = nullptr; ///< Pointer to reco hit indices // ----- List of the histograms ------------------------------------------------------------------------------------ diff --git a/algo/qa/CanvasConfig.cxx b/algo/qa/CanvasConfig.cxx index 449eba144c4b56f87d38740ed3151748f9f71a0b..bfbb99c2f282468095454d3c93316c22e84756b1 100644 --- a/algo/qa/CanvasConfig.cxx +++ b/algo/qa/CanvasConfig.cxx @@ -9,6 +9,7 @@ #include "CanvasConfig.h" +#include <log.hpp> #include <sstream> using cbm::algo::CanvasConfig; @@ -49,8 +50,15 @@ std::string CanvasConfig::ToString() const std::stringstream cfg; cfg << fsName << ';' << fsTitle << ';' << fNofPadsX << ';' << fNofPadsY; - for (const auto& padCfg : fvsPadConfigs) { - cfg << ';' << padCfg; + if (fvsPadConfigs.empty()) { + L_(warning) << "CanvasConfig::ToString(): creating a config message for an empty pad"; + auto pad = PadConfig(); + cfg << ';' << pad.ToString(); + } + else { + for (const auto& padCfg : fvsPadConfigs) { + cfg << ';' << padCfg; + } } return cfg.str(); } diff --git a/algo/qa/PadConfig.cxx b/algo/qa/PadConfig.cxx index 5743b665a6a6c63e741944642b61a2c1dbb2425b..4b9d1a0394e6fbd4005f91410daca602c85fabe8 100644 --- a/algo/qa/PadConfig.cxx +++ b/algo/qa/PadConfig.cxx @@ -9,6 +9,7 @@ #include "PadConfig.h" +#include <log.hpp> #include <sstream> using cbm::algo::PadConfig; @@ -37,7 +38,8 @@ std::string PadConfig::ToString() const std::stringstream cfg; cfg << fbGridX << ',' << fbGridY << ',' << fbLogX << ',' << fbLogY << ',' << fbLogZ; if (fvObjectList.empty()) { - cfg << ','; + L_(warning) << "PadConfig::ToString(): creating a config message for an empty pad"; + cfg << ",(nullptr,nullptr)"; } else { for (const auto& [name, opt] : fvObjectList) { diff --git a/macro/run/run_qa.C b/macro/run/run_qa.C index 47bfa43c0d62a14a0bbe38780bf0435917f29577..2f85dd770057b367745da4d32d42d532d79d9321 100644 --- a/macro/run/run_qa.C +++ b/macro/run/run_qa.C @@ -207,7 +207,7 @@ void run_qa(TString dataTraColl, FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile); auto* qaManager = new CbmQaManager(verbose); - qaManager->SetConfigName(qaConfig); + //qaManager->SetConfigName(qaConfig); if (!sBenchmark.IsNull()) { qaManager->OpenBenchmarkInput(sBenchmark); qaManager->OpenBenchmarkOutput(benchmarkOut);