diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index 4a256fdd47012ee1cd6e0b8f49c559cd522204c6..b81382879e529fdbb0e967435abfae3db1429ec0 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -208,6 +208,7 @@ install( base/SubChain.h base/PartitionedVector.h global/Reco.h + global/RecoResults.h global/RecoResultsInputArchive.h global/RecoResultsOutputArchive.h global/StorableRecoResults.h diff --git a/algo/base/Definitions.h b/algo/base/Definitions.h index ff02c3afac6e49d8742409c6c22ecc311296e22c..490edc62a47d0d54642dc102b03548d099f02185 100644 --- a/algo/base/Definitions.h +++ b/algo/base/Definitions.h @@ -36,6 +36,7 @@ namespace cbm::algo Unpack, DigiTrigger, LocalReco, + Tracking, }; enum class RecoData @@ -44,6 +45,7 @@ namespace cbm::algo DigiEvent, //< Digis after event building Cluster, Hit, + Track, }; } // namespace cbm::algo @@ -74,14 +76,16 @@ CBM_ENUM_DICT(fles::Subsystem, CBM_ENUM_DICT(cbm::algo::Step, {"Unpack", Step::Unpack}, {"DigiTrigger", Step::DigiTrigger}, - {"LocalReco", Step::LocalReco} + {"LocalReco", Step::LocalReco}, + {"Tracking", Step::Tracking} ); CBM_ENUM_DICT(cbm::algo::RecoData, {"Digi", RecoData::Digi}, {"DigiEvent", RecoData::DigiEvent}, {"Cluster", RecoData::Cluster}, - {"Hit", RecoData::Hit} + {"Hit", RecoData::Hit}, + {"Track", RecoData::Track} ); #endif diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx index 2005a16737a2c6aec2893ca53bcc0e2d1cfa91a5..16605f6defc768c18c524398e2d1a15953311ad7 100644 --- a/algo/ca/TrackingChain.cxx +++ b/algo/ca/TrackingChain.cxx @@ -12,18 +12,21 @@ #include <boost/filesystem.hpp> #include "CaConstants.h" +#include "CaHit.h" #include "CaInitManager.h" #include "CaParameters.h" +using cbm::algo::PartitionedPODVector; using cbm::algo::TrackingChain; +using cbm::algo::ca::EDetectorID; using cbm::algo::ca::Framework; +using cbm::algo::ca::HitTypes_t; using cbm::algo::ca::InitManager; using cbm::algo::ca::Parameters; using cbm::algo::ca::Track; using cbm::algo::ca::constants::clrs::CL; // clear text using cbm::algo::ca::constants::clrs::GNb; // grin bald text - // --------------------------------------------------------------------------------------------------------------------- // void TrackingChain::Init() @@ -45,24 +48,93 @@ void TrackingChain::Init() // --------------------------------------------------------------------------------------------------------------------- // -TrackingChain::Return_t TrackingChain::Run(/*vectors of hits*/) +TrackingChain::Return_t TrackingChain::Run(const RecoResults& recoResults) { // ----- Init input data --------------------------------------------------------------------------------------------- - fCaDataManager.ResetInputData(/*nHits = */ 0); - // Create and push back hits.... - fCaDataManager.SetNhitKeys(/*nHitKeys = */ 0); - fCaFramework.ReceiveInputData(fCaDataManager.TakeInputData()); + this->PrepareInput(recoResults); // ----- Run reconstruction ------------------------------------------------------------------------------------------ - // FIXME: SZh 22.10.2023: Return fMonitorDataPerCall, when the corresponding MR is accepted - fCaFramework.fTrackFinder.FindTracks(); + // FIXME: SZh 23.10.2023: + // Sub-timeslices algorithm seems not to be working, the whole hit sample is sent to the FindTracks function. + // Further investigations are needed. + //fCaFramework.fTrackFinder.FindTracks(); L_(info) << "Timeslice contains " << fCaFramework.fRecoTracks.size() << " tracks"; // ----- Init output data -------------------------------------------------------------------------------------------- // FIXME: SZh 22.10.2023: Provide a class for the tracking output data (tracks, hit indices and monitor) - return std::make_pair(std::move(fCaFramework.fRecoTracks), fCaFramework.GetMonitor().GetMonitorData()); + return std::make_pair(std::move(fCaFramework.fRecoTracks), fCaFramework.GetMonitorDataPerCall()); } // --------------------------------------------------------------------------------------------------------------------- // void TrackingChain::Finalize() {} + +// --------------------------------------------------------------------------------------------------------------------- +// +void TrackingChain::PrepareInput(const RecoResults& recoResults) +{ + fNofHitKeys = 0; + int nHitsTot = recoResults.stsHits.NElements(); + L_(info) << "Tracking chain: input has " << nHitsTot << " hits"; + fCaDataManager.ResetInputData(nHitsTot); + ReadHits<EDetectorID::Sts>(recoResults.stsHits); + fCaDataManager.SetNhitKeys(fNofHitKeys); + L_(info) << "Tracking chain:" << fCaDataManager.GetNofHits() << " will be passed to the ca::Framework"; + fCaFramework.ReceiveInputData(fCaDataManager.TakeInputData()); +} + +// --------------------------------------------------------------------------------------------------------------------- +// +template<EDetectorID DetID> +void TrackingChain::ReadHits(const PartitionedPODVector<ca::HitTypes_t::at<DetID>>& hits) +{ + ca::HitKeyIndex_t firstHitKey = fNofHitKeys; + int64_t dataStreamDet = static_cast<int64_t>(DetID) << 60; // detector part of the data stream + for (size_t iPartition = 0; iPartition < hits.NPartitions(); ++iPartition) { + const auto& [vHits, extHitAddress] = hits.Partition(iPartition); + // ---- Define data stream and station index + int64_t dataStream = dataStreamDet | extHitAddress; + int iStLocal = -1; + // FIXME: This definition of the station index works only for STS, and there is no any guaranty, that it will + // work for other mCBM setups. + if constexpr (DetID == EDetectorID::Sts) { iStLocal = (extHitAddress >> 4) & 0xF; } + int iStActive = (iStLocal != -1) ? fCaFramework.GetParameters().GetStationIndexActive(iStLocal, DetID) : -1; + size_t iOffset = hits.Offsets()[iPartition]; + if (iStActive < 0) { continue; } + + for (size_t iPartHit = 0; iPartHit < vHits.size(); ++iPartHit) { + const auto& hit = vHits[iPartHit]; + int iHitExt = iOffset + iPartHit; + // ---- Fill ca::Hit + ca::Hit caHit; + if constexpr (DetID == EDetectorID::Sts) { + caHit.SetFrontKey(firstHitKey + hit.fFrontClusterId); + caHit.SetBackKey(firstHitKey + hit.fBackClusterId); + } + else { + caHit.SetFrontKey(firstHitKey + iHitExt); + caHit.SetBackKey(caHit.FrontKey()); + } + caHit.SetX(hit.fX); + caHit.SetY(hit.fY); + caHit.SetZ(hit.fZ); + caHit.SetT(hit.fTime); + caHit.SetDx2(hit.fDx * hit.fDx); + caHit.SetDy2(hit.fDy * hit.fDy); + caHit.SetDxy(hit.fDxy); + caHit.SetDt2(hit.fTimeError * hit.fTimeError); + /// FIXME: Define ranges from the hit, when will be available + caHit.SetRangeX(3.5 * hit.fDx); + caHit.SetRangeY(3.5 * hit.fDy); + caHit.SetRangeT(3.5 * hit.fTimeError); + caHit.SetStation(iStActive); + caHit.SetId(fCaDataManager.GetNofHits()); + fCaDataManager.PushBackHit(caHit, dataStream); + // ---- Update number of hit keys + if (fNofHitKeys <= caHit.FrontKey()) { fNofHitKeys = caHit.FrontKey() + 1; } + if (fNofHitKeys <= caHit.BackKey()) { fNofHitKeys = caHit.BackKey() + 1; } + } // iPartHit + } // iPartition +} + +template void TrackingChain::ReadHits<EDetectorID::Sts>(const PartitionedPODVector<HitTypes_t::at<EDetectorID::Sts>>&); diff --git a/algo/ca/TrackingChain.h b/algo/ca/TrackingChain.h index c524bd477b29dc90f9973a0311bced5e9548a988..c59f81f400304af2d52f2a896dc51c53ac2dbb29 100644 --- a/algo/ca/TrackingChain.h +++ b/algo/ca/TrackingChain.h @@ -9,6 +9,8 @@ #pragma once +#include "TrackingDefs.h" + #include <vector> #include "CaDataManager.h" @@ -16,24 +18,10 @@ #include "CaTrack.h" #include "CaTrackingMonitor.h" #include "CaVector.h" +#include "PartitionedVector.h" +#include "RecoResults.h" #include "SubChain.h" - -namespace cbm::algo::ca -{ - /// \enum cbm::algo::ca::EDetectorID - /// \brief Enumeration for the detector subsystems used in CBM online tracking - /// \note It is important, that the subsystems are specified in the actual order. - /// \note The enumeration must not contain jumps in the ordering and the first entry must be equal 0 - enum class EDetectorID - { - Mvd = 0, - Sts, - Much, - Trd, - Tof, - kEND ///< End of enumeration - }; -} // namespace cbm::algo::ca +#include "data/sts/Hit.h" namespace cbm::algo { @@ -49,14 +37,29 @@ namespace cbm::algo void Init(); /// \brief Provides action for a given time-slice - /// \return A vector of cbm::algo::ca::Track - Return_t Run(/*vectors of hits*/); + /// \param recoResults Structure of reconstruction results + /// \return A pair (vector of tracks, tracking monitor) + Return_t Run(const RecoResults& recoResults); /// \brief Provides action in the end of the run void Finalize(); private: + /// \brief Prepares input data + /// \param recoResults Structure of reconstruction results + void PrepareInput(const RecoResults& recoResults); + + /// \brief Reads from different detector subsystems + /// \tparam DetID Detector ID + /// \param hits Hits vector + template<ca::EDetectorID DetID> + void ReadHits(const PartitionedPODVector<ca::HitTypes_t::at<DetID>>& hits); + ca::Framework fCaFramework {}; ///< CA framework instance ca::DataManager fCaDataManager {}; ///< CA data manager + + ca::HitKeyIndex_t fNofHitKeys = 0; ///< Current number of hit keys (aux) }; + + } // namespace cbm::algo diff --git a/algo/ca/TrackingDefs.h b/algo/ca/TrackingDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..04d457dd80c7f40ba6709bc6f70446ef0543e4cc --- /dev/null +++ b/algo/ca/TrackingDefs.h @@ -0,0 +1,81 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file TrackingDefs.h +/// \date 22.10.2023 +/// \brief Definitions for tracking in the online reconstruction +/// \author S.Zharko <s.zharko@gsi.de> + +#pragma once + +#include <tuple> + +#include "CaEnumArray.h" + +namespace cbm::algo +{ + namespace mvd + { + class Hit; + } + namespace sts + { + class Hit; + } + namespace much + { + class Hit; + } + namespace trd + { + class Hit; + } + namespace tof + { + class Hit; + } + + namespace ca + { + /// \enum cbm::algo::ca::EDetectorID + /// \brief Enumeration for the detector subsystems used in CBM online tracking + /// \note It is important, that the subsystems are specified in the actual order. + /// \note The enumeration must not contain jumps in the ordering and the first entry must be equal 0 + enum class EDetectorID + { + Mvd = 0, + Sts, + Much, + Trd, + Tof, + kEND ///< End of enumeration + }; + + /// \brief Alias to array, indexed by the EDetectorID enum + /// \note To be used only in CBM-specific code + template<typename T> + using DetIdArray_t = EnumArray<EDetectorID, T>; + + /// \struct DetIdTypeArr_t + /// \brief Array of types, indexed by EDetectorID + template<class... Types> + struct DetIdTypeArr_t { + template<EDetectorID DetID> + using at = std::tuple_element_t<static_cast<std::size_t>(DetID), std::tuple<Types...>>; + static constexpr std::size_t size = sizeof...(Types); + }; + + /// \brief Hit vector types + using MvdHit = ::cbm::algo::mvd::Hit; + using StsHit = ::cbm::algo::sts::Hit; + using MuchHit = ::cbm::algo::much::Hit; + using TrdHit = ::cbm::algo::trd::Hit; + using TofHit = ::cbm::algo::tof::Hit; + using HitTypes_t = DetIdTypeArr_t<MvdHit, StsHit, MuchHit, TrdHit, TofHit>; + + /// \brief Detector subsystem names + constexpr DetIdArray_t<const char*> kDetName = {{"MVD", "STS", "MUCH", "TRD", "TOF"}}; + + } // namespace ca +} // namespace cbm::algo diff --git a/algo/ca/core/CMakeLists.txt b/algo/ca/core/CMakeLists.txt index 0adcb851a589aced1fcc449a0761a337ef6a0965..544b54bd64c6b3112e9658a317f4ea2b2c9ffa55 100644 --- a/algo/ca/core/CMakeLists.txt +++ b/algo/ca/core/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRCS ${CMAKE_CURRENT_SOURCE_DIR}/data/CaTrack.cxx ${CMAKE_CURRENT_SOURCE_DIR}/data/CaTrackParam.cxx ${CMAKE_CURRENT_SOURCE_DIR}/data/CaGrid.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/data/CaHit.cxx ${CMAKE_CURRENT_SOURCE_DIR}/data/CaTriplet.cxx ${CMAKE_CURRENT_SOURCE_DIR}/data/CaMeasurementU.cxx ${CMAKE_CURRENT_SOURCE_DIR}/data/CaMeasurementXy.cxx diff --git a/algo/ca/core/data/CaHit.cxx b/algo/ca/core/data/CaHit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d719c97818afd6ebf7bf69cca247269d71f5fe18 --- /dev/null +++ b/algo/ca/core/data/CaHit.cxx @@ -0,0 +1,71 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CaHit.cxx +/// \date 23.10.2023 +/// \brief A generic hit for the CA tracker (header) (implementation) +/// \author S.Zharko <s.zharko@gsi.de> + +#include "CaHit.h" + +#include <iomanip> +#include <sstream> + +using cbm::algo::ca::Hit; + +std::string Hit::ToString(int verbose, bool bHeader) const +{ + if (verbose < 1) { return ""; } + using std::setw; + constexpr int widthF = 12; + constexpr int widthI = 4; + std::stringstream msg; + if (bHeader) { + msg << setw(widthI) << "IDe" << ' '; + msg << setw(widthI) << "st." << ' '; + if (verbose > 1) { + msg << setw(widthI) << "keyF" << ' '; + msg << setw(widthI) << "keyB" << ' '; + } + msg << setw(widthF) << "x [cm]" << ' '; + msg << setw(widthF) << "y [cm]" << ' '; + msg << setw(widthF) << "z [cm]" << ' '; + msg << setw(widthF) << "t [ns]" << ' '; + if (verbose > 1) { + msg << setw(widthF) << "dx2 [cm2]" << ' '; + msg << setw(widthF) << "dy2 [cm2]" << ' '; + msg << setw(widthF) << "dxy [cm2]" << ' '; + msg << setw(widthF) << "dt2 [ns2]" << ' '; + if (verbose > 2) { + msg << setw(widthF) << "rangeX [cm]" << ' '; + msg << setw(widthF) << "rangeY [cm]" << ' '; + msg << setw(widthF) << "rangeT [ns]" << ' '; + } + } + } + else { + msg << setw(widthI) << fId << ' '; + msg << setw(widthI) << fStation << ' '; + if (verbose > 1) { + msg << setw(widthI) << fFrontKey << ' '; + msg << setw(widthI) << fBackKey << ' '; + } + msg << setw(widthF) << fX << ' '; + msg << setw(widthF) << fY << ' '; + msg << setw(widthF) << fZ << ' '; + msg << setw(widthF) << fT << ' '; + if (verbose > 1) { + msg << setw(widthF) << fDx2 << ' '; + msg << setw(widthF) << fDy2 << ' '; + msg << setw(widthF) << fDxy << ' '; + msg << setw(widthF) << fDt2 << ' '; + if (verbose > 2) { + msg << setw(widthF) << fRangeX << ' '; + msg << setw(widthF) << fRangeY << ' '; + msg << setw(widthF) << fRangeT << ' '; + } + } + } + return msg.str(); +} diff --git a/algo/ca/core/data/CaHit.h b/algo/ca/core/data/CaHit.h index 5bb4b35153bbd32dad1be2552c076b2e2055e309..218969ff1184db808d4ca9017098db5ac1a417cb 100644 --- a/algo/ca/core/data/CaHit.h +++ b/algo/ca/core/data/CaHit.h @@ -2,9 +2,9 @@ SPDX-License-Identifier: GPL-3.0-only Authors: Valentina Akishina, Igor Kulakov, Sergey Gorbunov [committer], Maksym Zyzak */ -/// \file CaHit.h -/// \brief ca::Hit class describes a generic hit for the CA tracker -/// \date 2007-2023 +/// \file CaHit.h +/// \brief A generic hit for the CA tracker (header) +/// \date 2007-2023 #pragma once // include this header only once per compilation unit @@ -122,6 +122,10 @@ namespace cbm::algo::ca /// Get the station index int Station() const { return fStation; } + /// \brief String representation of the hit class + /// \param verbose Verbosity level + /// \param bHeader If true, prints the header + std::string ToString(int verbose = 2, bool bHeader = false) const; private: ///----------------------------------------------------------------------------- @@ -138,10 +142,10 @@ namespace cbm::algo::ca fscal fY {0.}; ///< measured Y coordinate [cm] fscal fZ {0.}; ///< fixed Z coordinate [cm] fscal fT {0.}; ///< measured time [ns] - fscal fDx2 {0.}; ///< rms^2 of uncertainty of X coordinate [cm] - fscal fDy2 {0.}; ///< rms^2 of uncertainty of Y coordinate [cm] + fscal fDx2 {0.}; ///< rms^2 of uncertainty of X coordinate [cm2] + fscal fDy2 {0.}; ///< rms^2 of uncertainty of Y coordinate [cm2] fscal fDxy {0.}; ///< X/Y covariance [cm2] - fscal fDt2 {0.}; ///< measured uncertainty of time [ns] + fscal fDt2 {0.}; ///< measured uncertainty of time [ns2] fscal fRangeX {0.}; ///< +/- range of uncertainty of X coordinate [cm] fscal fRangeY {0.}; ///< +/- range of uncertainty of Y coordinate [cm] fscal fRangeT {0.}; ///< +/- range of uncertainty of time [ns] diff --git a/algo/ca/core/tracking/CaTrackFinder.cxx b/algo/ca/core/tracking/CaTrackFinder.cxx index 4d80fb1771e4ae55eef899424be669c07b2db111..27522753ddbdbe7cbb6de6de97bf56cce6a7bf90 100644 --- a/algo/ca/core/tracking/CaTrackFinder.cxx +++ b/algo/ca/core/tracking/CaTrackFinder.cxx @@ -149,7 +149,6 @@ void TrackFinder::FindTracks() } while (areDataLeft) { - frAlgo.fMonitor.IncrementCounter(ECounter::SubTS); // select the sub-slice hits diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx index fae16aded93491e5fe73679b1cf2a46c4809e854..d3f03cfa46ef1a9e73b5145074e5867c314e2234 100644 --- a/algo/global/Reco.cxx +++ b/algo/global/Reco.cxx @@ -134,8 +134,6 @@ RecoResults Reco::Run(const fles::Timeslice& ts) stsHitfinderMonitor = stsResults.monitor; } - // --- Tracking - std::vector<ca::Track> tracks = fTracking.Run(); xpu::timings ts_times = xpu::pop_timer(); @@ -150,7 +148,11 @@ RecoResults Reco::Run(const fles::Timeslice& ts) if (Opts().HasOutput(RecoData::Hit)) results.stsHits = std::move(stsHits); // --- Tracking - TrackingChain::Return_t trackingOutput = fTracking.Run(); + if (Opts().HasStep(Step::Tracking)) { + TrackingChain::Return_t trackingOutput = fTracking.Run(results); + if (Opts().HasOutput(RecoData::Track)) { results.tracks = std::move(trackingOutput.first); } + QueueTrackingMetrics(trackingOutput.second); + } return results; } @@ -292,7 +294,7 @@ void Reco::QueueEvbuildMetrics(const evbuild::EventbuildChainMonitorData& mon) {"totalEvSelectionRatio", totalSelectionRatio}}); } -void Reco::QueueTrackingRecoMetrics(const ca::TrackingMonitorData& monitor) +void Reco::QueueTrackingMetrics(const ca::TrackingMonitorData& monitor) { if (!HasMonitor()) { return; } diff --git a/algo/global/Reco.h b/algo/global/Reco.h index 05989804b72ec618f41b1caf15dea37cd55053b8..83efd74ace93014a6dafd71fd3bff78b1dbbaf91 100644 --- a/algo/global/Reco.h +++ b/algo/global/Reco.h @@ -10,6 +10,7 @@ #include "SubChain.h" #include "UnpackChain.h" #include "ca/TrackingChain.h" +#include "global/RecoResults.h" #include "sts/HitfinderChain.h" namespace fles @@ -21,11 +22,6 @@ namespace cbm::algo { class Options; - struct RecoResults { - std::vector<DigiEvent> events; - PartitionedPODVector<sts::Hit> stsHits; - }; - class Reco : SubChain { public: Reco(); @@ -62,7 +58,7 @@ namespace cbm::algo void QueueUnpackerMetrics(const fles::Timeslice&, const UnpackMonitorData&, const DigiData&); void QueueStsRecoMetrics(const sts::HitfinderMonitor&); void QueueEvbuildMetrics(const evbuild::EventbuildChainMonitorData&); - void QueueTrackingRecoMetrics(const ca::TrackingMonitorData&); + void QueueTrackingMetrics(const ca::TrackingMonitorData&); }; } // namespace cbm::algo diff --git a/algo/global/RecoResults.h b/algo/global/RecoResults.h new file mode 100644 index 0000000000000000000000000000000000000000..0a2a3bbced9381de36b268bb371904910af2ca7f --- /dev/null +++ b/algo/global/RecoResults.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file RecoResults.h +/// \date 22.10.2023 +/// \brief A structure for reconstructed results: digi-events, hits and tracks +/// \author S.Zharko <s.zharko@gsi.de> + +#pragma once + +#include <vector> + +#include "DigiData.h" +#include "base/PartitionedVector.h" +#include "ca/core/utils/CaVector.h" +#include "data/sts/Hit.h" + +namespace cbm::algo +{ + /// \struct RecoResults + /// \brief Structure to keep reconstructed results: digi-events, hits and tracks + struct RecoResults { + std::vector<DigiEvent> events; + PartitionedPODVector<sts::Hit> stsHits; + ca::Vector<ca::Track> tracks; + }; +} // namespace cbm::algo diff --git a/reco/L1/CbmCaTimeSliceReader.h b/reco/L1/CbmCaTimeSliceReader.h index 98db0a8cb2dd8e35c2cee26bf25e23c2cf1eee49..29d07f3111a2bcf8a5d156da51f5b4e1d51c23e0 100644 --- a/reco/L1/CbmCaTimeSliceReader.h +++ b/reco/L1/CbmCaTimeSliceReader.h @@ -288,13 +288,13 @@ int cbm::ca::TimeSliceReader::ReadHitsForDetector() // Update number of hit keys if constexpr (ca::EDetectorID::kSts == DetID) { - if (fNofHitKeys <= hitRecord.fStripF) { fNofHitKeys += hitRecord.fStripF; } - if (fNofHitKeys <= hitRecord.fStripB) { fNofHitKeys += hitRecord.fStripB; } + if (fNofHitKeys <= hitRecord.fStripF) { fNofHitKeys = hitRecord.fStripF + 1; } + if (fNofHitKeys <= hitRecord.fStripB) { fNofHitKeys = hitRecord.fStripB + 1; } } else { hitRecord.fStripF = fFirstHitKey + iHext; hitRecord.fStripB = hitRecord.fStripF; - if (fNofHitKeys <= hitRecord.fStripF) { fNofHitKeys += hitRecord.fStripF; } + if (fNofHitKeys <= hitRecord.fStripF) { fNofHitKeys = hitRecord.fStripF + 1; } } // Save hit to data structures