diff --git a/Event/EventBase/include/Event/SOACollection.h b/Event/EventBase/include/Event/SOACollection.h index 53518f8b255d030b4277fba66efae48f60d79b03..5b7cf44fbaaef3f981172564d207d797f995ef57 100644 --- a/Event/EventBase/include/Event/SOACollection.h +++ b/Event/EventBase/include/Event/SOACollection.h @@ -269,6 +269,7 @@ namespace LHCb::Event { }; store( std::next( this->data<Tag>(), at ), value ); } + // -- make sure it accepts an int... template <typename Tag, typename I, typename M = std::true_type> void store( int at, int i, I const& idx, M&& mask = {} ) { auto store = [&]( auto* storage, auto const& val ) { @@ -280,6 +281,25 @@ namespace LHCb::Event { }; store( std::next( this->data<Tag>( i ), at ), idx ); } + + // -- ... and an enum as an argument + template <typename Tag, typename I, typename L, typename M = std::true_type, + typename std::enable_if_t<std::is_enum_v<L>>* = nullptr> + void store( int at, L i, I const& idx, M&& mask = {} ) { + auto store = [&]( auto* storage, auto const& val ) { + if constexpr ( std::is_same_v<std::true_type, std::decay_t<M>> ) { + val.store( storage ); + } else { + val.compressstore( mask, storage ); + } + }; + if constexpr ( std::is_enum_v<L> ) { + store( std::next( this->data<Tag>( static_cast<unsigned>( i ) ), at ), idx ); + } else { + store( std::next( this->data<Tag>( i ), at ), idx ); + } + } + // -- make sure it accepts an int... template <typename Tag, typename I, typename M = std::true_type> void store( int at, int i, int j, I const& idx, M&& mask = {} ) { auto store = [&]( auto* storage, auto const& val ) { @@ -292,6 +312,24 @@ namespace LHCb::Event { store( std::next( this->data<Tag>( i, j ), at ), idx ); } + // -- ... and an enum as an argument + template <typename Tag, typename I, typename L, typename M = std::true_type, + typename std::enable_if_t<std::is_enum_v<L>>* = nullptr> + void store( int at, int i, L j, I const& idx, M&& mask = {} ) { + auto store = [&]( auto* storage, auto const& val ) { + if constexpr ( std::is_same_v<std::true_type, std::decay_t<M>> ) { + val.store( storage ); + } else { + val.compressstore( mask, storage ); + } + }; + if constexpr ( std::is_enum_v<L> ) { + store( std::next( this->data<Tag>( i, static_cast<unsigned>( j ) ), at ), idx ); + } else { + store( std::next( this->data<Tag>( i, j ), at ), idx ); + } + } + private: /** Helper for methods that want to trigger exponential capacity growth if * more capacity is needed (copy_back, resize) diff --git a/Event/TrackEvent/include/Event/PrDownstreamTracks.h b/Event/TrackEvent/include/Event/PrDownstreamTracks.h index e231d028347ddb85b0bd20c3f126900c4d7f266d..feffad922858356cb44d8c9cb0d527cd66cfb5ba 100644 --- a/Event/TrackEvent/include/Event/PrDownstreamTracks.h +++ b/Event/TrackEvent/include/Event/PrDownstreamTracks.h @@ -31,19 +31,19 @@ namespace LHCb::Pr::Downstream { struct Tag { struct trackSeed : Event::int_field {}; - struct StateQoP : Event::float_field {}; struct nUTHits : Event::int_field {}; struct nFTHits : Event::int_field {}; struct ut_indices : Event::ints_field<TracksInfo::MaxUTHits> {}; struct ft_indices : Event::ints_field<TracksInfo::MaxFTHits> {}; struct lhcbIDs : Event::ints_field<TracksInfo::MaxFTHits + TracksInfo::MaxUTHits> {}; - struct StatePosition : Event::state_field {}; + struct State : Event::state_field {}; template <typename T> - using downstream_t = - Event::SOACollection<T, trackSeed, StateQoP, nFTHits, nUTHits, ft_indices, ut_indices, lhcbIDs, StatePosition>; + using downstream_t = Event::SOACollection<T, trackSeed, nFTHits, nUTHits, ft_indices, ut_indices, lhcbIDs, State>; }; + namespace SP = LHCb::Event::StateParameters; + struct Tracks : Tag::downstream_t<Tracks> { using base_t = typename Tag::downstream_t<Tracks>; @@ -59,11 +59,16 @@ namespace LHCb::Pr::Downstream { // Return pointer to ancestor container [[nodiscard]] LHCb::Pr::Seeding::Tracks const* getFTAncestors() const { return m_ft_ancestors; }; + template <typename F, typename M = std::true_type> + void store_qOverP( int at, F const& qOverP, M&& mask = {} ) { + store<Tag::State>( at, SP::StateVector::qOverP, qOverP, mask ); + } + // Define an minimal custom proxy for this track template <SIMDWrapper::InstructionSet simd, LHCb::Pr::ProxyBehaviour behaviour, typename ContainerType> struct DownstreamProxy : Event::Proxy<simd, behaviour, ContainerType> { using Event::Proxy<simd, behaviour, ContainerType>::Proxy; - [[nodiscard]] auto qOverP() const { return this->template get<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP() const { return this->template get<Tag::State>().qOverP(); } [[nodiscard]] auto seed_track_index() const { return this->template get<Tag::trackSeed>(); } [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto nUTHits() const { return this->template get<Tag::nUTHits>(); } diff --git a/Event/TrackEvent/include/Event/PrFittedForwardTracks.h b/Event/TrackEvent/include/Event/PrFittedForwardTracks.h index 09c037590eae298072f93d6c47abaf657e5c697b..21e7ca0a5f4d481f81461d6fa22b7fbda228b228 100644 --- a/Event/TrackEvent/include/Event/PrFittedForwardTracks.h +++ b/Event/TrackEvent/include/Event/PrFittedForwardTracks.h @@ -51,23 +51,26 @@ namespace LHCb::Pr::Fitted::Forward { }; } // namespace detail + enum struct CovXVector { x_x, x_tx, tx_tx }; + enum struct CovYVector { y_y, y_ty, ty_ty }; + struct Tag { struct trackSeed : Event::int_field {}; - struct StateQoP : Event::float_field {}; struct Chi2 : Event::float_field {}; struct Chi2nDoF : Event::int_field {}; struct UniqueID : Event::int_field {}; - struct StatePosition : Event::state_field {}; + struct State : Event::state_field {}; struct StateCovX : Event::floats_field<TracksInfo::NumCovXY> {}; struct StateCovY : Event::floats_field<TracksInfo::NumCovXY> {}; template <typename T> - using fitfwd_t = - Event::SOACollection<T, trackSeed, StateQoP, Chi2, Chi2nDoF, UniqueID, StatePosition, StateCovX, StateCovY>; + using fitfwd_t = Event::SOACollection<T, trackSeed, Chi2, Chi2nDoF, UniqueID, State, StateCovX, StateCovY>; }; + namespace SP = LHCb::Event::StateParameters; + struct Tracks : Tag::fitfwd_t<Tracks> { using base_t = typename Tag::fitfwd_t<Tracks>; @@ -91,13 +94,13 @@ namespace LHCb::Pr::Fitted::Forward { struct FittedProxy : Event::Proxy<simd, behaviour, ContainerType> { using Event::Proxy<simd, behaviour, ContainerType>::Proxy; - [[nodiscard]] auto qOverP() const { return this->template get<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP() const { return this->template get<Tag::State>().qOverP(); } [[nodiscard]] auto p() const { return abs( 1.f / qOverP() ); } [[nodiscard]] auto chi2() const { return this->template get<Tag::Chi2>(); } [[nodiscard]] auto nDoF() const { return this->template get<Tag::Chi2nDoF>(); } [[nodiscard]] auto pt() const { auto const mom = p(); - auto const s = this->template get<Tag::StatePosition>(); + auto const s = this->template get<Tag::State>(); auto const tx2ty2 = s.tx() * s.tx() + s.ty() * s.ty(); auto const pt2 = mom * mom * tx2ty2 / ( tx2ty2 + 1 ); using std::sqrt; @@ -105,14 +108,14 @@ namespace LHCb::Pr::Fitted::Forward { } template <typename dType> [[nodiscard]] auto closestToBeamStatePos() const { - return Vec3<typename dType::float_v>( this->template get<Tag::StatePosition>().x(), - this->template get<Tag::StatePosition>().y(), - this->template get<Tag::StatePosition>().z() ); + return Vec3<typename dType::float_v>( this->template get<Tag::State>().x(), + this->template get<Tag::State>().y(), + this->template get<Tag::State>().z() ); } template <typename dType> [[nodiscard]] auto closestToBeamStateDir() const { - return Vec3<typename dType::float_v>( this->template get<Tag::StatePosition>().tx(), - this->template get<Tag::StatePosition>().ty(), 1.f ); + return Vec3<typename dType::float_v>( this->template get<Tag::State>().tx(), + this->template get<Tag::State>().ty(), 1.f ); } template <typename dType> [[nodiscard]] auto covX() const { @@ -154,7 +157,7 @@ namespace LHCb::Pr::Fitted::Forward { public: [[nodiscard]] auto trackSeed() const { return loader<Tag::trackSeed>(); } - [[nodiscard]] auto qOverP() const { return loader<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP() const { return loader<Tag::State>( SP::StateVector::qOverP ); } [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto chi2() const { return loader<Tag::Chi2>(); } [[nodiscard]] auto chi2nDoF() const { return loader<Tag::Chi2nDoF>(); } @@ -167,7 +170,9 @@ namespace LHCb::Pr::Fitted::Forward { [[nodiscard]] auto unique_id_gen_tag() const { return this->m_Tracks->unique_id_gen_tag(); } - [[nodiscard]] auto StatePosElement( std::size_t i ) const { return loader<Tag::StatePosition>( i ); } + [[nodiscard]] auto StatePosElement( SP::StateVector j ) const { + return loader<Tag::State>( static_cast<std::size_t>( j ) ); + } [[nodiscard]] auto covX() const { return Vec3<FType>( loader<Tag::StateCovX>( 0 ), loader<Tag::StateCovX>( 1 ), loader<Tag::StateCovX>( 2 ) ); } @@ -201,9 +206,12 @@ namespace LHCb::Pr::Fitted::Forward { } auto closestToBeamStatePos() const { - return Vec3<FType>( StatePosElement( 0 ), StatePosElement( 1 ), StatePosElement( 2 ) ); + return Vec3<FType>( StatePosElement( SP::StateVector::x ), StatePosElement( SP::StateVector::y ), + StatePosElement( SP::StateVector::z ) ); + } + auto closestToBeamStateDir() const { + return Vec3<FType>( StatePosElement( SP::StateVector::tx ), StatePosElement( SP::StateVector::ty ), 1.f ); } - auto closestToBeamStateDir() const { return Vec3<FType>( StatePosElement( 3 ), StatePosElement( 4 ), 1.f ); } /** Return a proxy that exposes the a state-like API instead of the * track-like API of this struct. The use of `clone<Proxy>()` discards the * pointers to possible other members of the zip, which cannot be needed diff --git a/Event/TrackEvent/include/Event/PrLongTracks.h b/Event/TrackEvent/include/Event/PrLongTracks.h index a306d829982dcd736b45edc745f0f209e61fd654..28a5156b0ff594fcd3bf72b929d15ef5d5f6cd3d 100644 --- a/Event/TrackEvent/include/Event/PrLongTracks.h +++ b/Event/TrackEvent/include/Event/PrLongTracks.h @@ -36,7 +36,6 @@ namespace LHCb::Pr::Long { struct trackVP : Event::int_field {}; struct trackUT : Event::int_field {}; struct trackSeed : Event::int_field {}; - struct StateQoP : Event::float_field {}; struct nVPHits : Event::int_field {}; struct nUTHits : Event::int_field {}; struct nFTHits : Event::int_field {}; @@ -44,23 +43,23 @@ namespace LHCb::Pr::Long { struct ut_indices : Event::ints_field<TracksInfo::MaxUTHits> {}; struct ft_indices : Event::ints_field<TracksInfo::MaxFTHits> {}; struct lhcbIDs : Event::ints_field<TracksInfo::MaxFTHits + TracksInfo::MaxVPHits + TracksInfo::MaxUTHits> {}; - struct StatePositions : Event::states_field<TracksInfo::NumLongStates> {}; + struct States : Event::states_field<TracksInfo::NumLongStates> {}; template <typename T> - using long_t = Event::SOACollection<T, trackVP, trackUT, trackSeed, StateQoP, nVPHits, nUTHits, nFTHits, vp_indices, - ut_indices, ft_indices, lhcbIDs, StatePositions>; + using long_t = Event::SOACollection<T, trackVP, trackUT, trackSeed, nVPHits, nUTHits, nFTHits, vp_indices, + ut_indices, ft_indices, lhcbIDs, States>; }; + namespace SP = LHCb::Event::StateParameters; + struct Tracks : Tag::long_t<Tracks> { using base_t = typename Tag::long_t<Tracks>; - constexpr static auto NumStatePars = TracksInfo::NumStatePars; - constexpr static auto NumLongStates = TracksInfo::NumLongStates; // number of state 0: vstate, 1: Tstate - constexpr static auto NumLongStatePars = NumStatePars * NumLongStates; - constexpr static auto MaxVPHits = TracksInfo::MaxVPHits; - constexpr static auto MaxUTHits = TracksInfo::MaxUTHits; - constexpr static auto MaxFTHits = TracksInfo::MaxFTHits; - constexpr static auto MaxLHCbIDs = TracksInfo::MaxFTHits + TracksInfo::MaxVPHits + TracksInfo::MaxUTHits; + constexpr static auto NumLongStates = TracksInfo::NumLongStates; // number of state 0: vstate, 1: Tstate + constexpr static auto MaxVPHits = TracksInfo::MaxVPHits; + constexpr static auto MaxUTHits = TracksInfo::MaxUTHits; + constexpr static auto MaxFTHits = TracksInfo::MaxFTHits; + constexpr static auto MaxLHCbIDs = TracksInfo::MaxFTHits + TracksInfo::MaxVPHits + TracksInfo::MaxUTHits; using base_t::allocator_type; @@ -84,16 +83,6 @@ namespace LHCb::Pr::Long { [[nodiscard]] Upstream::Tracks const* getUpstreamAncestors() const { return m_upstream_ancestors; }; [[nodiscard]] Seeding::Tracks const* getSeedAncestors() const { return m_seed_ancestors; }; - template <typename F, typename M = std::true_type> - void store_StatePosDir( int at, int state, Vec3<F> const& pos, Vec3<F> const& dir, M&& mask = {} ) { - // state 0: velo, state 1: T - store<Tag::StatePositions>( at, state, 0, pos.x, mask ); - store<Tag::StatePositions>( at, state, 1, pos.y, mask ); - store<Tag::StatePositions>( at, state, 2, pos.z, mask ); - store<Tag::StatePositions>( at, state, 3, dir.x, mask ); - store<Tag::StatePositions>( at, state, 4, dir.y, mask ); - } - template <typename I, typename M = std::true_type> void store_vp_index( int at, int i, I const& vpidx, M&& mask = {} ) { store<Tag::vp_indices>( at, i, vpidx, mask ); @@ -110,12 +99,18 @@ namespace LHCb::Pr::Long { void store_lhcbID( int at, int i, I const& lhcbid, M&& mask = {} ) { store<Tag::lhcbIDs>( at, i, lhcbid, mask ); } + template <typename F, typename M = std::true_type> + void store_qOverP( int at, int iState, F const& qOverP, M&& mask = {} ) { + store<Tag::States>( at, iState, SP::StateVector::qOverP, qOverP, mask ); + } // Define an minimal custom proxy for this track template <SIMDWrapper::InstructionSet simd, ProxyBehaviour behaviour, typename ContainerType> struct LongProxy : Event::Proxy<simd, behaviour, ContainerType> { using Event::Proxy<simd, behaviour, ContainerType>::Proxy; - [[nodiscard]] auto qOverP() const { return this->template get<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP( std::size_t iState = 0 ) const { + return this->template get<Tag::States>( iState ).qOverP(); + } [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto nVPHits() const { return this->template get<Tag::nVPHits>(); } [[nodiscard]] auto nUTHits() const { return this->template get<Tag::nUTHits>(); } @@ -132,6 +127,16 @@ namespace LHCb::Pr::Long { template <SIMDWrapper::InstructionSet simd, ProxyBehaviour behaviour, typename ContainerType> using proxy_type = LongProxy<simd, behaviour, ContainerType>; + template <typename F, typename M = std::true_type> + void store_StatePosDir( int at, int state, Vec3<F> const& pos, Vec3<F> const& dir, M&& mask = {} ) { + // state 0: velo, state 1: T + store<Tag::States>( at, state, SP::StateVector::x, pos.x, mask ); + store<Tag::States>( at, state, SP::StateVector::y, pos.y, mask ); + store<Tag::States>( at, state, SP::StateVector::z, pos.z, mask ); + store<Tag::States>( at, state, SP::StateVector::tx, dir.x, mask ); + store<Tag::States>( at, state, SP::StateVector::ty, dir.y, mask ); + } + private: Velo::Tracks const* m_velo_ancestors{nullptr}; Upstream::Tracks const* m_upstream_ancestors{nullptr}; @@ -155,7 +160,9 @@ namespace LHCb::Pr::Long { [[nodiscard]] auto trackVP() const { return loader<Tag::trackVP>(); } [[nodiscard]] auto trackUT() const { return loader<Tag::trackUT>(); } [[nodiscard]] auto trackSeed() const { return loader<Tag::trackSeed>(); } - [[nodiscard]] auto qOverP() const { return loader<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP( std::size_t iState = 0 ) const { + return loader<Tag::States>( iState, SP::StateVector::qOverP ); + } [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto nVPHits() const { return loader<Tag::nVPHits>(); } [[nodiscard]] auto nUTHits() const { return loader<Tag::nUTHits>(); } @@ -166,22 +173,26 @@ namespace LHCb::Pr::Long { [[nodiscard]] auto ut_index( std::size_t i ) const { return loader<Tag::ut_indices>( i ); } [[nodiscard]] auto ft_index( std::size_t i ) const { return loader<Tag::ft_indices>( i ); } [[nodiscard]] auto lhcbID( std::size_t i ) const { return loader<Tag::lhcbIDs>( i ); } - [[nodiscard]] auto StatePosElement( std::size_t i, std::size_t j ) const { - return loader<Tag::StatePositions>( i, j ); + [[nodiscard]] auto StatePosElement( std::size_t i, SP::StateVector j ) const { + return loader<Tag::States>( i, static_cast<std::size_t>( j ) ); } // Retrieve state Info [[nodiscard]] auto StatePosDir( std::size_t i ) const { - using LHCb::Utils::unwind; - LHCb::LinAlg::Vec<decltype( this->StatePosElement( 0, 0 ) ), TracksInfo::NumStatePars> out; - unwind<0, TracksInfo::NumStatePars>( [&]( auto j ) { out( j ) = this->StatePosElement( i, j ); } ); + LHCb::LinAlg::Vec<decltype( this->StatePosElement( 0, SP::StateVector::x ) ), TracksInfo::NumPosDirPars> out; + out( 0 ) = this->StatePosElement( i, SP::StateVector::x ); + out( 1 ) = this->StatePosElement( i, SP::StateVector::y ); + out( 2 ) = this->StatePosElement( i, SP::StateVector::z ); + out( 3 ) = this->StatePosElement( i, SP::StateVector::tx ); + out( 4 ) = this->StatePosElement( i, SP::StateVector::ty ); return out; } [[nodiscard]] auto StatePos( std::size_t i ) const { - return Vec3<FType>( StatePosDir( i )( 0 ), StatePosDir( i )( 1 ), StatePosDir( i )( 2 ) ); + return Vec3<FType>( StatePosElement( i, SP::StateVector::x ), StatePosElement( i, SP::StateVector::y ), + StatePosElement( i, SP::StateVector::z ) ); } [[nodiscard]] auto StateDir( std::size_t i ) const { - return Vec3<FType>( StatePosDir( i )( 3 ), StatePosDir( i )( 4 ), 1.f ); + return Vec3<FType>( StatePosElement( i, SP::StateVector::tx ), StatePosElement( i, SP::StateVector::ty ), 1.f ); } // Retrieve the set of LHCbIDs [[nodiscard]] std::vector<LHCbID> lhcbIDs() const { diff --git a/Event/TrackEvent/include/Event/PrSeedTracks.h b/Event/TrackEvent/include/Event/PrSeedTracks.h index 5458aff3e5a36c1fee18dbbac67f76bbf17e8e7c..81346804287c7926b6e273eee2d399166359aeee 100644 --- a/Event/TrackEvent/include/Event/PrSeedTracks.h +++ b/Event/TrackEvent/include/Event/PrSeedTracks.h @@ -99,18 +99,19 @@ namespace LHCb::Pr::Seeding { struct Tag { - struct StateQoP : Event::float_field {}; struct Chi2PerDoF : Event::float_field {}; struct nFTHits : Event::int_field {}; struct ft_indices : Event::ints_field<TracksInfo::MaxFTHits> {}; struct lhcbIDs : Event::ints_field<TracksInfo::MaxFTHits> {}; - struct StatePositions : Event::states_field<TracksInfo::NumSeedStates> {}; + struct States : Event::states_field<TracksInfo::NumSeedStates> {}; template <typename T> - using seed_t = Event::SOACollection<T, StateQoP, Chi2PerDoF, nFTHits, ft_indices, lhcbIDs, StatePositions>; + using seed_t = Event::SOACollection<T, Chi2PerDoF, nFTHits, ft_indices, lhcbIDs, States>; }; + namespace SP = LHCb::Event::StateParameters; + struct Tracks : Tag::seed_t<Tracks> { using base_t = typename Tag::seed_t<Tracks>; using base_t::base_t; @@ -123,7 +124,9 @@ namespace LHCb::Pr::Seeding { struct SeedProxy : Event::Proxy<simd, behaviour, ContainerType> { using Event::Proxy<simd, behaviour, ContainerType>::Proxy; - [[nodiscard]] auto qOverP() const { return this->template get<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP( std::size_t iState = 0 ) const { + return this->template get<Tag::States>( iState ).qOverP(); + } [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto chi2PerDoF() const { return this->template get<Tag::Chi2PerDoF>(); } [[nodiscard]] auto nHits() const { return this->template get<Tag::nFTHits>(); } @@ -131,9 +134,9 @@ namespace LHCb::Pr::Seeding { [[nodiscard]] auto ft_index( std::size_t i ) const { return this->template get<Tag::ft_indices>( i ); } [[nodiscard]] auto lhcbID( std::size_t i ) const { return this->template get<Tag::lhcbIDs>( i ); } [[nodiscard]] LHCb::State getLHCbState( std::size_t iState ) const { - auto v = this->template get<Tag::StatePositions>( iState ); + auto v = this->template get<Tag::States>( iState ); LHCb::StateVector sv{ - {v.x().cast(), v.y().cast(), v.z().cast()}, {v.tx().cast(), v.ty().cast(), 1.f}, qOverP().cast()}; + {v.x().cast(), v.y().cast(), v.z().cast()}, {v.tx().cast(), v.ty().cast(), 1.f}, qOverP( iState ).cast()}; LHCb::State state; state.setState( sv ); diff --git a/Event/TrackEvent/include/Event/PrTracksTag.h b/Event/TrackEvent/include/Event/PrTracksTag.h index 6588e878a254a82fce64d65277b46d163146f9ab..f7b8e0fc92f7e5bf3b35efb8d8646f61146406a5 100644 --- a/Event/TrackEvent/include/Event/PrTracksTag.h +++ b/Event/TrackEvent/include/Event/PrTracksTag.h @@ -14,12 +14,129 @@ #include "GaudiKernel/SymmetricMatrixTypes.h" #include "LHCbMath/Vec3.h" +namespace LHCb::Event::StateParameters { + + enum struct StateVector { x, y, tx, ty, qOverP, z }; + + enum struct CovMatrix { + x_x, + x_y, + x_tx, + x_ty, + x_qOverP, + y_y, + y_tx, + y_ty, + y_qOverP, + tx_tx, + tx_ty, + tx_qOverP, + ty_ty, + ty_qOverP, + qOverP_qOverP + }; + + constexpr unsigned int operator+( unsigned int i, StateVector s ) { return i + static_cast<unsigned>( s ); } + + constexpr unsigned int operator+( unsigned int i, CovMatrix s ) { return i + static_cast<unsigned>( s ); } +} // namespace LHCb::Event::StateParameters + +namespace LHCb::Event::PosDirParameters { + + enum struct PosDirVector { x, y, z, tx, ty }; + + constexpr unsigned int operator+( unsigned int i, PosDirVector s ) { return i + static_cast<unsigned>( s ); } + +} // namespace LHCb::Event::PosDirParameters + namespace LHCb::Event { /** - * Tag and Proxy baseclasses for representing a 5 parameters state vector (x, y, z, tx, ty) + * Tag and Proxy baseclasses for representing a 6 parameters state vector (x, y, tx, ty, q/p, z) + */ + template <std::size_t... N> + struct states_field : floats_field<N..., 6> { + template <typename Tag, SIMDWrapper::InstructionSet Simd, LHCb::Pr::ProxyBehaviour Behaviour, + typename ContainerType, typename... Ts> + struct NDStateProxy { + using simd_t = SIMDWrapper::type_map_t<Simd>; + using type = typename Tag::template vec_type<simd_t>; + using OffsetType = LHCb::Pr::detail::offset_t<Behaviour, Simd>; + using proxy_type = NDNumericProxy<Tag, Simd, Behaviour, ContainerType, Ts..., std::size_t>; + + NDStateProxy( ContainerType* container, OffsetType offset, Ts... Is ) + : m_container( container ), m_offset( offset ), m_indices( Is... ) {} + + template <StateParameters::StateVector i> + [[nodiscard]] constexpr auto proxy() const { + return std::apply( + [&]( auto&&... args ) { + return proxy_type{m_container, m_offset, std::forward<decltype( args )>( args )..., + static_cast<unsigned>( i )}; + }, + m_indices ); + } + + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x() const { + return proxy<StateParameters::StateVector::x>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y() const { + return proxy<StateParameters::StateVector::y>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx() const { + return proxy<StateParameters::StateVector::tx>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto ty() const { + return proxy<StateParameters::StateVector::ty>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto qOverP() const { + return proxy<StateParameters::StateVector::qOverP>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto z() const { + return proxy<StateParameters::StateVector::z>().get(); + } + + inline __attribute__( ( always_inline ) ) constexpr void setPosition( type const& x, type const& y, + type const& z ) { + proxy<StateParameters::StateVector::x>().set( x ); + proxy<StateParameters::StateVector::y>().set( y ); + proxy<StateParameters::StateVector::z>().set( z ); + } + + inline __attribute__( ( always_inline ) ) constexpr void setDirection( type const& tx, type const& ty ) { + proxy<StateParameters::StateVector::tx>().set( tx ); + proxy<StateParameters::StateVector::ty>().set( ty ); + } + + inline __attribute__( ( always_inline ) ) constexpr void setQOverP( type const& qOverP ) { + proxy<StateParameters::StateVector::qOverP>().set( qOverP ); + } + + [[deprecated]] inline __attribute__( ( always_inline ) ) constexpr void + set( type const& x, type const& y, type const& z, type const& tx, type const& ty, type const& qOverP ) { + setPosition( x, y, z ); + setDirection( tx, ty ); + setQOverP( qOverP ); + } + + constexpr auto get() const { return *this; } + + private: + ContainerType* m_container; + OffsetType m_offset; + const std::tuple<Ts...> m_indices; + }; + + template <typename Tag, SIMDWrapper::InstructionSet Simd, LHCb::Pr::ProxyBehaviour Behaviour, + typename ContainerType, typename... Ts> + using proxy_type = NDStateProxy<Tag, Simd, Behaviour, ContainerType, Ts...>; + }; + using state_field = states_field<>; + + /** + * Tag and Proxy baseclasses for representing a position (x,y,z) and a direction (tx, ty), no momentum */ template <std::size_t... N> - struct states_field : floats_field<N..., 5> { + struct pos_dirs_field : floats_field<N..., 5> { template <typename Tag, SIMDWrapper::InstructionSet Simd, LHCb::Pr::ProxyBehaviour Behaviour, typename ContainerType, typename... Ts> struct NDStateProxy { @@ -31,31 +148,42 @@ namespace LHCb::Event { NDStateProxy( ContainerType* container, OffsetType offset, Ts... Is ) : m_container( container ), m_offset( offset ), m_indices( Is... ) {} - template <auto i> + template <PosDirParameters::PosDirVector i> [[nodiscard]] constexpr auto proxy() const { return std::apply( [&]( auto&&... args ) { - return proxy_type{m_container, m_offset, std::forward<decltype( args )>( args )..., i}; + return proxy_type{m_container, m_offset, std::forward<decltype( args )>( args )..., + static_cast<unsigned>( i )}; }, m_indices ); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x() const { return proxy<0>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y() const { return proxy<1>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto z() const { return proxy<2>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx() const { return proxy<3>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto ty() const { return proxy<4>().get(); } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x() const { + return proxy<PosDirParameters::PosDirVector::x>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y() const { + return proxy<PosDirParameters::PosDirVector::y>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx() const { + return proxy<PosDirParameters::PosDirVector::tx>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto ty() const { + return proxy<PosDirParameters::PosDirVector::ty>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto z() const { + return proxy<PosDirParameters::PosDirVector::z>().get(); + } inline __attribute__( ( always_inline ) ) constexpr void setPosition( type const& x, type const& y, type const& z ) { - proxy<0>().set( x ); - proxy<1>().set( y ); - proxy<2>().set( z ); + proxy<PosDirParameters::PosDirVector::x>().set( x ); + proxy<PosDirParameters::PosDirVector::y>().set( y ); + proxy<PosDirParameters::PosDirVector::z>().set( z ); } inline __attribute__( ( always_inline ) ) constexpr void setDirection( type const& tx, type const& ty ) { - proxy<3>().set( tx ); - proxy<4>().set( ty ); + proxy<PosDirParameters::PosDirVector::tx>().set( tx ); + proxy<PosDirParameters::PosDirVector::ty>().set( ty ); } inline __attribute__( ( always_inline ) ) constexpr void set( type const& x, type const& y, type const& z, @@ -76,7 +204,7 @@ namespace LHCb::Event { typename ContainerType, typename... Ts> using proxy_type = NDStateProxy<Tag, Simd, Behaviour, ContainerType, Ts...>; }; - using state_field = states_field<>; + using pos_dir_field = pos_dirs_field<>; /** * Tag and Proxy baseclasses for representing a 5 X 5 state covariance matrix: @@ -104,77 +232,98 @@ namespace LHCb::Event { StateCovProxy( ContainerType* container, OffsetType offset, Ts... Is ) : m_container( container ), m_offset( offset ), m_indices( Is... ) {} - template <auto i> + template <StateParameters::CovMatrix i> [[nodiscard]] constexpr auto proxy() const { return std::apply( [&]( auto&&... args ) { - return proxy_type{m_container, m_offset, std::forward<decltype( args )>( args )..., i}; + return proxy_type{m_container, m_offset, std::forward<decltype( args )>( args )..., + static_cast<unsigned>( i )}; }, m_indices ); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_x() const { return proxy<0>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_y() const { return proxy<1>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_tx() const { return proxy<2>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_ty() const { return proxy<3>().get(); } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_x() const { + return proxy<StateParameters::CovMatrix::x_x>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_y() const { + return proxy<StateParameters::CovMatrix::x_y>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_tx() const { + return proxy<StateParameters::CovMatrix::x_tx>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_ty() const { + return proxy<StateParameters::CovMatrix::x_ty>().get(); + } [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x_QoverP() const { - return proxy<4>().get(); + return proxy<StateParameters::CovMatrix::x_qOverP>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y_y() const { return proxy<5>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y_tx() const { return proxy<6>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y_ty() const { return proxy<7>().get(); } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y_y() const { + return proxy<StateParameters::CovMatrix::y_y>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y_tx() const { + return proxy<StateParameters::CovMatrix::y_tx>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y_ty() const { + return proxy<StateParameters::CovMatrix::y_ty>().get(); + } [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y_QoverP() const { - return proxy<8>().get(); + return proxy<StateParameters::CovMatrix::y_qOverP>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx_tx() const { return proxy<9>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx_ty() const { return proxy<10>().get(); } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx_tx() const { + return proxy<StateParameters::CovMatrix::tx_tx>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx_ty() const { + return proxy<StateParameters::CovMatrix::tx_ty>().get(); + } [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto tx_QoverP() const { - return proxy<11>().get(); + return proxy<StateParameters::CovMatrix::tx_qOverP>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto ty_ty() const { return proxy<12>().get(); } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto ty_ty() const { + return proxy<StateParameters::CovMatrix::ty_ty>().get(); + } [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto ty_QoverP() const { - return proxy<13>().get(); + return proxy<StateParameters::CovMatrix::ty_qOverP>().get(); } [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto QoverP_QoverP() const { - return proxy<14>().get(); + return proxy<StateParameters::CovMatrix::qOverP_qOverP>().get(); } inline __attribute__( ( always_inline ) ) constexpr void setXCovariance( type const& x_x, type const& x_y, type const& x_tx, type const& x_ty, type const& x_QoverP ) { - proxy<0>().set( x_x ); - proxy<1>().set( x_y ); - proxy<2>().set( x_tx ); - proxy<3>().set( x_ty ); - proxy<4>().set( x_QoverP ); + proxy<StateParameters::CovMatrix::x_x>().set( x_x ); + proxy<StateParameters::CovMatrix::x_y>().set( x_y ); + proxy<StateParameters::CovMatrix::x_tx>().set( x_tx ); + proxy<StateParameters::CovMatrix::x_ty>().set( x_ty ); + proxy<StateParameters::CovMatrix::x_qOverP>().set( x_QoverP ); } inline __attribute__( ( always_inline ) ) constexpr void setYCovariance( type const& y_y, type const& y_tx, type const& y_ty, type const& y_QoverP ) { - proxy<5>().set( y_y ); - proxy<6>().set( y_tx ); - proxy<7>().set( y_ty ); - proxy<8>().set( y_QoverP ); + proxy<StateParameters::CovMatrix::y_y>().set( y_y ); + proxy<StateParameters::CovMatrix::y_tx>().set( y_tx ); + proxy<StateParameters::CovMatrix::y_ty>().set( y_ty ); + proxy<StateParameters::CovMatrix::y_qOverP>().set( y_QoverP ); } inline __attribute__( ( always_inline ) ) constexpr void setTXCovariance( type const& tx_tx, type const& tx_ty, type const& tx_QoverP ) { - proxy<9>().set( tx_tx ); - proxy<10>().set( tx_ty ); - proxy<11>().set( tx_QoverP ); + proxy<StateParameters::CovMatrix::tx_tx>().set( tx_tx ); + proxy<StateParameters::CovMatrix::tx_ty>().set( tx_ty ); + proxy<StateParameters::CovMatrix::tx_qOverP>().set( tx_QoverP ); } inline __attribute__( ( always_inline ) ) constexpr void setTYCovariance( type const& ty_ty, type const& ty_QoverP ) { - proxy<12>().set( ty_ty ); - proxy<13>().set( ty_QoverP ); + proxy<StateParameters::CovMatrix::ty_ty>().set( ty_ty ); + proxy<StateParameters::CovMatrix::ty_qOverP>().set( ty_QoverP ); } inline __attribute__( ( always_inline ) ) constexpr void setQoverPCovariance( type const& QoverP_QoverP ) { - proxy<14>().set( QoverP_QoverP ); + proxy<StateParameters::CovMatrix::qOverP_qOverP>().set( QoverP_QoverP ); } inline __attribute__( ( always_inline ) ) constexpr void set( type const& x_x, type const& x_y, type const& x_tx, type const& x_ty, type const& x_QoverP, type const& y_y, @@ -215,31 +364,38 @@ namespace LHCb::Event { Vec3Proxy( ContainerType* container, OffsetType offset, Ts... Is ) : m_container( container ), m_offset( offset ), m_indices( Is... ) {} - template <auto i> + template <PosDirParameters::PosDirVector i> [[nodiscard]] constexpr auto proxy() const { return std::apply( [&]( auto&&... args ) { - return proxy_type{m_container, m_offset, std::forward<decltype( args )>( args )..., i}; + return proxy_type{m_container, m_offset, std::forward<decltype( args )>( args )..., + static_cast<unsigned>( i )}; }, m_indices ); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x() const { return proxy<0>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y() const { return proxy<1>().get(); } - [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto z() const { return proxy<2>().get(); } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto x() const { + return proxy<PosDirParameters::PosDirVector::x>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto y() const { + return proxy<PosDirParameters::PosDirVector::y>().get(); + } + [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto z() const { + return proxy<PosDirParameters::PosDirVector::z>().get(); + } [[nodiscard]] inline __attribute__( ( always_inline ) ) constexpr auto vec3() const { return Vec3<type>( x(), y(), z() ); } inline __attribute__( ( always_inline ) ) constexpr void set( type const& x, type const& y, type const& z ) { - proxy<0>().set( x ); - proxy<1>().set( y ); - proxy<2>().set( z ); + proxy<PosDirParameters::PosDirVector::x>().set( x ); + proxy<PosDirParameters::PosDirVector::y>().set( y ); + proxy<PosDirParameters::PosDirVector::z>().set( z ); } inline __attribute__( ( always_inline ) ) constexpr void set( Vec3<type> const& vec ) { - proxy<0>().set( vec.x ); - proxy<1>().set( vec.y ); - proxy<2>().set( vec.z ); + proxy<PosDirParameters::PosDirVector::x>().set( vec.x ); + proxy<PosDirParameters::PosDirVector::y>().set( vec.y ); + proxy<PosDirParameters::PosDirVector::z>().set( vec.z ); } constexpr auto get() const { return *this; } @@ -264,7 +420,7 @@ namespace LHCb::Pr::TracksInfo { // The total layers of each sub-detector enum class DetLayers { VPLayers = 26, FTLayers = 12, UTLayers = 4 }; // The maximum number of hits for PrLongTracks, depends on the pattern recognition - inline constexpr std::size_t NumStatePars = 5; // statePosVec vector(5D) (x,y,z,dx,dy) + inline constexpr std::size_t NumPosDirPars = 5; // statePosVec vector(5D) (x,y,z,dx,dy) inline constexpr std::size_t NumSeedStates = 3; inline constexpr std::size_t NumLongStates = 2; inline constexpr std::size_t NumVeloStates = 2; diff --git a/Event/TrackEvent/include/Event/PrUpstreamTracks.h b/Event/TrackEvent/include/Event/PrUpstreamTracks.h index 7360dd90dbeb4b6215b2ab12ad4edb65a64ab905..f557f8e9e26d7bda8441712460ee404a175e4657 100644 --- a/Event/TrackEvent/include/Event/PrUpstreamTracks.h +++ b/Event/TrackEvent/include/Event/PrUpstreamTracks.h @@ -33,22 +33,25 @@ namespace LHCb::Pr::Upstream { + enum struct CovXVector { x_x, x_tx, tx_tx }; + struct Tag { struct trackVP : Event::int_field {}; - struct StateQoP : Event::float_field {}; struct nVPHits : Event::int_field {}; struct nUTHits : Event::int_field {}; struct vp_indices : Event::ints_field<TracksInfo::MaxVPHits> {}; struct ut_indices : Event::ints_field<TracksInfo::MaxUTHits> {}; struct lhcbIDs : Event::ints_field<TracksInfo::MaxVPHits + TracksInfo::MaxUTHits> {}; - struct StatePosition : Event::state_field {}; + struct State : Event::state_field {}; struct StateCovX : Event::floats_field<TracksInfo::NumCovXY> {}; template <typename T> - using upstream_t = Event::SOACollection<T, trackVP, StateQoP, nVPHits, nUTHits, vp_indices, ut_indices, lhcbIDs, - StatePosition, StateCovX>; + using upstream_t = + Event::SOACollection<T, trackVP, nVPHits, nUTHits, vp_indices, ut_indices, lhcbIDs, State, StateCovX>; }; + namespace SP = LHCb::Event::StateParameters; + struct Tracks : Tag::upstream_t<Tracks> { using base_t = typename Tag::upstream_t<Tracks>; @@ -71,17 +74,21 @@ namespace LHCb::Pr::Upstream { template <typename F, typename M = std::true_type> void store_StatePosDir( int at, Vec3<F> const& pos, Vec3<F> const& dir, M&& mask = {} ) { - store<Tag::StatePosition>( at, 0, pos.x, mask ); - store<Tag::StatePosition>( at, 1, pos.y, mask ); - store<Tag::StatePosition>( at, 2, pos.z, mask ); - store<Tag::StatePosition>( at, 3, dir.x, mask ); - store<Tag::StatePosition>( at, 4, dir.y, mask ); + store<Tag::State>( at, SP::StateVector::x, pos.x, mask ); + store<Tag::State>( at, SP::StateVector::y, pos.y, mask ); + store<Tag::State>( at, SP::StateVector::z, pos.z, mask ); + store<Tag::State>( at, SP::StateVector::tx, dir.x, mask ); + store<Tag::State>( at, SP::StateVector::ty, dir.y, mask ); + } + template <typename F, typename M = std::true_type> + void store_qOverP( int at, F const& qOverP, M&& mask = {} ) { + store<Tag::State>( at, SP::StateVector::qOverP, qOverP, mask ); } template <typename F, typename M = std::true_type> void store_StateCovX( int at, Vec3<F> const& covx, M&& mask = {} ) { - store<Tag::StateCovX>( at, 0, covx.x, mask ); - store<Tag::StateCovX>( at, 1, covx.y, mask ); - store<Tag::StateCovX>( at, 2, covx.z, mask ); + store<Tag::StateCovX>( at, CovXVector::x_x, covx.x, mask ); + store<Tag::StateCovX>( at, CovXVector::x_tx, covx.y, mask ); + store<Tag::StateCovX>( at, CovXVector::tx_tx, covx.z, mask ); } template <typename I, typename M = std::true_type> void store_vp_index( int at, int i, I const& vpidx, M&& mask = {} ) { @@ -100,7 +107,7 @@ namespace LHCb::Pr::Upstream { template <SIMDWrapper::InstructionSet simd, ProxyBehaviour behaviour, typename ContainerType> struct UpstreamProxy : Event::Proxy<simd, behaviour, ContainerType> { using Event::Proxy<simd, behaviour, ContainerType>::Proxy; - [[nodiscard]] auto qOverP() const { return this->template get<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP() const { return this->template get<Tag::State>().qOverP(); } [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto nUTHits() const { return this->template get<Tag::nUTHits>(); } [[nodiscard]] auto nVPHits() const { return this->template get<Tag::nVPHits>(); } @@ -129,7 +136,7 @@ namespace LHCb::Pr::Upstream { } public: - [[nodiscard]] auto qOverP() const { return loader<Tag::StateQoP>(); } + [[nodiscard]] auto qOverP() const { return loader<Tag::State>( SP::StateVector::qOverP ); } [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto trackVP() const { return loader<Tag::trackVP>(); } [[nodiscard]] auto nVPHits() const { return loader<Tag::nVPHits>(); } @@ -148,16 +155,23 @@ namespace LHCb::Pr::Upstream { for ( auto i = 0; i < nUTHits().hmax( this->loop_mask() ); i++ ) out[i] = ut_index( i ); return out; } + [[nodiscard]] auto lhcbID( std::size_t i ) const { return loader<Tag::lhcbIDs>( i ); } - [[nodiscard]] auto StatePosElement( std::size_t i ) const { return loader<Tag::StatePosition>( i ); } - [[nodiscard]] auto StateCovElement( std::size_t i ) const { return loader<Tag::StateCovX>( i ); } + [[nodiscard]] auto StatePosElement( SP::StateVector i ) const { + return loader<Tag::State>( static_cast<int>( i ) ); + } + [[nodiscard]] auto StateCovElement( CovXVector i ) const { return loader<Tag::StateCovX>( static_cast<int>( i ) ); } // Retrieve state info [[nodiscard]] auto StatePos() const { - return Vec3<FType>( StatePosElement( 0 ), StatePosElement( 1 ), StatePosElement( 2 ) ); + return Vec3<FType>( StatePosElement( SP::StateVector::x ), StatePosElement( SP::StateVector::y ), + StatePosElement( SP::StateVector::z ) ); + } + [[nodiscard]] auto StateDir() const { + return Vec3<FType>( StatePosElement( SP::StateVector::tx ), StatePosElement( SP::StateVector::ty ), 1.f ); } - [[nodiscard]] auto StateDir() const { return Vec3<FType>( StatePosElement( 3 ), StatePosElement( 4 ), 1.f ); } [[nodiscard]] auto StateCov() const { - return Vec3<FType>( StateCovElement( 0 ), StateCovElement( 1 ), StateCovElement( 2 ) ); + return Vec3<FType>( StateCovElement( CovXVector::x_x ), StateCovElement( CovXVector::x_tx ), + StateCovElement( CovXVector::tx_tx ) ); } // Retrieve the (sorted) set of LHCbIDs [[nodiscard]] std::vector<LHCbID> lhcbIDs() const { diff --git a/Event/TrackEvent/include/Event/PrVeloTracks.h b/Event/TrackEvent/include/Event/PrVeloTracks.h index d7d56b0f027eef0eb4d282e1a976d023286ae22d..e7213aee539790921e8897ee0ec73d601b674df9 100644 --- a/Event/TrackEvent/include/Event/PrVeloTracks.h +++ b/Event/TrackEvent/include/Event/PrVeloTracks.h @@ -32,47 +32,49 @@ namespace LHCb::Pr::Velo { + enum struct CovXVector { x_x, x_tx, tx_tx }; + enum struct CovYVector { y_y, y_ty, ty_ty }; + struct Tag { - struct StateQoP : Event::float_field {}; struct nVPHits : Event::int_field {}; struct vp_indices : Event::ints_field<TracksInfo::MaxVPHits> {}; struct lhcbIDs : Event::ints_field<TracksInfo::MaxVPHits> {}; - struct StatePositions : Event::states_field<TracksInfo::NumVeloStates> {}; + struct States : Event::pos_dirs_field<TracksInfo::NumVeloStates> { + }; // technically these are not states, as there is no q/p field. struct StateCovXs : Event::floats_field<TracksInfo::NumVeloStates, TracksInfo::NumCovXY> {}; struct StateCovYs : Event::floats_field<TracksInfo::NumVeloStates, TracksInfo::NumCovXY> {}; template <typename T> - using velo_t = - Event::SOACollection<T, StateQoP, nVPHits, vp_indices, lhcbIDs, StatePositions, StateCovXs, StateCovYs>; + using velo_t = Event::SOACollection<T, nVPHits, vp_indices, lhcbIDs, States, StateCovXs, StateCovYs>; }; + namespace PD = LHCb::Event::PosDirParameters; + struct Tracks : Tag::velo_t<Tracks> { using base_t = typename Tag::velo_t<Tracks>; using base_t::base_t; - constexpr static auto NumStatePars = TracksInfo::NumStatePars; - constexpr static auto NumVeloStates = TracksInfo::NumVeloStates; - constexpr static auto NumVeloStatePars = NumStatePars * NumVeloStates; - constexpr static auto NumCovXY = TracksInfo::NumCovXY; - constexpr static auto NumVeloStateCov = TracksInfo::NumVeloStateCov; - constexpr static auto MaxVPHits = TracksInfo::MaxVPHits; + constexpr static auto NumVeloStates = TracksInfo::NumVeloStates; + constexpr static auto NumCovXY = TracksInfo::NumCovXY; + constexpr static auto NumVeloStateCov = TracksInfo::NumVeloStateCov; + constexpr static auto MaxVPHits = TracksInfo::MaxVPHits; template <typename F, typename M = std::true_type> void store_StatePosDir( int at, int state, Vec3<F> const& pos, Vec3<F> const& dir, M&& mask = {} ) { - store<Tag::StatePositions>( at, state, 0, pos.x, mask ); - store<Tag::StatePositions>( at, state, 1, pos.y, mask ); - store<Tag::StatePositions>( at, state, 2, pos.z, mask ); - store<Tag::StatePositions>( at, state, 3, dir.x, mask ); - store<Tag::StatePositions>( at, state, 4, dir.y, mask ); + store<Tag::States>( at, state, PD::PosDirVector::x, pos.x, mask ); + store<Tag::States>( at, state, PD::PosDirVector::y, pos.y, mask ); + store<Tag::States>( at, state, PD::PosDirVector::z, pos.z, mask ); + store<Tag::States>( at, state, PD::PosDirVector::tx, dir.x, mask ); + store<Tag::States>( at, state, PD::PosDirVector::ty, dir.y, mask ); } template <typename F, typename M = std::true_type> void store_StateCovXY( int at, int state, Vec3<F> const& covx, Vec3<F> const& covy, M&& mask = {} ) { - store<Tag::StateCovXs>( at, state, 0, covx.x, mask ); - store<Tag::StateCovXs>( at, state, 1, covx.y, mask ); - store<Tag::StateCovXs>( at, state, 2, covx.z, mask ); - store<Tag::StateCovYs>( at, state, 0, covy.x, mask ); - store<Tag::StateCovYs>( at, state, 1, covy.y, mask ); - store<Tag::StateCovYs>( at, state, 2, covy.z, mask ); + store<Tag::StateCovXs>( at, state, CovXVector::x_x, covx.x, mask ); + store<Tag::StateCovXs>( at, state, CovXVector::x_tx, covx.y, mask ); + store<Tag::StateCovXs>( at, state, CovXVector::tx_tx, covx.z, mask ); + store<Tag::StateCovYs>( at, state, CovYVector::y_y, covy.x, mask ); + store<Tag::StateCovYs>( at, state, CovYVector::y_ty, covy.y, mask ); + store<Tag::StateCovYs>( at, state, CovYVector::ty_ty, covy.z, mask ); } template <typename I, typename M = std::true_type> void store_vp_index( int at, int i, I const& vpidx, M&& mask = {} ) { @@ -87,8 +89,6 @@ namespace LHCb::Pr::Velo { template <SIMDWrapper::InstructionSet simd, ProxyBehaviour behaviour, typename ContainerType> struct VeloProxy : Event::Proxy<simd, behaviour, ContainerType> { using Event::Proxy<simd, behaviour, ContainerType>::Proxy; - [[nodiscard]] auto qOverP() const { return this->template get<Tag::StateQoP>(); } - [[nodiscard]] auto p() const { return abs( 1.0 / qOverP() ); } [[nodiscard]] auto nHits() const { return this->template get<Tag::nVPHits>(); } [[nodiscard]] auto nVPHits() const { return nHits(); } [[nodiscard]] auto vp_index( std::size_t i ) const { return this->template get<Tag::vp_indices>( i ); } @@ -133,34 +133,42 @@ namespace LHCb::Pr::Velo { return out; } [[nodiscard]] auto lhcbID( std::size_t i ) const { return loader<Tag::lhcbIDs>( i ); } - [[nodiscard]] auto StatePosElement( std::size_t i, std::size_t j ) const { - return loader<Tag::StatePositions>( i, j ); + [[nodiscard]] auto StatePosElement( std::size_t i, PD::PosDirVector j ) const { + return loader<Tag::States>( i, static_cast<std::size_t>( j ) ); } - [[nodiscard]] auto StateCovXElement( std::size_t i, std::size_t j ) const { - return loader<Tag::StateCovXs>( i, j ); + [[nodiscard]] auto StateCovXElement( std::size_t i, CovXVector j ) const { + return loader<Tag::StateCovXs>( i, static_cast<std::size_t>( j ) ); } - [[nodiscard]] auto StateCovYElement( std::size_t i, std::size_t j ) const { - return loader<Tag::StateCovYs>( i, j ); + [[nodiscard]] auto StateCovYElement( std::size_t i, CovYVector j ) const { + return loader<Tag::StateCovYs>( i, static_cast<std::size_t>( j ) ); } // Retrieve state info [[nodiscard]] auto StatePosDir( std::size_t i ) const { using Utils::unwind; - LinAlg::Vec<decltype( this->StatePosElement( 0, 0 ) ), TracksInfo::NumStatePars> out; - unwind<0, TracksInfo::NumStatePars>( [&]( auto j ) { out( j ) = this->StatePosElement( i, j ); } ); + LinAlg::Vec<decltype( this->StatePosElement( 0, PD::PosDirVector::x ) ), TracksInfo::NumPosDirPars> out; + // unwind<0, TracksInfo::NumVeloStatePars>( [&]( auto j ) { + out( 0 ) = this->StatePosElement( i, PD::PosDirVector::x ); + out( 1 ) = this->StatePosElement( i, PD::PosDirVector::y ); + out( 2 ) = this->StatePosElement( i, PD::PosDirVector::z ); + out( 3 ) = this->StatePosElement( i, PD::PosDirVector::tx ); + out( 4 ) = this->StatePosElement( i, PD::PosDirVector::ty ); return out; } [[nodiscard]] auto StatePos( std::size_t i ) const { - return Vec3<FType>( StatePosDir( i )( 0 ), StatePosDir( i )( 1 ), StatePosDir( i )( 2 ) ); + return Vec3<FType>( StatePosElement( i, PD::PosDirVector::x ), StatePosElement( i, PD::PosDirVector::y ), + StatePosElement( i, PD::PosDirVector::z ) ); } [[nodiscard]] auto StateDir( std::size_t i ) const { - return Vec3<FType>( StatePosDir( i )( 3 ), StatePosDir( i )( 4 ), 1.f ); + return Vec3<FType>( StatePosElement( i, PD::PosDirVector::tx ), StatePosElement( i, PD::PosDirVector::ty ), 1.f ); } [[nodiscard]] auto StateCovX( std::size_t i ) const { - return Vec3<FType>( StateCovXElement( i, 0 ), StateCovXElement( i, 1 ), StateCovXElement( i, 2 ) ); + return Vec3<FType>( StateCovXElement( i, CovXVector::x_x ), StateCovXElement( i, CovXVector::x_tx ), + StateCovXElement( i, CovXVector::tx_tx ) ); } [[nodiscard]] auto StateCovY( std::size_t i ) const { - return Vec3<FType>( StateCovYElement( i, 0 ), StateCovYElement( i, 1 ), StateCovYElement( i, 2 ) ); + return Vec3<FType>( StateCovYElement( i, CovYVector::y_y ), StateCovYElement( i, CovYVector::y_ty ), + StateCovYElement( i, CovYVector::ty_ty ) ); } auto pseudoRapidity() const { return StateDir( 0 ).eta(); } auto phi() const { return StateDir( 0 ).phi(); } diff --git a/Event/TrackEvent/include/Event/SOATrackConversion.h b/Event/TrackEvent/include/Event/SOATrackConversion.h index 3280162c44a339c450a91be1a34e8e30fc1cc23a..772f4ace505d6a4cbf6902f199d15cc7d774afc8 100644 --- a/Event/TrackEvent/include/Event/SOATrackConversion.h +++ b/Event/TrackEvent/include/Event/SOATrackConversion.h @@ -104,8 +104,9 @@ namespace LHCb::Event::conversion { auto state = Gaudi::Functional::details::deref( rstate ); // positions, slopes, q/p - outTrack.template field<v3::Tag::State>( L ).set( state.x(), state.y(), state.z(), state.tx(), state.ty() ); - outTrack.template field<v3::Tag::State_QoverP>( L ).set( state.qOverP() ); + outTrack.template field<v3::Tag::State>( L ).setPosition( state.x(), state.y(), state.z() ); + outTrack.template field<v3::Tag::State>( L ).setDirection( state.tx(), state.ty() ); + outTrack.template field<v3::Tag::State>( L ).setQOverP( state.qOverP() ); // covariance auto const& cov = state.covariance(); diff --git a/Event/TrackEvent/include/Event/Track_v3.h b/Event/TrackEvent/include/Event/Track_v3.h index b55d90c745363b4574db88316f8a6a01ea567191..048b1e3ffc0e37ee12c7ac90264ccaef97c94246 100644 --- a/Event/TrackEvent/include/Event/Track_v3.h +++ b/Event/TrackEvent/include/Event/Track_v3.h @@ -226,31 +226,8 @@ namespace LHCb::Event::v3 { // struct State : Event::states_field<MaxNumStates> {}; struct State_QoverP : Event::floats_field<MaxNumStates> {}; - - constexpr std::size_t x_index = 0; - constexpr std::size_t y_index = 1; - constexpr std::size_t z_index = 2; - constexpr std::size_t tx_index = 3; - constexpr std::size_t ty_index = 4; - struct StateCov : Event::state_covs_field<MaxNumStates> {}; - constexpr std::size_t x_x_index = 0; - constexpr std::size_t x_y_index = 1; - constexpr std::size_t x_tx_index = 2; - constexpr std::size_t x_ty_index = 3; - constexpr std::size_t x_QoP_index = 4; - constexpr std::size_t y_y_index = 5; - constexpr std::size_t y_tx_index = 6; - constexpr std::size_t y_ty_index = 7; - constexpr std::size_t y_QoP_index = 8; - constexpr std::size_t tx_tx_index = 9; - constexpr std::size_t tx_ty_index = 10; - constexpr std::size_t tx_QoP_index = 11; - constexpr std::size_t ty_ty_index = 12; - constexpr std::size_t ty_QoP_index = 13; - constexpr std::size_t QoP_QoP_index = 14; - template <typename T> using Track_t = Event::SOACollection<T, trackFT, Chi2, Chi2nDoF, UniqueID, LHCbIDs, numVPLHCbIDs, numUTLHCbIDs, numFTLHCbIDs, State, State_QoverP, StateCov>; @@ -369,7 +346,7 @@ namespace LHCb::Event::v3 { if ( !this->m_Tracks->has_state( StateLoc ) ) { throw std::invalid_argument( "State not defined for this track type." ); } - return loader<Tag::State_QoverP>( StateLoc ); + return loader<Tag::State>( StateLoc, StateParameters::StateVector::qOverP ); } [[nodiscard]] auto p( StateLocation StateLoc ) const { return abs( 1.0 / qOverP( StateLoc ) ); } [[nodiscard]] auto chi2() const { return loader<Tag::Chi2>(); } @@ -390,21 +367,21 @@ namespace LHCb::Event::v3 { // tX|____|____|____|____|____| // tY|____|____|____|____|____| // q/p|____|____|____|____|____| - cov( 0, 0 ) = loader<Tag::StateCov>( StateLoc, Tag::x_x_index ); // x error - cov( 0, 1 ) = loader<Tag::StateCov>( StateLoc, Tag::x_y_index ); // x-y covariance - cov( 0, 2 ) = loader<Tag::StateCov>( StateLoc, Tag::x_tx_index ); // x-tx covariance - cov( 0, 3 ) = loader<Tag::StateCov>( StateLoc, Tag::x_ty_index ); // x-ty covariance - cov( 0, 4 ) = loader<Tag::StateCov>( StateLoc, Tag::x_QoP_index ); // x-qop covariance - cov( 1, 1 ) = loader<Tag::StateCov>( StateLoc, Tag::y_y_index ); // y error - cov( 1, 2 ) = loader<Tag::StateCov>( StateLoc, Tag::y_tx_index ); // y-tx covariance - cov( 1, 3 ) = loader<Tag::StateCov>( StateLoc, Tag::y_ty_index ); // y-ty covariance - cov( 1, 4 ) = loader<Tag::StateCov>( StateLoc, Tag::y_QoP_index ); // y-qop covariance - cov( 2, 2 ) = loader<Tag::StateCov>( StateLoc, Tag::tx_tx_index ); // tx error - cov( 2, 3 ) = loader<Tag::StateCov>( StateLoc, Tag::tx_ty_index ); // tx-ty covariance - cov( 2, 4 ) = loader<Tag::StateCov>( StateLoc, Tag::tx_QoP_index ); // tx-qop covariance - cov( 3, 3 ) = loader<Tag::StateCov>( StateLoc, Tag::ty_ty_index ); // ty error - cov( 3, 4 ) = loader<Tag::StateCov>( StateLoc, Tag::ty_QoP_index ); // ty-qop covariance - cov( 4, 4 ) = loader<Tag::StateCov>( StateLoc, Tag::QoP_QoP_index ); // qop error + cov( 0, 0 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::x_x ); // x error + cov( 0, 1 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::x_y ); // x-y covariance + cov( 0, 2 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::x_tx ); // x-tx covariance + cov( 0, 3 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::x_ty ); // x-ty covariance + cov( 0, 4 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::x_qOverP ); // x-qop covariance + cov( 1, 1 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::y_y ); // y error + cov( 1, 2 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::y_tx ); // y-tx covariance + cov( 1, 3 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::y_ty ); // y-ty covariance + cov( 1, 4 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::y_qOverP ); // y-qop covariance + cov( 2, 2 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::tx_tx ); // tx error + cov( 2, 3 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::tx_ty ); // tx-ty covariance + cov( 2, 4 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::tx_qOverP ); // tx-qop covariance + cov( 3, 3 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::ty_ty ); // ty error + cov( 3, 4 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::ty_qOverP ); // ty-qop covariance + cov( 4, 4 ) = loader<Tag::StateCov>( StateLoc, StateParameters::CovMatrix::qOverP_qOverP ); // qop error return cov; } @@ -413,15 +390,16 @@ namespace LHCb::Event::v3 { if ( !this->m_Tracks->has_state( StateLoc ) ) { throw std::invalid_argument( "State not defined for this track type." ); } - return Vec3<FType>( loader<Tag::State>( StateLoc, Tag::x_index ), loader<Tag::State>( StateLoc, Tag::y_index ), - loader<Tag::State>( StateLoc, Tag::z_index ) ); + return Vec3<FType>( loader<Tag::State>( StateLoc, StateParameters::StateVector::x ), + loader<Tag::State>( StateLoc, StateParameters::StateVector::y ), + loader<Tag::State>( StateLoc, StateParameters::StateVector::z ) ); } auto direction( StateLocation StateLoc ) const { if ( !this->m_Tracks->has_state( StateLoc ) ) { throw std::invalid_argument( "State not defined for this track type." ); } - return Vec3<FType>( loader<Tag::State>( StateLoc, Tag::tx_index ), loader<Tag::State>( StateLoc, Tag::ty_index ), - 1.f ); + return Vec3<FType>( loader<Tag::State>( StateLoc, StateParameters::StateVector::tx ), + loader<Tag::State>( StateLoc, StateParameters::StateVector::ty ), 1.f ); } /** Return a proxy that exposes the a state-like API instead of the * track-like API of this struct. The use of `clone<Proxy>()` discards the @@ -437,8 +415,8 @@ namespace LHCb::Event::v3 { auto pt( StateLocation StateLoc ) const { auto const mom = p( StateLoc ); - auto const tx = loader<Tag::State>( StateLoc, Tag::tx_index ); - auto const ty = loader<Tag::State>( StateLoc, Tag::ty_index ); + auto const tx = loader<Tag::State>( StateLoc, StateParameters::StateVector::tx ); + auto const ty = loader<Tag::State>( StateLoc, StateParameters::StateVector::ty ); auto const tx2ty2 = tx * tx + ty * ty; auto const pt2 = mom * mom * tx2ty2 / ( tx2ty2 + 1 ); using std::sqrt; diff --git a/Event/TrackEvent/src/GeneratePrFittedForwardTracks.cpp b/Event/TrackEvent/src/GeneratePrFittedForwardTracks.cpp index 4e221dc92d1289593aa87ffb0fcf2730a0388761..ee2eafa78bd7065a9a68cc5299a99a58ef9c2e31 100644 --- a/Event/TrackEvent/src/GeneratePrFittedForwardTracks.cpp +++ b/Event/TrackEvent/src/GeneratePrFittedForwardTracks.cpp @@ -116,16 +116,16 @@ Tracks LHCb::Pr::Fitted::Forward::generate_tracks( std::size_t nTracks, LHCb::Un auto newTrack = tracks.emplace_back<SIMDWrapper::InstructionSet::Scalar>(); newTrack.field<Tag::trackSeed>().set( i ); - newTrack.field<Tag::StateQoP>().set( get_qoverp( gen_qoverp ) ); newTrack.field<Tag::Chi2>().set( chi2 / ndof ); newTrack.field<Tag::Chi2nDoF>().set( ndof ); newTrack.field<Tag::UniqueID>().set( decltype( newTrack.field<Tag::UniqueID>().get() ){unique_id_gen.generate<int>().value()} ); - auto state = newTrack.field<Tag::StatePosition>(); + auto state = newTrack.field<Tag::State>(); state.setPosition( x, y, z ); state.setDirection( tx, ty ); + state.setQOverP( get_qoverp( gen_qoverp ) ); newTrack.field<Tag::StateCovX>( 0 ).set( cov_x_x ); // x_err**2 newTrack.field<Tag::StateCovX>( 1 ).set( cov_x_tx ); // cov(x, tx) diff --git a/Event/TrackEvent/src/GenerateSOATracks.cpp b/Event/TrackEvent/src/GenerateSOATracks.cpp index 40d37bdcb342ff82a2afdbbe5405765adfb3e755..37bbe1b5614cdfe9f3a98164e8b3e33ad8950480 100644 --- a/Event/TrackEvent/src/GenerateSOATracks.cpp +++ b/Event/TrackEvent/src/GenerateSOATracks.cpp @@ -123,9 +123,9 @@ v3::Tracks LHCb::Event::v3::generate_tracks( std::size_t nTracks, LHCb::UniqueID newTrack.field<Tag::UniqueID>().set( decltype( newTrack.field<Tag::UniqueID>().get() ){unique_id_gen.generate<int>().value()} ); - newTrack.field<Tag::State>( Tracks::StateLocation::ClosestToBeam ).set( x, y, z, tx, ty ); - newTrack.field<Tag::State_QoverP>( Tracks::StateLocation::ClosestToBeam ).set( get_qoverp( gen_qoverp ) ); - + newTrack.field<Tag::State>( Tracks::StateLocation::ClosestToBeam ).setPosition( x, y, z ); + newTrack.field<Tag::State>( Tracks::StateLocation::ClosestToBeam ).setDirection( tx, ty ); + newTrack.field<Tag::State>( Tracks::StateLocation::ClosestToBeam ).setQOverP( get_qoverp( gen_qoverp ) ); newTrack.field<Tag::StateCov>( Tracks::StateLocation::ClosestToBeam ) .set( cov_x_x, 0, cov_x_tx, 0, cov_x_tx / 2.0, cov_x_x, 0, cov_x_tx, cov_x_tx / 2.0, cov_tx_tx, 0, 0, cov_tx_tx, 0, 0.6e-5f * get_qoverp( gen_qoverp ) ); diff --git a/UT/UTDAQ/include/UTDAQ/UTTrackUtils.h b/UT/UTDAQ/include/UTDAQ/UTTrackUtils.h index ff9b00331e736d06dcebcfe06a6e1b5360e72d65..8a54b2ec60c264aa54becec92ff52a85b7f0ec3e 100644 --- a/UT/UTDAQ/include/UTDAQ/UTTrackUtils.h +++ b/UT/UTDAQ/include/UTDAQ/UTTrackUtils.h @@ -20,12 +20,11 @@ namespace LHCb::UT::TrackUtils { // -- A "small" state for internal purposes namespace MiniStateTag { - struct StatePosition : Event::state_field {}; - struct StateQoP : Event::float_field {}; + struct State : Event::state_field {}; struct index : Event::int_field {}; template <typename T> - using ministate_t = Event::SOACollection<T, StateQoP, index, StatePosition>; + using ministate_t = Event::SOACollection<T, index, State>; } // namespace MiniStateTag struct MiniStates : MiniStateTag::ministate_t<MiniStates> {