diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt index 53f1bba9bd17544a717924199bc5e70bea5dc7c2..3def910df0366de12129af0657227a66871b7f0e 100644 --- a/reco/L1/CMakeLists.txt +++ b/reco/L1/CMakeLists.txt @@ -148,6 +148,8 @@ L1Algo/L1CAIteration.cxx L1Algo/L1BaseStationInfo.cxx L1Algo/L1InitManager.cxx L1Algo/L1Parameters.cxx +L1Algo/L1InputData.cxx +L1Algo/L1IODataManager.cxx L1Algo/L1ClonesMerger.cxx L1Algo/L1ConfigRW.cxx L1Algo/utils/L1AlgoDraw.cxx @@ -286,6 +288,8 @@ Install(FILES CbmL1Counters.h L1Algo/L1InitManager.h L1Algo/L1CAIteration.h L1Algo/L1Parameters.h + L1Algo/L1InputData.h + L1Algo/L1IODataManager.h L1Algo/L1ClonesMerger.h L1Algo/L1ConfigRW.h L1Algo/L1Constants.h diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index 00220d4a86b21743721d76fa15254cb6ef0c64e1..9be1b80d694dd4b23247549f6c3fc654e1b1ee2e 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -76,7 +76,7 @@ using std::ios; ClassImp(CbmL1); -static L1Algo gAlgo _fvecalignment; // TODO: gAlgo +static L1Algo gAlgo _fvecalignment; // TODO: Change coupling logic between L1Algo and CbmL1 //L1AlgoInputData* fData_static _fvecalignment; @@ -92,6 +92,7 @@ CbmL1::CbmL1() : CbmL1("L1") {} CbmL1::CbmL1(const char* name, Int_t verbose, Int_t performance, int dataMode, const TString& dataDir, int findParticleMode) : FairTask(name, verbose) + , fIODataManager(L1IODataManager(gAlgo.GetParameters())) , fPerformance(performance) , fSTAPDataMode(dataMode) , fSTAPDataDir(dataDir) @@ -966,6 +967,8 @@ void CbmL1::Reconstruct(CbmEvent* event) ReadEvent(fpData, TsStart, TsLength, TsOverlap, FstHitinTs, areDataLeft, event); } + // Send data from IODataManager to L1Algo + fIODataManager.SendInputData(fpAlgo); // ******************************************************************************************** if constexpr (0) { // correct hits on MC // dbg diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 6c31a012a190db405a9a6270c2f83092d74be3ec..c97afc589c5e0bf4a744dc35614ee9da30c1fccc 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -51,6 +51,7 @@ #include "L1Algo/L1Algo.h" #include "L1Algo/L1Vector.h" #include "L1EventEfficiencies.h" +#include "L1IODataManager.h" struct L1AlgoInputData; class L1Algo; @@ -397,6 +398,9 @@ public: L1Algo* fpAlgo = nullptr; ///< Pointer to the L1 track finder algorithm L1InitManager* fpInitManager = nullptr; ///< Pointer to the initialization manager for the L1 algorithm + L1IODataManager fIODataManager; ///< Input-output data manager + + bool fUseHitErrors = true; ///< bool fMissingHits = false; ///< Turns on several ad-hock settings for "mcbm_beam_2021_07_surveyed.100ev" setup diff --git a/reco/L1/CbmL1ReadEvent.cxx b/reco/L1/CbmL1ReadEvent.cxx index b9d8f9a575ece5edce9fb60a6aa430e09388c7a3..89d3ab69160a7ee7b74838eb3082f3fc39aea944 100644 --- a/reco/L1/CbmL1ReadEvent.cxx +++ b/reco/L1/CbmL1ReadEvent.cxx @@ -221,7 +221,6 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength, // -- produce Sts hits from space points -- for (int i = 0; i < fNStations; i++) { - fData_->HitsStartIndex[i] = static_cast<L1HitIndex_t>(-1); fData_->HitsStopIndex[i] = 0; } @@ -1144,6 +1143,9 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength, fvHitStore.reserve(nHits); fvHitPointIndexes.reserve(nHits); + fIODataManager.ResetInputData(); + fIODataManager.ReserveNhits(nHits); + fIODataManager.SetNhitKeys(NStrips); // ----- Fill for (int i = 0; i < nHits; i++) { @@ -1166,27 +1168,17 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength, assert(th.iStripB >= 0 || th.iStripB < NStrips); L1Hit h; - h.f = th.iStripF; - h.b = th.iStripB; - - h.ID = th.id; - - h.t = th.time; - h.dt = th.dt; - - // h.track = th.track; - // h.dx = th.dx; - // h.dy = th.dy; - h.du = th.du; - h.dv = th.dv; - h.u = th.u; - h.v = th.v; - // h.dxy = th.dxy; - // h.p = th.p; - // h.q = th.q; - // h.ista = th.iStation; - - h.z = th.z; + h.f = th.iStripF; + h.b = th.iStripB; + h.ID = th.id; + h.t = th.time; + h.dt = th.dt; + h.du = th.du; + h.dv = th.dv; + h.u = th.u; + h.v = th.v; + h.z = th.z; + h.iSt = th.iStation; // save hit @@ -1203,10 +1195,12 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength, fData_->vHits.push_back(h); + fIODataManager.PushBackHit(h); int iSt = th.iStation; - if (fData_->HitsStartIndex[iSt] == static_cast<L1HitIndex_t>(-1)) fData_->HitsStartIndex[iSt] = nEffHits; + if (fData_->HitsStartIndex[iSt] == static_cast<L1HitIndex_t>(-1)) { fData_->HitsStartIndex[iSt] = nEffHits; } + assert(nEffHits == i); nEffHits++; fData_->HitsStopIndex[iSt] = nEffHits; @@ -1230,6 +1224,7 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength, fpAlgo->SetData(fData_->GetHits(), fData_->GetNstrips(), fData_->GetSFlag(), fData_->GetHitsStartIndex(), fData_->GetHitsStopIndex()); + if (fPerformance) { if (fVerbose >= 10) cout << "HitMatch is done." << endl; if (fVerbose >= 10) cout << "MCPoints and MCTracks are saved." << endl; diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx index 36b9d066f2340b078c58898dafbac0645a9eec50..667b28ea4522fe74f65a08b9da37fee4a553f337 100644 --- a/reco/L1/L1Algo/L1Algo.cxx +++ b/reco/L1/L1Algo/L1Algo.cxx @@ -100,6 +100,15 @@ void L1Algo::Init(const bool UseHitErrors, const TrackingMode mode, const bool M fMomentumCutOff = fInitManager.GetMomentumCutOff(); } +// --------------------------------------------------------------------------------------------------------------------- +// +void L1Algo::ReceiveInputData(L1InputData&& inputData) +{ + fInputData = std::move(inputData); + // TODO: Reset here internal data (probably, we should have additional class for internal data) +} + + /// void L1Algo::SetData(L1Vector<L1Hit>& Hits_, int nStrips_, L1Vector<unsigned char>& SFlag_, const L1HitIndex_t* HitsStartIndex_, const L1HitIndex_t* HitsStopIndex_) diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h index 4cd34ad21aaa0e77986beccc355654acd4c340df..fcbf372edeae273f99887e39c8fef2c2bbd97729 100644 --- a/reco/L1/L1Algo/L1Algo.h +++ b/reco/L1/L1Algo/L1Algo.h @@ -50,6 +50,7 @@ class L1AlgoDraw; #include "L1HitPoint.h" #include "L1HitsSortHelper.h" #include "L1InitManager.h" +#include "L1InputData.h" #include "L1Parameters.h" #include "L1Portion.h" #include "L1Station.h" @@ -171,6 +172,10 @@ public: /// Gets a pointer to the L1Algo initialization object L1InitManager* GetInitManager() { return &fInitManager; } + /// Receives input data + void ReceiveInputData(L1InputData&& inputData); + + /// ----- Hit-point-strips conversion routines ------ void GetHitCoor(const L1Hit& _h, fscal& _x, fscal& _y, fscal& _z, const L1Station& sta); @@ -455,11 +460,14 @@ private: "L1Algo::fvHitKeyFlags"}; ///< List of key flags: has been this hit or cluster already used public: - int fNstrips {0}; ///< number of strips - L1Vector<L1Hit>* vHits {nullptr}; ///< hits as a combination of front-, backstrips and z-position - L1Grid vGrid[L1Constants::size::kMaxNstations]; ///< + L1InputData fInputData; ///< Tracking input data + + int fNstrips {0}; ///< number of strips + L1Vector<L1Hit>* vHits {nullptr}; ///< hits as a combination of front and back strips and z-position + L1Grid vGrid[L1Constants::size::kMaxNstations]; ///< L1Grid vGridTime[L1Constants::size::kMaxNstations]; ///< + L1Vector<unsigned char>* fStripFlag {nullptr}; // information of hits station & using hits in tracks; double fCATime {0.}; // time of track finding diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx index 163e293691c260270b515b4809e26ec59192958a..34ee0329006fdce6be96e0fa87f4896674f86479 100644 --- a/reco/L1/L1Algo/L1CATrackFinder.cxx +++ b/reco/L1/L1Algo/L1CATrackFinder.cxx @@ -2252,10 +2252,10 @@ void L1Algo::CATrackFinder() if (isec != TRACKS_FROM_TRIPLETS_ITERATION) #endif { // ghost supression !!! - // TODO: Primary => 3 hits tracks are saved, other whise 3 hit tracks are thrown away + // TODO: Primary => 3 hits tracks are saved, otherwise 3 hit tracks are thrown away if (isec != kFastPrimIter && isec != kAllPrimIter && isec != kAllPrimEIter && isec != kAllSecEIter) if (first_trip.GetLevel() == 0) - continue; // ghost suppression // find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet + continue; //ghost suppression//find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet if (kGlobal != fTrackingMode && kMcbm != fTrackingMode) { if ((firstTripletLevel == 0) diff --git a/reco/L1/L1Algo/L1Constants.h b/reco/L1/L1Algo/L1Constants.h index a174a0e8c0c8813767ee1b7968fa7a66b9efe4d4..b436d95c9b1da6c6db8b834d47374610354aca5b 100644 --- a/reco/L1/L1Algo/L1Constants.h +++ b/reco/L1/L1Algo/L1Constants.h @@ -61,6 +61,15 @@ namespace L1Constants /// Flag: hit errors /// true - hit errors will be saved in the track extender algorithm constexpr bool kIfSaveHitErrorsInTrackExtender {false}; + + /// Flag: input data QA level + /// - 0: no checks will be done + /// - 1: only number of hits and strips as well as validity of hits first and last indexes will be checked + /// - 2: hits sorting is checked + /// - 3: every hit is checked for consistency + /// \note The larger Level corresponds to more precise checks, but is followed by larger time penalty + constexpr int kInputDataQaLevel = 3; + } // namespace control /// Physics constants @@ -74,9 +83,9 @@ namespace L1Constants /// Miscellaneous constants namespace misc { - constexpr int kAssertionLevel {0}; ///< Assertion level - constexpr int kAlignment {16}; - } // namespace misc + constexpr int kAssertionLevel = 0; ///< Assertion level + constexpr int kAlignment = 16; ///< Default alignment of data (bytes) + } // namespace misc /// NoInit constants (aliases) namespace noin diff --git a/reco/L1/L1Algo/L1Hit.h b/reco/L1/L1Algo/L1Hit.h index 5a16305ed763a54003fcade555850d8709810297..4568b1eda8502680fe704d9bf2dbf43fd4c7a92a 100644 --- a/reco/L1/L1Algo/L1Hit.h +++ b/reco/L1/L1Algo/L1Hit.h @@ -12,6 +12,8 @@ #ifndef L1Hit_h #define L1Hit_h +#include "L1Constants.h" + using L1HitIndex_t = unsigned /*short*/ int; ///< Index of L1Hit using L1StripIndex_t = unsigned /*short*/ int; ///< Index of the station strip @@ -20,18 +22,24 @@ using L1StripIndex_t = unsigned /*short*/ int; ///< Index of the station strip /// Note: U is a transverse coordinate of the hit in the axis perpendicular to the front strip /// Note: V is a transverse coordinate of the hit in the axis perpendicular to the back strip /// -class L1Hit { +class /*alignas(L1Constants::misc::kAlignment)*/ L1Hit { public: - L1StripIndex_t f {0}; ///< front strip index - L1StripIndex_t b {0}; ///< back strip index - float u {0.f}; ///< measured U coordinate [cm] - float v {0.f}; ///< measured V coordinate [cm] - float t {0.f}; ///< measured time - float z {0.f}; ///< fixed Z coordinate - float du {0.f}; ///< measured uncertainty of U coordinate [cm] - float dv {0.f}; ///< measured uncertainty of V coordinate [cm] - float dt {0.f}; ///< measured uncertainty of time [ns] - int ID {0}; ///< TODO: check if this ID is redundant + L1StripIndex_t f {0}; ///< front hit key index + L1StripIndex_t b {0}; ///< back hit key index + /// NOTE: For STS f and b correspond to the indexes of the front and back clusters of the hit in a dataset. For other + /// tracking detectors (MVD, MuCh, TRD, TOF) f == b and corresponds to the index of the hit. Indexes f and b + /// do not intersect between different detector stations. + + float u = 0.f; ///< measured U coordinate [cm] + float v = 0.f; ///< measured V coordinate [cm] + float t = 0.f; ///< measured time [ns] + float z = 0.f; ///< fixed Z coordinate [cm] + float du = 0.f; ///< measured uncertainty of U coordinate [cm] + float dv = 0.f; ///< measured uncertainty of V coordinate [cm] + float dt = 0.f; ///< measured uncertainty of time [ns] + int ID = 0; ///< index of hit before hits sorting + int iSt = 0; ///< index of station in the active stations array + // TODO: Test speed penalty of using iSt index }; #endif diff --git a/reco/L1/L1Algo/L1IODataManager.cxx b/reco/L1/L1Algo/L1IODataManager.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2b7f7d56823ee9231dd85b9133ad8629335f2d64 --- /dev/null +++ b/reco/L1/L1Algo/L1IODataManager.cxx @@ -0,0 +1,68 @@ +/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergey Gorbunov, Sergei Zharko [committer] */ + +/// \file L1IODataManager.h +/// \brief Input-output data manager for L1 tracking algorithm +/// \since 08.08.2022 +/// \author S.Zharko <s.zharko@gsi.de> + +#include "L1IODataManager.h" + +#include "L1Algo.h" + +// --------------------------------------------------------------------------------------------------------------------- +// +L1IODataManager::L1IODataManager(const L1Parameters* pParameters) : fpParameters(pParameters) {} + +// --------------------------------------------------------------------------------------------------------------------- +// +bool L1IODataManager::SendInputData(L1Algo* pAlgo) +{ + // Set boundary hit indexes + SetStartStopHitIndexes(); + + // Check data before input + if (CheckInputData<L1Constants::control::kInputDataQaLevel>()) { + assert(pAlgo); + pAlgo->ReceiveInputData(std::move(fInputData)); + return true; + } + LOG(error) << "L1: Attempt to set up inconsistent input data"; + return false; +} + +// --------------------------------------------------------------------------------------------------------------------- +// +void L1IODataManager::ResetInputData() noexcept +{ + L1InputData tmp; + fInputData.Swap(tmp); +} + +// --------------------------------------------------------------------------------------------------------------------- +// +void L1IODataManager::SetStartStopHitIndexes() +{ + // TODO: probably, it is better to loop before the actual number of stations + for (int iStation = 0; iStation < fpParameters->GetNstationsActive(); ++iStation) { + fInputData.fvStartHitIndexes[iStation] = + std::lower_bound(fInputData.fvHits.begin(), fInputData.fvHits.end(), iStation, + [](const L1Hit& hit, int ist) { return hit.iSt < ist; }) + - fInputData.fvHits.begin(); + + fInputData.fvStopHitIndexes[iStation] = + std::upper_bound(fInputData.fvHits.begin(), fInputData.fvHits.end(), iStation, + [](int ist, const L1Hit& hit) { return hit.iSt > ist; }) + - fInputData.fvHits.begin(); + + // Account for stations with no hits + if (fInputData.fvStartHitIndexes[iStation] == fInputData.fvStopHitIndexes[iStation]) { + fInputData.fvStartHitIndexes[iStation] = 0; + fInputData.fvStopHitIndexes[iStation] = 0; + } + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// diff --git a/reco/L1/L1Algo/L1IODataManager.h b/reco/L1/L1Algo/L1IODataManager.h new file mode 100644 index 0000000000000000000000000000000000000000..98fa07793792cab4e95c38c2ad76631ec60e0ef1 --- /dev/null +++ b/reco/L1/L1Algo/L1IODataManager.h @@ -0,0 +1,141 @@ +/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergey Gorbunov, Sergei Zharko [committer] */ + +/// \file L1IODataManager.h +/// \brief Input-output data manager for L1 tracking algorithm +/// \since 05.08.2022 +/// \author S.Zharko <s.zharko@gsi.de> + +#ifndef L1IODataManager_h +#define L1IODataManager_h 1 + +#include "L1Constants.h" +#include "L1InputData.h" + +class L1Parameters; +class L1Algo; +//class L1OutputData; + +/// Class L1IODataManager defines the interface for input and output data flow in the L1 tracking algorithm +/// +class alignas(L1Constants::misc::kAlignment) L1IODataManager { +public: + // *************************** + // ** Member functions list ** + // *************************** + + // ** Constructors and destructor ** + + /// Default constructor + L1IODataManager() = delete; + + /// Constructor + /// \param fpParameters Pointer to the L1 tracking algorithm parameters instance + L1IODataManager(const L1Parameters* pParameters); + + /// Destructor + ~L1IODataManager() = default; + + /// Copy constructor + L1IODataManager(const L1IODataManager& other) = delete; + + /// Move constructor + L1IODataManager(L1IODataManager&& other) = delete; + + /// Copy assignment operator + L1IODataManager& operator=(const L1IODataManager& other) = delete; + + /// Move assignment operator + L1IODataManager& operator=(L1IODataManager&& other) = delete; + + /// Reserve number of hits + /// \param nHits Number of hits to be stored + /// \note If one does not call this method, the underlying vector of hits will be filled with the time penalty + void ReserveNhits(L1HitIndex_t nHits) { fInputData.fvHits.reserve(nHits); } + + /// Resets the input data block + void ResetInputData() noexcept; + + /// Pushes back a hit + /// \param hit An L1Hit object + void PushBackHit(const L1Hit& hit) { fInputData.fvHits.push_back(hit); } + + /// Sets the number of hit keys + /// \param nKeys Number of hit keys + void SetNhitKeys(int nKeys) { fInputData.fNhitKeys = nKeys; } + + /// Sends (moves) input data to the destination reference + /// \param pAlgo Pointer to the L1 tracking algorithm main class + /// \return Success flag + bool SendInputData(L1Algo* pAlgo); + +private: + /// Sets the start and stop indexes vs. station index + void SetStartStopHitIndexes(); + + /// Provides quick QA for input data + /// \tparam Level The level of the checks. The values of the parameter: + /// - 0: no checks will be done + /// - 1: only number of hits and strips as well as validity of hits first and last indexes will be checked + /// - 2: hits sorting is checked + /// - 3: every hit is checked for consistency + /// \note The larger Level corresponds to more precise checks, but is followed by larger time penalty + template<int Level> + bool CheckInputData() const; + + + // *************************** + // ** Member variables list ** + // *************************** + + L1InputData fInputData {}; ///< Object of input data + + const L1Parameters* fpParameters = nullptr; ///< Pointer to the tracking parameters object +}; + + +// ************************************* +// ** Inline functions implementation ** +// ************************************* + +// --------------------------------------------------------------------------------------------------------------------- +// + +// TODO: Complete this function +template<int Level> +inline bool L1IODataManager::CheckInputData() const +{ + if constexpr (Level == 0) { return true; } // Level = 0 -> do nothing + else if constexpr (Level > 0) { // Level = 1 and higher + // ----- Check if the hits container is not empty ------------------------------------------------------------------ + if (fInputData.fvHits.size() == 0) { + LOG(warn) << "L1IODataManager [check input]: Sample contains empty hits, tracking will not be executed"; + return false; + } + + // ----- Checks if the number of hit keys is valid ----------------------------------------------------------------- + if (fInputData.fNhitKeys < 1) { + LOG(error) << "L1IODataManager [check input]: Incorrect number of keys passed (" << fInputData.fNhitKeys + << "), tracking will not be executed"; + return false; + } + + // ----- Checks the indexes of first and last hits in stations + // TODO: Add one of the two following checks for fvStartHitIn + + if constexpr (Level > 1) { // Level = 2 and higher + // ----- Checks for hits sorting --------------------------------------------------------------------------------- + // TODO... + if constexpr (Level > 2) { // Level = 3 and higher + // ----- Checks for consistency of the particular hit ---------------------------------------------------------- + // TODO... + } + } + return true; + } + return true; +} + + +#endif // L1IODataManager_h diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx index 78f230a6737d1eba1e5e095adb9a680dc0f2d608..718d5037a4837db35199688ac2a9a283425fc3db 100644 --- a/reco/L1/L1Algo/L1InitManager.cxx +++ b/reco/L1/L1Algo/L1InitManager.cxx @@ -2,11 +2,9 @@ SPDX-License-Identifier: GPL-3.0-only Authors: Sergey Gorbunov, Sergei Zharko [committer] */ -/************************************************************************************************************ - * @file L1InitManager.cxx - * @brief Input data management class for L1Algo - * @since 19.01.2022 - ***********************************************************************************************************/ +/// \file L1InitManager.cxx +/// \brief Input parameters management class for L1Algo +/// \since 19.01.2022 #include "L1InitManager.h" diff --git a/reco/L1/L1Algo/L1InputData.cxx b/reco/L1/L1Algo/L1InputData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..35dfe5bdc122071e7caf2c07397ef90384158a37 --- /dev/null +++ b/reco/L1/L1Algo/L1InputData.cxx @@ -0,0 +1,55 @@ +/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergey Gorbunov, Sergei Zharko [committer] */ + +/// \file L1InputData.cxx +/// \brief Structure for input data to the L1 tracking algorithm (implementation) +/// \since 08.08.2022 +/// \author Sergei Zharko <s.zharko@gsi.de> + +#include "L1InputData.h" + + +// --------------------------------------------------------------------------------------------------------------------- +// +L1InputData::L1InputData() +{ + // Init first hit indexes + //for (int iStation = 0; iStation < L1Constants::size::kMaxNstations; ++iStation) { + // fvFirstHitIndexes[iStation] = static_cast<L1HitIndex_t>(-1); + //} + // NOTE: the last hit indexes should be initialized with 0. It is done in the variable declaration +} + +// --------------------------------------------------------------------------------------------------------------------- +// +L1InputData::L1InputData(const L1InputData& other) + : fvHits(other.fvHits) + , fvStartHitIndexes(other.fvStartHitIndexes) + , fvStopHitIndexes(other.fvStopHitIndexes) + , fNhitKeys(other.fNhitKeys) +{ +} + +// --------------------------------------------------------------------------------------------------------------------- +// +L1InputData::L1InputData(L1InputData&& other) noexcept { this->Swap(other); } + +// --------------------------------------------------------------------------------------------------------------------- +// +L1InputData& L1InputData::operator=(const L1InputData& other) +{ + if (this != &other) { L1InputData(other).Swap(*this); } + return *this; +} + +// --------------------------------------------------------------------------------------------------------------------- +// +L1InputData& L1InputData::operator=(L1InputData&& other) noexcept +{ + if (this != &other) { + L1InputData tmp(std::move(other)); + this->Swap(tmp); + } + return *this; +} diff --git a/reco/L1/L1Algo/L1InputData.h b/reco/L1/L1Algo/L1InputData.h new file mode 100644 index 0000000000000000000000000000000000000000..945bee3e237fef7aa697deeb7e133e2762c075bd --- /dev/null +++ b/reco/L1/L1Algo/L1InputData.h @@ -0,0 +1,122 @@ +/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergey Gorbunov, Sergei Zharko [committer] */ + +/// \file L1InputData.h +/// \brief Structure for input data to the L1 tracking algorithm (declaration) +/// \since 08.08.2022 +/// \author Sergei Zharko <s.zharko@gsi.de> + +#ifndef L1InputData_h +#define L1InputData_h 1 + +#include <array> + +#include "L1Constants.h" +#include "L1Hit.h" +#include "L1Vector.h" + + +/// Class L1InputData represents a block of the input data to the L1 tracking algorithm per event or time slice. +/// Filling of the L1InputData is carried out with L1IODataManager class +/// +class alignas(L1Constants::misc::kAlignment) L1InputData { +public: + // ************************** + // ** Friend classes list ** + // ************************** + + friend class L1IODataManager; ///< Class which fills the L1InputData object for each event or time slice + + + // *************************** + // ** Member functions list ** + // *************************** + + // ** Constructors and destructor ** + + /// Default constructor + L1InputData(); + + /// Destructor + ~L1InputData() = default; + + /// Copy constructor + L1InputData(const L1InputData& other); + + /// Move constructor + L1InputData(L1InputData&&) noexcept; + + /// Copy assignment operator + L1InputData& operator=(const L1InputData& other); + + /// Move assignment operator + L1InputData& operator=(L1InputData&& other) noexcept; + + /// Gets hits sample size + L1HitIndex_t GetSampleSize() const { return fvHits.size(); } + + + // ** Accessors ** + + /// Gets reference to hit by its index + /// \param index Index of hit in the hits sample + const L1Hit& GetHit(L1HitIndex_t index) const { return fvHits[index]; } + + /// Get reference to hits vector + const L1Vector<L1Hit>& GetHits() const { return fvHits; } + + /// Gets total number of stored keys + int GetNhitKeys() const { return fNhitKeys; } + + /// Gets index of the first hit in the sorted hits vector + /// \param iStation Index of the tracking station in the active stations array + L1HitIndex_t GetStartHitIndex(int iStation) const { return fvStartHitIndexes[iStation]; } + + /// Gets index of (the last + 1) hit in the sorted hits vector + /// \param iStation Index of the tracking station in the active stations array + L1HitIndex_t GetStopHitIndex(int iStation) const { return fvStopHitIndexes[iStation]; } + + +private: + /// Swap method + void Swap(L1InputData& other) noexcept; + + + // *************************** + // ** Member variables list ** + // *************************** + + L1Vector<L1Hit> fvHits = {"L1InputData::fvHits"}; ///< Sorted sample of input hits + ///< \note Hits in the vector are sorted as follows. Among two hits + ///< the largest has the largest station index in the active + ///< stations array. If both indexes were measured withing one + ///< station, the largest hit has the largest y component of + ///< the coordinates + + /// Index of the first hit in the sorted hits vector for a given station + std::array<L1HitIndex_t, L1Constants::size::kMaxNstations> fvStartHitIndexes = {0}; + + /// Index of the last hit in the sorted hits vector for a given station + std::array<L1HitIndex_t, L1Constants::size::kMaxNstations> fvStopHitIndexes = {0}; + + /// Number of hit keys used for rejecting fake STS hits + int fNhitKeys = -1; +}; + + +// ******************************************** +// ** Inline member functions initialization ** +// ********************************************* + +// --------------------------------------------------------------------------------------------------------------------- +// +[[gnu::always_inline]] inline void L1InputData::Swap(L1InputData& other) noexcept +{ + std::swap(fvHits, other.fvHits); + std::swap(fvStartHitIndexes, other.fvStartHitIndexes); + std::swap(fvStopHitIndexes, other.fvStopHitIndexes); + std::swap(fNhitKeys, other.fNhitKeys); +} + +#endif // L1InputData_h diff --git a/reco/L1/L1Algo/L1Parameters.cxx b/reco/L1/L1Algo/L1Parameters.cxx index 29bdaddc15363d2fefdd2ab34edde0bde8295695..1ec8e92e60f62c2f2f65e35cd197986886e89834 100644 --- a/reco/L1/L1Algo/L1Parameters.cxx +++ b/reco/L1/L1Algo/L1Parameters.cxx @@ -11,18 +11,18 @@ #include <FairLogger.h> -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // L1Parameters::L1Parameters() { fActiveStationGlobalIDs.fill(-1); // by default, all stations are inactive, thus all the IDs must be -1 } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // L1Parameters::~L1Parameters() noexcept {} -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // L1Parameters::L1Parameters(const L1Parameters& other) noexcept : fMaxDoubletsPerSinglet(other.fMaxDoubletsPerSinglet) @@ -43,7 +43,7 @@ L1Parameters::L1Parameters(const L1Parameters& other) noexcept { } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // L1Parameters& L1Parameters::operator=(const L1Parameters& other) noexcept { @@ -51,11 +51,11 @@ L1Parameters& L1Parameters::operator=(const L1Parameters& other) noexcept return *this; } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // L1Parameters::L1Parameters(L1Parameters&& other) noexcept { this->Swap(other); } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // L1Parameters& L1Parameters::operator=(L1Parameters&& other) noexcept { @@ -66,7 +66,7 @@ L1Parameters& L1Parameters::operator=(L1Parameters&& other) noexcept return *this; } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // void L1Parameters::Swap(L1Parameters& other) noexcept { @@ -87,7 +87,7 @@ void L1Parameters::Swap(L1Parameters& other) noexcept std::swap(fDevIsMatchTripletsViaMc, other.fDevIsMatchTripletsViaMc); } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // void L1Parameters::CheckConsistency() const { @@ -202,7 +202,7 @@ void L1Parameters::CheckConsistency() const } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // void L1Parameters::Print(int /*verbosityLevel*/) const { @@ -210,7 +210,7 @@ void L1Parameters::Print(int /*verbosityLevel*/) const LOG(info) << ToString(); } -//------------------------------------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- // std::string L1Parameters::ToString(int verbosity, int indentLevel) const {