From c6d19c7796cc24d42a44e85cfa930d53364d20db Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Fri, 6 Dec 2024 16:35:25 +0100 Subject: [PATCH 01/14] Changes for making MuonStandaloneRec to work with muon hits and clusters, clean MuonStandaloneTrack --- .../include/MuonInterfaces/MuonCluster.h | 9 + Muon/MuonTools/CMakeLists.txt | 1 + .../src/MuonHitContainerToCommonMuonHits.cpp | 51 ++++++ Tr/TrackTools/src/StandaloneMuonRec.cpp | 171 ++++++++++-------- Tr/TrackTools/src/StandaloneMuonTrack.h | 145 ++++++++------- 5 files changed, 238 insertions(+), 139 deletions(-) create mode 100644 Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp diff --git a/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h b/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h index 21df944cbab..b7c7a7ad1e3 100644 --- a/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h +++ b/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h @@ -97,8 +97,11 @@ public: int npads() const { return m_pads.size(); } int clsizeX() const { return m_xsize; } /// cluster size in X int clsizeY() const { return m_ysize; } /// cluster size in Y + double dx() const { return m_dx; } /// error on X position double dX() const { return m_dx; } /// error on X position + double dy() const { return m_dy; } /// error on Y position double dY() const { return m_dy; } /// error on Y position + double dz() const { return m_dz; } /// error on Z position double dZ() const { return m_dz; } /// error on Z position double minX() const { return m_hit_minx; } double maxX() const { return m_hit_maxx; } @@ -106,9 +109,13 @@ public: double maxY() const { return m_hit_maxy; } double minZ() const { return m_hit_minz; } double maxZ() const { return m_hit_maxz; } + double x() const { return m_position.X(); } double X() const { return m_position.X(); } + double y() const { return m_position.Y(); } double Y() const { return m_position.Y(); } + double z() const { return m_position.Z(); } double Z() const { return m_position.Z(); } + Gaudi::XYZVector pos() const { return m_position; } MuonCluster& SetXYZ( double x, double y, double z ) { m_position = { x, y, z }; @@ -151,3 +158,5 @@ using MuonClusters = std::vector<MuonCluster, LHCb::Allocators::EventLocal<MuonC typedef std::vector<const MuonCluster*> ConstMuonClusters; typedef const Gaudi::Range_<MuonClusters> MuonClusterRange; typedef const Gaudi::Range_<ConstMuonClusters> ConstMuonClusterRange; + + diff --git a/Muon/MuonTools/CMakeLists.txt b/Muon/MuonTools/CMakeLists.txt index 4b32be5ba62..856eec278b1 100644 --- a/Muon/MuonTools/CMakeLists.txt +++ b/Muon/MuonTools/CMakeLists.txt @@ -21,6 +21,7 @@ gaudi_add_module(MuonTools src/MuonPIDV2ToMuonTracks.cpp src/MergeMuonPIDs.cpp src/MergeMuonPIDsV1.cpp + src/MuonHitContainerToCommonMuonHits.cpp LINK Gaudi::GaudiAlgLib Gaudi::GaudiKernel diff --git a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp new file mode 100644 index 00000000000..cf17159f7c2 --- /dev/null +++ b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp @@ -0,0 +1,51 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\*****************************************************************************/ + +// Gaudi +#include "LHCbAlgs/Transformer.h" + +// LHCb +#include "MuonDAQ/CommonMuonHit.h" +#include "MuonDAQ/MuonHitContainer.h" +#include "Event/PrHits.h" + +namespace LHCb { + + /** + * Converter from MuonPIDs to MuonTracks so that alignment can work + * + * This has been developed as a work around after the replacement of MuonIDAlgLite by + * MuonIDHlt2Alg, as the former one was creating a list of MuonTracks while the later + * does not. + */ + + using CommonMuonHits = std::vector<CommonMuonHit, LHCb::Allocators::EventLocal<CommonMuonHit>>; + + class MuonHitContainerToCommonMuonHits : public Algorithm::Transformer<CommonMuonHits( const MuonHitContainer& )> { + + public: + MuonHitContainerToCommonMuonHits( const std::string& name, ISvcLocator* pSvcLocator ) + : Transformer( name, pSvcLocator, KeyValue{"Input", ""}, KeyValue{"Output", ""} ) {} + + CommonMuonHits operator()( const MuonHitContainer& hitContainer ) const override { + CommonMuonHits out; + out.reserve( hitContainer.hits( 0 ).size()*4 ); + for ( int s = 0 ; s < 4 ; ++s) { + auto hits = hitContainer.hits( s ); + for( auto hit : hits ) out.push_back( hit ); + } + return out; + } + }; + + DECLARE_COMPONENT_WITH_ID( MuonHitContainerToCommonMuonHits, "MuonHitContainerToCommonMuonHits" ) + +} // namespace LHCb diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index 7d40d979d5e..9ccf44fd9b8 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -29,6 +29,7 @@ #include "MuonDet/DeMuonDetector.h" #include "MuonDet/MuonNamespace.h" #include "vdt/vdtMath.h" +#include "MuonInterfaces/MuonCluster.h" #include "StandaloneMuonTrack.h" @@ -82,63 +83,70 @@ namespace { }; } // namespace -class StandaloneMuonRec : public LHCb::Algorithm::Transformer<LHCb::Tracks( const MuonHitContainer&, const Cache& ), +template<class MuonPosition> +class StandaloneMuonRec : public LHCb::Algorithm::Transformer<LHCb::Tracks( const std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>>&, const Cache& ), LHCb::Algorithm::Traits::usesConditions<Cache>> { public: - using base_class_t = LHCb::Algorithm::Transformer<LHCb::Tracks( const MuonHitContainer&, const Cache& ), + + typedef std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>> MuonPositionContainer; + typedef std::array<std::vector<MuonPosition>,4> PositionsInStations; + + using base_class_t = LHCb::Algorithm::Transformer<LHCb::Tracks( const MuonPositionContainer&, const Cache& ), LHCb::Algorithm::Traits::usesConditions<Cache>>; using base_class_t::addConditionDerivation; /// Standard constructor StandaloneMuonRec( const std::string& name, ISvcLocator* pSvcLocator ) : base_class_t( name, pSvcLocator, - { KeyValue{ "MuonHitsLocation", MuonHitContainerLocation::Default }, - KeyValue{ "ConditionsCache", "StandaloneMuonAlg-" + name + "-ConditionsCache" } }, - KeyValue{ "OutputMuonTracks", "Rec/Track/Muon" } ) {} + {typename base_class_t::KeyValue{"MuonHitsLocation", MuonHitContainerLocation::Default}, + typename base_class_t::KeyValue{"ConditionsCache", "StandaloneMuonAlg-" + name + "-ConditionsCache"}}, + typename base_class_t::KeyValue{"OutputMuonTracks", "Rec/Track/Muon"} ) {} StatusCode initialize() override { return base_class_t::initialize().andThen( [&] { - this->addConditionDerivation( { DeMuonLocation::Default, LHCb::Det::Magnet::det_path }, - this->inputLocation<Cache>(), - [&]( const DeMuonDetector& det, const DeMagnet& magnet ) { - Cache cache{ det }; - const Gaudi::XYZPoint begin( 0., 0., 0. ); - const Gaudi::XYZPoint end( 0., 0., cache.stationZ[M2] ); - m_bIntegrator->calculateBdlAndCenter( magnet.fieldGrid(), begin, end, 0.0001, 0., - cache.zCenter, cache.bdl ); - cache.fieldPolarity = magnet.isDown() ? -1 : 1; - debug() << "Integrated B field is " << cache.bdl.x() << " Tm" - << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" - << " with polarity " << cache.fieldPolarity << endmsg; - return cache; - } ); + this->template addConditionDerivation( {DeMuonLocation::Default, LHCb::Det::Magnet::det_path}, + this->template inputLocation<Cache>(), + [&]( const DeMuonDetector& det, const DeMagnet& magnet ) { + Cache cache{det}; + const Gaudi::XYZPoint begin( 0., 0., 0. ); + const Gaudi::XYZPoint end( 0., 0., cache.stationZ[M2] ); + m_bIntegrator->calculateBdlAndCenter( magnet.fieldGrid(), begin, end, 0.0001, 0., + cache.zCenter, cache.bdl ); + cache.fieldPolarity = magnet.isDown() ? -1 : 1; + this->template debug() << "Integrated B field is " << cache.bdl.x() << " Tm" + << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" + << " with polarity " << cache.fieldPolarity << endmsg; + return cache; + } ); } ); } - LHCb::Tracks operator()( const MuonHitContainer& hitContainer, const Cache& cache ) const override; + + LHCb::Tracks operator()( const MuonPositionContainer& hitContainer, const Cache& cache ) const override; ToolHandle<IBIntegrator> m_bIntegrator{ this, "BIntegrator", "BIntegrator" }; private: enum { M2 = 0, M3, M4, M5 }; - Gaudi::Property<bool> m_cloneKiller{ this, "CloneKiller", true }; - Gaudi::Property<bool> m_chi2Cut{ this, "Chi2Cut", false }; - Gaudi::Property<float> m_maxchi2Cut{ this, "MaxChi2Cut", 1.0 }; - Gaudi::Property<bool> m_strongCloneKiller{ this, "StrongCloneKiller", false }; - Gaudi::Property<bool> m_secondLoop{ this, "SecondLoop", false }; - Gaudi::Property<std::vector<float>> m_ParabolicCorrection{ this, "ParabolicCorrection", { 1.04, 0.14 } }; - Gaudi::Property<std::vector<float>> m_resParams{ this, "m_resParams", { 0.015, 0.29 } }; - Gaudi::Property<float> m_Constant{ this, "ConstantCorrection", 0., "In MeV" }; - - std::vector<StandaloneMuonTrack> muonSearch( const MuonHitContainer& hitContainer, const Cache& cache ) const; + Gaudi::Property<bool> m_cloneKiller{this, "CloneKiller", true}; + Gaudi::Property<bool> m_chi2Cut{this, "Chi2Cut", false}; + Gaudi::Property<float> m_maxchi2Cut{this, "MaxChi2Cut", 1.0}; + Gaudi::Property<bool> m_strongCloneKiller{this, "StrongCloneKiller", false}; + Gaudi::Property<bool> m_secondLoop{this, "SecondLoop", false}; + Gaudi::Property<std::vector<float>> m_ParabolicCorrection{this, "ParabolicCorrection", {1.04, 0.14}}; + Gaudi::Property<std::vector<float>> m_resParams{this, "m_resParams", {0.015, 0.29}}; + Gaudi::Property<float> m_Constant{this, "ConstantCorrection", 0., "In MeV"}; + Gaudi::Property<float> m_yAt0Error{this, "yAt0Error", 20.0, "Error on y constraint to point to 0/0/0"}; + + std::vector<StandaloneMuonTrack<MuonPosition>> muonSearch( const PositionsInStations& hitContainer, const Cache& cache ) const; bool findCoincidence( const float x, const float y, const unsigned int station, const unsigned int regionBefore, - const CommonMuonHitRange& hits, CommonMuonHit& hitcand ) const; - void findmuonTrack( const MuonHitContainer& hitContainer, const Cache& cache, - std::array<CommonMuonHit, 4>& bestCandidates, const int seed, - std::vector<StandaloneMuonTrack>& muonTracks ) const; - void recMomentum( StandaloneMuonTrack& muonTrack, const Cache& cache, LHCb::Track& track ) const; - void detectClone( std::vector<StandaloneMuonTrack>& muonTracks, const Cache& cache ) const; + const std::vector<MuonPosition>& hits, MuonPosition& hitcand ) const; + void findmuonTrack( const PositionsInStations& hitContainer, const Cache& cache, + std::array<MuonPosition, 4>& bestCandidates, const int seed, + std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks ) const; + void recMomentum( StandaloneMuonTrack<MuonPosition>& muonTrack, const Cache& cache, LHCb::Track& track ) const; + void detectClone( std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks, const Cache& cache ) const; // counters mutable Gaudi::Accumulators::Counter<> m_countEvents{ this, "nEvents" }; @@ -148,26 +156,34 @@ private: mutable Gaudi::Accumulators::MsgCounter<MSG::INFO> m_error_zeroBint{ this, "B integral is 0!!" }; }; -DECLARE_COMPONENT( StandaloneMuonRec ) +DECLARE_COMPONENT_WITH_ID( StandaloneMuonRec<CommonMuonHit>, "StandaloneMuonRec" ) +DECLARE_COMPONENT_WITH_ID( StandaloneMuonRec<MuonCluster>, "StandaloneMuonRecWithClusters" ) //============================================================================= // Main execution //============================================================================= -LHCb::Tracks StandaloneMuonRec::operator()( const MuonHitContainer& hitContainer, const Cache& cache ) const { +template<typename MuonPosition> +LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionContainer& hitContainer, const Cache& cache ) const { + + if ( this-> template msgLevel( MSG::DEBUG ) ) this-> template debug() << "==> Execute" << endmsg; - if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg; + PositionsInStations posInStations; + for( auto hit : hitContainer ){ + posInStations[hit.station()].push_back( hit ); + } LHCb::Tracks outputTracks; outputTracks.reserve( 1024 ); ++m_countEvents; - auto muonTracks = muonSearch( hitContainer, cache ); + auto muonTracks = muonSearch( posInStations, cache ); if ( m_cloneKiller ) { detectClone( muonTracks, cache ); } for ( auto& muTrack : muonTracks ) { if ( muTrack.isClone() ) continue; + muTrack.setYAt0Err( m_yAt0Error ); auto sc = muTrack.linearFit(); if ( !sc ) { ++m_failed_linearfit; @@ -181,15 +197,15 @@ LHCb::Tracks StandaloneMuonRec::operator()( const MuonHitContainer& hitContainer } m_countMuCandidates += outputTracks.size(); - if ( msgLevel( MSG::DEBUG ) ) debug() << " stored candidates " << outputTracks.size() << endmsg; + if ( this -> template msgLevel( MSG::DEBUG ) ) this-> template debug() << " stored candidates " << outputTracks.size() << endmsg; return outputTracks; } - -bool StandaloneMuonRec::findCoincidence( const float x, const float y, const unsigned int station, - const unsigned int regionBefore, const CommonMuonHitRange& hits, - CommonMuonHit& hitcand ) const { - +template<typename MuonPosition> +bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const float y, const unsigned int station, + const unsigned int regionBefore, const std::vector<MuonPosition>& hits, + MuonPosition& hitcand ) const { + const auto tol = m_tolForRegion[regionBefore]; float deltaYmin = 9999.; float deltaXmin = 9999.; @@ -209,9 +225,10 @@ bool StandaloneMuonRec::findCoincidence( const float x, const float y, const uns } return findCand; } -void StandaloneMuonRec::findmuonTrack( const MuonHitContainer& hitContainer, const Cache& cache, - std::array<CommonMuonHit, 4>& bestCandidates, const int seed, - std::vector<StandaloneMuonTrack>& muonTracks ) const { +template<typename MuonPosition> +void StandaloneMuonRec<MuonPosition>::findmuonTrack( const PositionsInStations& hitContainer, const Cache& cache, + std::array<MuonPosition, 4>& bestCandidates, const int seed, + std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks ) const { float xseed = bestCandidates[seed].x(); float yseed = bestCandidates[seed].y(); unsigned int hit_region = bestCandidates[seed].region(); @@ -220,7 +237,7 @@ void StandaloneMuonRec::findmuonTrack( const MuonHitContainer& hitContainer, con bool findAll = false; for ( int ista = seed - 1; ista > -1; ista-- ) { - auto findCandidate = findCoincidence( x, y, ista, hit_region, hitContainer.hits( ista ), bestCandidates[ista] ); + auto findCandidate = findCoincidence( x, y, ista, hit_region, hitContainer.at(ista), bestCandidates[ ista ] ); if ( !findCandidate && ( !m_secondLoop || ista < M4 ) ) break; if ( findCandidate && ista == M2 ) { findAll = true; @@ -243,34 +260,33 @@ void StandaloneMuonRec::findmuonTrack( const MuonHitContainer& hitContainer, con } if ( findAll ) { // create the muon track - StandaloneMuonTrack muon; - muon.setPoint( 0, bestCandidates[M2] ); - muon.setPoint( 1, bestCandidates[M3] ); + StandaloneMuonTrack<MuonPosition> muon; + muon.addPoint( bestCandidates[M2] ); + muon.addPoint( bestCandidates[M3] ); if ( m_secondLoop && bestCandidates[M4].station() == bestCandidates[M5].station() ) { - muon.setPoint( 2, bestCandidates[M4] ); - muon.setnHits( 3 ); + muon.addPoint( bestCandidates[M4] ); } else { - muon.setPoint( 2, bestCandidates[M4] ); - muon.setPoint( 3, bestCandidates[M5] ); - muon.setnHits( 4 ); + muon.addPoint( bestCandidates[M4] ); + muon.addPoint( bestCandidates[M5] ); } muonTracks.push_back( muon ); } } -std::vector<StandaloneMuonTrack> StandaloneMuonRec::muonSearch( const MuonHitContainer& hitContainer, - const Cache& cache ) const { - std::vector<StandaloneMuonTrack> muonTracks; +template<typename MuonPosition> +std::vector<StandaloneMuonTrack<MuonPosition>> StandaloneMuonRec<MuonPosition>::muonSearch( const PositionsInStations& hitContainer, + const Cache& cache ) const { + std::vector<StandaloneMuonTrack<MuonPosition>> muonTracks; muonTracks.reserve( 48 ); - const auto& hitsM5 = hitContainer.hits( M5 ); - std::array<CommonMuonHit, 4> bestCandidates; + const auto& hitsM5 = hitContainer.at(M5); + std::array<MuonPosition, 4> bestCandidates; for ( auto& hit : hitsM5 ) { bestCandidates[3] = hit; findmuonTrack( hitContainer, cache, bestCandidates, M5, muonTracks ); } ///---second loop from M4 if ( m_secondLoop ) { - const auto& hitsM4 = hitContainer.hits( M4 ); + const auto& hitsM4 = hitContainer[M4]; for ( auto& hit : hitsM4 ) { // To remove these hits of M4 used in the first round of search auto used = std::find_if( muonTracks.begin(), muonTracks.end(), @@ -285,7 +301,8 @@ std::vector<StandaloneMuonTrack> StandaloneMuonRec::muonSearch( const MuonHitCon } // estimate the momentum of muonTrack -void StandaloneMuonRec::recMomentum( StandaloneMuonTrack& track, const Cache& cache, LHCb::Track& lbtrack ) const { +template<typename MuonPosition> +void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosition>& track, const Cache& cache, LHCb::Track& lbtrack ) const { const float bdlX = cache.bdl.x(); const float fieldPolarity = cache.fieldPolarity; @@ -353,25 +370,37 @@ void StandaloneMuonRec::recMomentum( StandaloneMuonTrack& track, const Cache& ca state.setLocation( LHCb::State::Location::Muon ); endstate.setLocation( LHCb::State::Location::LastMeasurement ); - debug() << "Muon state = " << state << endmsg; + this-> template debug() << "Muon state = " << state << endmsg; lbtrack.clearStates(); lbtrack.addToStates( state ); lbtrack.addToStates( endstate ); lbtrack.setChi2PerDoF( track.chi2x() + track.chi2y() ); - lbtrack.setNDoF( track.nHits() - 2 ); + const int DoFForPointAtZero = m_yAt0Error < std::numeric_limits<float>::max(); + lbtrack.setNDoF( track.nHits() - 2 + DoFForPointAtZero ); // add one degree of freedom for the point at 0/0/0 for ( int i = 0; i < track.nHits(); i++ ) { - const auto Tile = track.point( i ).tile(); - lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( Tile ) ); - debug() << " Muon Hit " << i << " tile " << Tile << " tiles in station " << track.point( i ).station() << endmsg; + if constexpr(std::is_same_v<MuonPosition,CommonMuonHit>){ + const auto tile = track.point( i ).tile(); + lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); + this-> template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; + }else if constexpr( std::is_same_v<MuonPosition,MuonCluster>){ + const auto tiles = track.point(i).getPadTiles(); + for( const auto tile : tiles){ + lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); + this-> template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; + } + }else{ + this-> template error() << "Incompatible muon position class. Will not add LHCbIDs to the track" << endmsg; + } } lbtrack.setPatRecStatus( LHCb::Track::PatRecStatus::PatRecIDs ); lbtrack.setType( LHCb::Track::Types::Muon ); } -void StandaloneMuonRec::detectClone( std::vector<StandaloneMuonTrack>& muonTracks, const Cache& cache ) const { +template<typename MuonPosition> +void StandaloneMuonRec<MuonPosition>::detectClone( std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks, const Cache& cache ) const { for ( auto itMuonTrackFirst = muonTracks.begin(); itMuonTrackFirst < muonTracks.end(); itMuonTrackFirst++ ) { for ( auto itMuonTrackSecond = itMuonTrackFirst + 1; itMuonTrackSecond < muonTracks.end(); itMuonTrackSecond++ ) { diff --git a/Tr/TrackTools/src/StandaloneMuonTrack.h b/Tr/TrackTools/src/StandaloneMuonTrack.h index 77df068d551..e938075e8a9 100644 --- a/Tr/TrackTools/src/StandaloneMuonTrack.h +++ b/Tr/TrackTools/src/StandaloneMuonTrack.h @@ -17,6 +17,7 @@ #include "GaudiKernel/Vector3DTypes.h" #include <string> +#include <boost/container/small_vector.hpp> /** @class StandaloneMuonTrack StandaloneMuonTrack.h * @@ -29,18 +30,35 @@ * @date 2011-03-03 */ namespace { - void LinearFitXZ( bool XZ, std::array<CommonMuonHit, 4>& m_points, int nHits, float& slope, float& trunc, - float& chi2ndof, float& err_slope, float& err_trunc, float& cov ) { + + enum class FitMode { XZ, YZ }; + + struct FitResult{ + float slope = -1e6; + float trunc = -1e6; + float chi2ndof = -1e6; + float err_slope = -1e6; + float err_trunc = -1e6; + float cov = -1e6; + }; + + + + template<typename MuonPositionClass, FitMode fitMode> + FitResult linearFitImpl( boost::container::small_vector<MuonPositionClass, 4>& points, float yAt0Err = std::numeric_limits<float>::max()){ float sz2, sz, s0, sxz, sx, sx2; sz2 = sz = s0 = sxz = sx = sx2 = 0; - for ( int i = 0; i < nHits; i++ ) { - const auto hit = m_points[i]; - const auto z = hit.z(); - auto x = hit.x(); - auto xerr = 2. * hit.dx(); - if ( !XZ ) { - x = hit.y(); - xerr = 2 * hit.dy(); + + FitResult result; + + for ( const auto& point : points ) { + const auto z = point.z(); + auto x = point.x(); + auto xerr = 2. * point.dx(); + if ( fitMode == FitMode::YZ ) { + x = point.y(); + xerr = 2 * point.dy(); + } sz2 += z * z / xerr / xerr; sz += z / xerr / xerr; @@ -49,91 +67,82 @@ namespace { sx += x / xerr / xerr; sx2 += x * x / xerr / xerr; } - float xdet = sz2 * s0 - sz * sz; + + if( yAt0Err < std::numeric_limits<float>::max() ) s0 += 1.0 / ( yAt0Err*yAt0Err); // this applies a constraint to 0/0/0 + + const float xdet = sz2 * s0 - sz * sz; if ( !LHCb::essentiallyZero( xdet ) ) { - slope = ( sxz * s0 - sx * sz ) / xdet; - trunc = ( sx * sz2 - sxz * sz ) / xdet; + result.slope = ( sxz * s0 - sx * sz ) / xdet; + result.trunc = ( sx * sz2 - sxz * sz ) / xdet; - err_trunc = sqrt( sz2 / xdet ); - err_slope = sqrt( s0 / xdet ); - cov = -sz / xdet; + result.err_trunc = sqrt( sz2 / xdet ); + result.err_slope = sqrt( s0 / xdet ); + result.cov = -sz / xdet; - chi2ndof = ( sx2 + slope * slope * sz2 + trunc * trunc * s0 - 2. * slope * sxz - 2. * trunc * sx + - 2 * slope * trunc * sz ) / - ( nHits - 2 ); + result.chi2ndof = ( sx2 + result.slope * result.slope * sz2 + result.trunc * result.trunc * s0 - 2. * result.slope * sxz - 2. * result.trunc * sx + + 2 * result.slope * result.trunc * sz ) / + ( points.size() - 2 + (yAt0Err < std::numeric_limits<float>::max()) ); // add one degree of freedom if we add the "point" at 0/0/0 } + + return result; + } } // namespace +template<typename MuonPositionClass> class StandaloneMuonTrack final { public: /// Standard constructor - StandaloneMuonTrack() { m_clone = 0; }; + StandaloneMuonTrack() { m_clone = false; m_points.reserve(4); }; virtual ~StandaloneMuonTrack(){}; ///< Destructor - void setPoint( unsigned int station, CommonMuonHit point ) { m_points[station] = point; }; + void setPoint( unsigned int station, MuonPositionClass point ) { m_points[station] = point; }; + void addPoint( MuonPositionClass point ) { m_points.push_back(point); }; - CommonMuonHit point( unsigned int station ) const { return m_points[station]; }; + MuonPositionClass point( unsigned int station ) const { return m_points[station]; }; - void setClone() { m_clone = 1; }; - bool isClone() const { return m_clone > 0; } - - double slopeX( int stationFirst, int stationSecond, double zFirst, double zSecond ) const { - return ( m_points[stationFirst].x() - m_points[stationSecond].x() ) / ( zFirst - zSecond ); - }; - double slopeY( int stationFirst, int stationSecond, double zFirst, double zSecond ) const { - return ( m_points[stationFirst].y() - m_points[stationSecond].y() ) / ( zFirst - zSecond ); - }; + void setClone() { m_clone = true; }; + bool isClone() const { return m_clone; } + // -- used to constrain the straight line fit in y to 0/0/0 + void setYAt0Err(const float yAt0Err){ m_yAt0Err = yAt0Err; } + // Fit with a min chi^2 in the 2 projections xz and yz bool linearFit() { - double dof = nHits() - 2.; + const double dof = nHits() - 2.; if ( dof < 0 ) return false; - LinearFitXZ( true, m_points, nHits(), m_sx, m_bx, m_chi2x, m_errsx, m_errbx, m_covbsx ); - LinearFitXZ( false, m_points, nHits(), m_sy, m_by, m_chi2y, m_errsy, m_errby, m_covbsy ); - if ( m_chi2x > -1.f && m_chi2y > -1.f ) - return true; - else - return false; + m_resultXZ = linearFitImpl<MuonPositionClass, FitMode::XZ>( m_points ); + m_resultYZ = linearFitImpl<MuonPositionClass, FitMode::YZ>( m_points, m_yAt0Err ); + return m_resultXZ.chi2ndof > -1.f && m_resultYZ.chi2ndof > -1.f; }; - inline double chi2x() const { return m_chi2x; } /// chi2/dof XZ - inline double chi2y() const { return m_chi2y; } /// chi2/dof YZ + inline double chi2x() const { return m_resultXZ.chi2ndof; } /// chi2/dof XZ + inline double chi2y() const { return m_resultYZ.chi2ndof; } /// chi2/dof YZ // slope XZ - inline double sx() const { return m_sx; } + inline double sx() const { return m_resultXZ.slope; } // intercept XZ - inline double bx() const { return m_bx; } + inline double bx() const { return m_resultYZ.trunc; } // slope YZ - inline double sy() const { return m_sy; } + inline double sy() const { return m_resultXZ.slope; } // intercept YZ - inline double by() const { return m_by; } + inline double by() const { return m_resultYZ.trunc; } // errors on the above parameters - inline double errsx() const { return m_errsx; } - inline double errbx() const { return m_errbx; } - inline double covbsx() const { return m_covbsx; } - inline double errsy() const { return m_errsy; } - inline double errby() const { return m_errby; } - inline double covbsy() const { return m_covbsy; } + inline double errsx() const { return m_resultXZ.err_slope; } + inline double errbx() const { return m_resultXZ.err_trunc; } + inline double covbsx() const { return m_resultXZ.cov; } + inline double errsy() const { return m_resultYZ.err_slope; } + inline double errby() const { return m_resultYZ.err_trunc; } + inline double covbsy() const { return m_resultYZ.cov; } - inline void setnHits( int n ) { m_nHits = n; } - inline int nHits() const { return m_nHits; } + inline int nHits() const { return m_points.size(); } private: - std::array<CommonMuonHit, 4> m_points; - unsigned int m_clone; - unsigned int m_nHits; - - float m_chi2x = -1.f; - float m_chi2y = -1.f; - float m_sx = -1.f; - float m_bx = -1.f; - float m_sy = -1.f; - float m_by = -1.f; - float m_errsx = -1.f; - float m_errbx = -1.f; - float m_covbsx = -1.f; - float m_errsy = -1.f; - float m_errby = -1.f; - float m_covbsy = -1.f; + boost::container::small_vector<MuonPositionClass,4> m_points; + bool m_clone; + float m_yAt0Err = std::numeric_limits<float>::max(); + + FitResult m_resultXZ; + FitResult m_resultYZ; + }; -- GitLab From 341f19672b755eb8e6372d12032878a4dbd62d11 Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Sat, 7 Dec 2024 22:19:00 +0100 Subject: [PATCH 02/14] fix wrong return values for XZ and YZ fit --- Tr/TrackTools/src/StandaloneMuonTrack.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tr/TrackTools/src/StandaloneMuonTrack.h b/Tr/TrackTools/src/StandaloneMuonTrack.h index e938075e8a9..8cc1b07028b 100644 --- a/Tr/TrackTools/src/StandaloneMuonTrack.h +++ b/Tr/TrackTools/src/StandaloneMuonTrack.h @@ -121,9 +121,9 @@ public: // slope XZ inline double sx() const { return m_resultXZ.slope; } // intercept XZ - inline double bx() const { return m_resultYZ.trunc; } + inline double bx() const { return m_resultXZ.trunc; } // slope YZ - inline double sy() const { return m_resultXZ.slope; } + inline double sy() const { return m_resultYZ.slope; } // intercept YZ inline double by() const { return m_resultYZ.trunc; } -- GitLab From 3f649d9aaf84da0e4e870f4133332aa647aa7d48 Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Sun, 8 Dec 2024 20:35:25 +0100 Subject: [PATCH 03/14] replace harded 4 with constant for number of muon stations, reduce number of tracks to reserve --- Tr/TrackTools/src/StandaloneMuonRec.cpp | 22 +++++++++++----------- Tr/TrackTools/src/StandaloneMuonTrack.h | 5 +++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index 9ccf44fd9b8..465d43ec7eb 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -68,11 +68,11 @@ namespace { 60., 120., 240., 480. } }; // M4 // -- Set tolerances for hit search in region - constexpr std::array<float, 4> m_tolForRegion{ { 2.0, 4.0, 8.0, 10.0 } }; + constexpr std::array<float, LHCb::Detector::Muon::nRegions> m_tolForRegion{{2.0, 4.0, 8.0, 10.0}}; class Cache { public: - std::array<float, 4> stationZ{}; + std::array<float, LHCb::Detector::Muon::nStations> stationZ{}; Gaudi::XYZVector bdl; double zCenter{}; int fieldPolarity{}; @@ -90,7 +90,7 @@ class StandaloneMuonRec : public LHCb::Algorithm::Transformer<LHCb::Tracks( cons public: typedef std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>> MuonPositionContainer; - typedef std::array<std::vector<MuonPosition>,4> PositionsInStations; + typedef std::array<std::vector<MuonPosition>,LHCb::Detector::Muon::nStations> PositionsInStations; using base_class_t = LHCb::Algorithm::Transformer<LHCb::Tracks( const MuonPositionContainer&, const Cache& ), LHCb::Algorithm::Traits::usesConditions<Cache>>; @@ -137,13 +137,13 @@ private: Gaudi::Property<std::vector<float>> m_ParabolicCorrection{this, "ParabolicCorrection", {1.04, 0.14}}; Gaudi::Property<std::vector<float>> m_resParams{this, "m_resParams", {0.015, 0.29}}; Gaudi::Property<float> m_Constant{this, "ConstantCorrection", 0., "In MeV"}; - Gaudi::Property<float> m_yAt0Error{this, "yAt0Error", 20.0, "Error on y constraint to point to 0/0/0"}; + Gaudi::Property<float> m_yAt0Error{this, "yAt0Error", std::numeric_limits<float>::max(), "Error on y constraint to point to 0/0/0"}; std::vector<StandaloneMuonTrack<MuonPosition>> muonSearch( const PositionsInStations& hitContainer, const Cache& cache ) const; bool findCoincidence( const float x, const float y, const unsigned int station, const unsigned int regionBefore, const std::vector<MuonPosition>& hits, MuonPosition& hitcand ) const; void findmuonTrack( const PositionsInStations& hitContainer, const Cache& cache, - std::array<MuonPosition, 4>& bestCandidates, const int seed, + std::array<MuonPosition, LHCb::Detector::Muon::nStations>& bestCandidates, const int seed, std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks ) const; void recMomentum( StandaloneMuonTrack<MuonPosition>& muonTrack, const Cache& cache, LHCb::Track& track ) const; void detectClone( std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks, const Cache& cache ) const; @@ -173,7 +173,7 @@ LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionCont } LHCb::Tracks outputTracks; - outputTracks.reserve( 1024 ); + outputTracks.reserve( 10 ); ++m_countEvents; @@ -214,7 +214,7 @@ bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const floa float deltaX = fabs( x - hit.x() ); float deltaY = fabs( y - hit.y() ); //-- Check if the hit is within the FOI (copy from MuonCombRec); in any case a xFOI >1000 is not considered - if ( deltaX < m_Xmax[station * 4 + regionBefore] && deltaY < m_Ymax[station * 4 + regionBefore] && + if ( deltaX < m_Xmax[station * LHCb::Detector::Muon::nStations + regionBefore] && deltaY < m_Ymax[station * LHCb::Detector::Muon::nStations + regionBefore] && ( deltaY < deltaYmin - tol || ( deltaY < deltaYmin + tol && ( deltaX < deltaXmin - tol || fabs( deltaXmin - deltaX ) < 0.1 ) ) ) ) { deltaXmin = deltaX; @@ -227,7 +227,7 @@ bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const floa } template<typename MuonPosition> void StandaloneMuonRec<MuonPosition>::findmuonTrack( const PositionsInStations& hitContainer, const Cache& cache, - std::array<MuonPosition, 4>& bestCandidates, const int seed, + std::array<MuonPosition, LHCb::Detector::Muon::nStations>& bestCandidates, const int seed, std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks ) const { float xseed = bestCandidates[seed].x(); float yseed = bestCandidates[seed].y(); @@ -276,10 +276,10 @@ template<typename MuonPosition> std::vector<StandaloneMuonTrack<MuonPosition>> StandaloneMuonRec<MuonPosition>::muonSearch( const PositionsInStations& hitContainer, const Cache& cache ) const { std::vector<StandaloneMuonTrack<MuonPosition>> muonTracks; - muonTracks.reserve( 48 ); + muonTracks.reserve( 12 ); const auto& hitsM5 = hitContainer.at(M5); - std::array<MuonPosition, 4> bestCandidates; + std::array<MuonPosition, LHCb::Detector::Muon::nStations> bestCandidates; for ( auto& hit : hitsM5 ) { bestCandidates[3] = hit; findmuonTrack( hitContainer, cache, bestCandidates, M5, muonTracks ); @@ -371,7 +371,7 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit endstate.setLocation( LHCb::State::Location::LastMeasurement ); this-> template debug() << "Muon state = " << state << endmsg; - + lbtrack.clearStates(); lbtrack.addToStates( state ); lbtrack.addToStates( endstate ); diff --git a/Tr/TrackTools/src/StandaloneMuonTrack.h b/Tr/TrackTools/src/StandaloneMuonTrack.h index 8cc1b07028b..0f86109c532 100644 --- a/Tr/TrackTools/src/StandaloneMuonTrack.h +++ b/Tr/TrackTools/src/StandaloneMuonTrack.h @@ -13,6 +13,7 @@ #include "Core/FloatComparison.h" #include "MuonDAQ/CommonMuonHit.h" +#include "Detector/Muon/MuonConstants.h" #include "GaudiKernel/Point3DTypes.h" #include "GaudiKernel/Vector3DTypes.h" @@ -45,7 +46,7 @@ namespace { template<typename MuonPositionClass, FitMode fitMode> - FitResult linearFitImpl( boost::container::small_vector<MuonPositionClass, 4>& points, float yAt0Err = std::numeric_limits<float>::max()){ + FitResult linearFitImpl( boost::container::small_vector<MuonPositionClass, LHCb::Detector::Muon::nStations>& points, float yAt0Err = std::numeric_limits<float>::max()){ float sz2, sz, s0, sxz, sx, sx2; sz2 = sz = s0 = sxz = sx = sx2 = 0; @@ -138,7 +139,7 @@ public: inline int nHits() const { return m_points.size(); } private: - boost::container::small_vector<MuonPositionClass,4> m_points; + boost::container::small_vector<MuonPositionClass,LHCb::Detector::Muon::nStations> m_points; bool m_clone; float m_yAt0Err = std::numeric_limits<float>::max(); -- GitLab From 21f009039041adcdd51a5da53a02fdf50827969f Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Sun, 8 Dec 2024 20:37:25 +0100 Subject: [PATCH 04/14] fix (old) bug where position for last state was wrongly calculated --- Tr/TrackTools/src/StandaloneMuonRec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index 465d43ec7eb..4b4fdad71e8 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -313,7 +313,7 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit LHCb::State state( LHCb::StateVector( trackPos, Gaudi::XYZVector( track.sx(), track.sy(), 1.0 ), 1. / 10000. ) ); const auto Zend = cache.stationZ[M5]; - Gaudi::XYZPoint endtrackPos( track.bx() + track.sx() * Zfirst, track.by() + track.sy() * Zend, Zend ); + Gaudi::XYZPoint endtrackPos( track.bx() + track.sx() * Zend, track.by() + track.sy() * Zend, Zend ); LHCb::State endstate( LHCb::StateVector( endtrackPos, Gaudi::XYZVector( track.sx(), track.sy(), 1.0 ), 1. / 10000. ) ); -- GitLab From 89545b8b21b5f191db3aaa24f5b262cb9e77f33a Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Wed, 12 Feb 2025 17:05:57 +0100 Subject: [PATCH 05/14] replace more hardcoded 4s with meaningful expression --- Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp index cf17159f7c2..b7240bb3bd7 100644 --- a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp +++ b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp @@ -37,8 +37,8 @@ namespace LHCb { CommonMuonHits operator()( const MuonHitContainer& hitContainer ) const override { CommonMuonHits out; - out.reserve( hitContainer.hits( 0 ).size()*4 ); - for ( int s = 0 ; s < 4 ; ++s) { + out.reserve( hitContainer.hits( 0 ).size()*LHCb::Detector::Muon::nStations ); + for ( int s = 0 ; s < LHCb::Detector::Muon::nStations ; ++s) { auto hits = hitContainer.hits( s ); for( auto hit : hits ) out.push_back( hit ); } -- GitLab From ffc07d41a748f5eec2c108cb3e3e9b004577cb04 Mon Sep 17 00:00:00 2001 From: Gitlab CI <noreply@cern.ch> Date: Wed, 12 Feb 2025 16:06:41 +0000 Subject: [PATCH 06/14] pre-commit fixes patch generated by https://gitlab.cern.ch/lhcb/Rec/-/jobs/50886445 --- .../include/MuonInterfaces/MuonCluster.h | 44 +++-- .../src/MuonHitContainerToCommonMuonHits.cpp | 12 +- Tr/TrackTools/src/StandaloneMuonRec.cpp | 164 ++++++++++-------- Tr/TrackTools/src/StandaloneMuonTrack.h | 64 +++---- 4 files changed, 147 insertions(+), 137 deletions(-) diff --git a/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h b/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h index b7c7a7ad1e3..d25b8171331 100644 --- a/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h +++ b/Muon/MuonInterfaces/include/MuonInterfaces/MuonCluster.h @@ -94,27 +94,27 @@ public: /// return the MuonTileIDs of the logical pads used for this cluster std::vector<LHCb::Detector::Muon::TileID> getPadTiles() const; /// number of logical pads in this hit - int npads() const { return m_pads.size(); } - int clsizeX() const { return m_xsize; } /// cluster size in X - int clsizeY() const { return m_ysize; } /// cluster size in Y - double dx() const { return m_dx; } /// error on X position - double dX() const { return m_dx; } /// error on X position - double dy() const { return m_dy; } /// error on Y position - double dY() const { return m_dy; } /// error on Y position - double dz() const { return m_dz; } /// error on Z position - double dZ() const { return m_dz; } /// error on Z position - double minX() const { return m_hit_minx; } - double maxX() const { return m_hit_maxx; } - double minY() const { return m_hit_miny; } - double maxY() const { return m_hit_maxy; } - double minZ() const { return m_hit_minz; } - double maxZ() const { return m_hit_maxz; } - double x() const { return m_position.X(); } - double X() const { return m_position.X(); } - double y() const { return m_position.Y(); } - double Y() const { return m_position.Y(); } - double z() const { return m_position.Z(); } - double Z() const { return m_position.Z(); } + int npads() const { return m_pads.size(); } + int clsizeX() const { return m_xsize; } /// cluster size in X + int clsizeY() const { return m_ysize; } /// cluster size in Y + double dx() const { return m_dx; } /// error on X position + double dX() const { return m_dx; } /// error on X position + double dy() const { return m_dy; } /// error on Y position + double dY() const { return m_dy; } /// error on Y position + double dz() const { return m_dz; } /// error on Z position + double dZ() const { return m_dz; } /// error on Z position + double minX() const { return m_hit_minx; } + double maxX() const { return m_hit_maxx; } + double minY() const { return m_hit_miny; } + double maxY() const { return m_hit_maxy; } + double minZ() const { return m_hit_minz; } + double maxZ() const { return m_hit_maxz; } + double x() const { return m_position.X(); } + double X() const { return m_position.X(); } + double y() const { return m_position.Y(); } + double Y() const { return m_position.Y(); } + double z() const { return m_position.Z(); } + double Z() const { return m_position.Z(); } Gaudi::XYZVector pos() const { return m_position; } MuonCluster& SetXYZ( double x, double y, double z ) { @@ -158,5 +158,3 @@ using MuonClusters = std::vector<MuonCluster, LHCb::Allocators::EventLocal<MuonC typedef std::vector<const MuonCluster*> ConstMuonClusters; typedef const Gaudi::Range_<MuonClusters> MuonClusterRange; typedef const Gaudi::Range_<ConstMuonClusters> ConstMuonClusterRange; - - diff --git a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp index b7240bb3bd7..86ce8741ab3 100644 --- a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp +++ b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp @@ -13,9 +13,9 @@ #include "LHCbAlgs/Transformer.h" // LHCb +#include "Event/PrHits.h" #include "MuonDAQ/CommonMuonHit.h" #include "MuonDAQ/MuonHitContainer.h" -#include "Event/PrHits.h" namespace LHCb { @@ -33,14 +33,14 @@ namespace LHCb { public: MuonHitContainerToCommonMuonHits( const std::string& name, ISvcLocator* pSvcLocator ) - : Transformer( name, pSvcLocator, KeyValue{"Input", ""}, KeyValue{"Output", ""} ) {} + : Transformer( name, pSvcLocator, KeyValue{ "Input", "" }, KeyValue{ "Output", "" } ) {} CommonMuonHits operator()( const MuonHitContainer& hitContainer ) const override { CommonMuonHits out; - out.reserve( hitContainer.hits( 0 ).size()*LHCb::Detector::Muon::nStations ); - for ( int s = 0 ; s < LHCb::Detector::Muon::nStations ; ++s) { - auto hits = hitContainer.hits( s ); - for( auto hit : hits ) out.push_back( hit ); + out.reserve( hitContainer.hits( 0 ).size() * LHCb::Detector::Muon::nStations ); + for ( int s = 0; s < LHCb::Detector::Muon::nStations; ++s ) { + auto hits = hitContainer.hits( s ); + for ( auto hit : hits ) out.push_back( hit ); } return out; } diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index 4b4fdad71e8..392cab03d60 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -28,8 +28,8 @@ #include "Magnet/DeMagnet.h" #include "MuonDet/DeMuonDetector.h" #include "MuonDet/MuonNamespace.h" -#include "vdt/vdtMath.h" #include "MuonInterfaces/MuonCluster.h" +#include "vdt/vdtMath.h" #include "StandaloneMuonTrack.h" @@ -68,14 +68,14 @@ namespace { 60., 120., 240., 480. } }; // M4 // -- Set tolerances for hit search in region - constexpr std::array<float, LHCb::Detector::Muon::nRegions> m_tolForRegion{{2.0, 4.0, 8.0, 10.0}}; + constexpr std::array<float, LHCb::Detector::Muon::nRegions> m_tolForRegion{ { 2.0, 4.0, 8.0, 10.0 } }; class Cache { public: std::array<float, LHCb::Detector::Muon::nStations> stationZ{}; - Gaudi::XYZVector bdl; - double zCenter{}; - int fieldPolarity{}; + Gaudi::XYZVector bdl; + double zCenter{}; + int fieldPolarity{}; Cache(){}; Cache( DeMuonDetector const& det ) { for ( int s = 0; s != det.stations(); ++s ) { stationZ[s] = det.getStationZ( s ); } @@ -83,63 +83,66 @@ namespace { }; } // namespace -template<class MuonPosition> -class StandaloneMuonRec : public LHCb::Algorithm::Transformer<LHCb::Tracks( const std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>>&, const Cache& ), - LHCb::Algorithm::Traits::usesConditions<Cache>> { +template <class MuonPosition> +class StandaloneMuonRec + : public LHCb::Algorithm::Transformer< + LHCb::Tracks( const std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>>&, const Cache& ), + LHCb::Algorithm::Traits::usesConditions<Cache>> { public: + typedef std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>> MuonPositionContainer; + typedef std::array<std::vector<MuonPosition>, LHCb::Detector::Muon::nStations> PositionsInStations; - typedef std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>> MuonPositionContainer; - typedef std::array<std::vector<MuonPosition>,LHCb::Detector::Muon::nStations> PositionsInStations; - using base_class_t = LHCb::Algorithm::Transformer<LHCb::Tracks( const MuonPositionContainer&, const Cache& ), LHCb::Algorithm::Traits::usesConditions<Cache>>; using base_class_t::addConditionDerivation; /// Standard constructor StandaloneMuonRec( const std::string& name, ISvcLocator* pSvcLocator ) - : base_class_t( name, pSvcLocator, - {typename base_class_t::KeyValue{"MuonHitsLocation", MuonHitContainerLocation::Default}, - typename base_class_t::KeyValue{"ConditionsCache", "StandaloneMuonAlg-" + name + "-ConditionsCache"}}, - typename base_class_t::KeyValue{"OutputMuonTracks", "Rec/Track/Muon"} ) {} + : base_class_t( + name, pSvcLocator, + { typename base_class_t::KeyValue{ "MuonHitsLocation", MuonHitContainerLocation::Default }, + typename base_class_t::KeyValue{ "ConditionsCache", "StandaloneMuonAlg-" + name + "-ConditionsCache" } }, + typename base_class_t::KeyValue{ "OutputMuonTracks", "Rec/Track/Muon" } ) {} StatusCode initialize() override { return base_class_t::initialize().andThen( [&] { - this->template addConditionDerivation( {DeMuonLocation::Default, LHCb::Det::Magnet::det_path}, - this->template inputLocation<Cache>(), - [&]( const DeMuonDetector& det, const DeMagnet& magnet ) { - Cache cache{det}; - const Gaudi::XYZPoint begin( 0., 0., 0. ); - const Gaudi::XYZPoint end( 0., 0., cache.stationZ[M2] ); - m_bIntegrator->calculateBdlAndCenter( magnet.fieldGrid(), begin, end, 0.0001, 0., - cache.zCenter, cache.bdl ); - cache.fieldPolarity = magnet.isDown() ? -1 : 1; - this->template debug() << "Integrated B field is " << cache.bdl.x() << " Tm" - << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" - << " with polarity " << cache.fieldPolarity << endmsg; - return cache; - } ); + this->template addConditionDerivation( + { DeMuonLocation::Default, LHCb::Det::Magnet::det_path }, this->template inputLocation<Cache>(), + [&]( const DeMuonDetector& det, const DeMagnet& magnet ) { + Cache cache{ det }; + const Gaudi::XYZPoint begin( 0., 0., 0. ); + const Gaudi::XYZPoint end( 0., 0., cache.stationZ[M2] ); + m_bIntegrator->calculateBdlAndCenter( magnet.fieldGrid(), begin, end, 0.0001, 0., cache.zCenter, + cache.bdl ); + cache.fieldPolarity = magnet.isDown() ? -1 : 1; + this->template debug() << "Integrated B field is " << cache.bdl.x() << " Tm" + << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" + << " with polarity " << cache.fieldPolarity << endmsg; + return cache; + } ); } ); } - LHCb::Tracks operator()( const MuonPositionContainer& hitContainer, const Cache& cache ) const override; ToolHandle<IBIntegrator> m_bIntegrator{ this, "BIntegrator", "BIntegrator" }; private: enum { M2 = 0, M3, M4, M5 }; - Gaudi::Property<bool> m_cloneKiller{this, "CloneKiller", true}; - Gaudi::Property<bool> m_chi2Cut{this, "Chi2Cut", false}; - Gaudi::Property<float> m_maxchi2Cut{this, "MaxChi2Cut", 1.0}; - Gaudi::Property<bool> m_strongCloneKiller{this, "StrongCloneKiller", false}; - Gaudi::Property<bool> m_secondLoop{this, "SecondLoop", false}; - Gaudi::Property<std::vector<float>> m_ParabolicCorrection{this, "ParabolicCorrection", {1.04, 0.14}}; - Gaudi::Property<std::vector<float>> m_resParams{this, "m_resParams", {0.015, 0.29}}; - Gaudi::Property<float> m_Constant{this, "ConstantCorrection", 0., "In MeV"}; - Gaudi::Property<float> m_yAt0Error{this, "yAt0Error", std::numeric_limits<float>::max(), "Error on y constraint to point to 0/0/0"}; - - std::vector<StandaloneMuonTrack<MuonPosition>> muonSearch( const PositionsInStations& hitContainer, const Cache& cache ) const; + Gaudi::Property<bool> m_cloneKiller{ this, "CloneKiller", true }; + Gaudi::Property<bool> m_chi2Cut{ this, "Chi2Cut", false }; + Gaudi::Property<float> m_maxchi2Cut{ this, "MaxChi2Cut", 1.0 }; + Gaudi::Property<bool> m_strongCloneKiller{ this, "StrongCloneKiller", false }; + Gaudi::Property<bool> m_secondLoop{ this, "SecondLoop", false }; + Gaudi::Property<std::vector<float>> m_ParabolicCorrection{ this, "ParabolicCorrection", { 1.04, 0.14 } }; + Gaudi::Property<std::vector<float>> m_resParams{ this, "m_resParams", { 0.015, 0.29 } }; + Gaudi::Property<float> m_Constant{ this, "ConstantCorrection", 0., "In MeV" }; + Gaudi::Property<float> m_yAt0Error{ this, "yAt0Error", std::numeric_limits<float>::max(), + "Error on y constraint to point to 0/0/0" }; + + std::vector<StandaloneMuonTrack<MuonPosition>> muonSearch( const PositionsInStations& hitContainer, + const Cache& cache ) const; bool findCoincidence( const float x, const float y, const unsigned int station, const unsigned int regionBefore, const std::vector<MuonPosition>& hits, MuonPosition& hitcand ) const; void findmuonTrack( const PositionsInStations& hitContainer, const Cache& cache, @@ -162,15 +165,14 @@ DECLARE_COMPONENT_WITH_ID( StandaloneMuonRec<MuonCluster>, "StandaloneMuonRecWit //============================================================================= // Main execution //============================================================================= -template<typename MuonPosition> -LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionContainer& hitContainer, const Cache& cache ) const { +template <typename MuonPosition> +LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionContainer& hitContainer, + const Cache& cache ) const { - if ( this-> template msgLevel( MSG::DEBUG ) ) this-> template debug() << "==> Execute" << endmsg; + if ( this->template msgLevel( MSG::DEBUG ) ) this->template debug() << "==> Execute" << endmsg; PositionsInStations posInStations; - for( auto hit : hitContainer ){ - posInStations[hit.station()].push_back( hit ); - } + for ( auto hit : hitContainer ) { posInStations[hit.station()].push_back( hit ); } LHCb::Tracks outputTracks; outputTracks.reserve( 10 ); @@ -197,15 +199,17 @@ LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionCont } m_countMuCandidates += outputTracks.size(); - if ( this -> template msgLevel( MSG::DEBUG ) ) this-> template debug() << " stored candidates " << outputTracks.size() << endmsg; + if ( this->template msgLevel( MSG::DEBUG ) ) + this->template debug() << " stored candidates " << outputTracks.size() << endmsg; return outputTracks; } -template<typename MuonPosition> +template <typename MuonPosition> bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const float y, const unsigned int station, - const unsigned int regionBefore, const std::vector<MuonPosition>& hits, - MuonPosition& hitcand ) const { - + const unsigned int regionBefore, + const std::vector<MuonPosition>& hits, + MuonPosition& hitcand ) const { + const auto tol = m_tolForRegion[regionBefore]; float deltaYmin = 9999.; float deltaXmin = 9999.; @@ -214,7 +218,8 @@ bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const floa float deltaX = fabs( x - hit.x() ); float deltaY = fabs( y - hit.y() ); //-- Check if the hit is within the FOI (copy from MuonCombRec); in any case a xFOI >1000 is not considered - if ( deltaX < m_Xmax[station * LHCb::Detector::Muon::nStations + regionBefore] && deltaY < m_Ymax[station * LHCb::Detector::Muon::nStations + regionBefore] && + if ( deltaX < m_Xmax[station * LHCb::Detector::Muon::nStations + regionBefore] && + deltaY < m_Ymax[station * LHCb::Detector::Muon::nStations + regionBefore] && ( deltaY < deltaYmin - tol || ( deltaY < deltaYmin + tol && ( deltaX < deltaXmin - tol || fabs( deltaXmin - deltaX ) < 0.1 ) ) ) ) { deltaXmin = deltaX; @@ -225,10 +230,11 @@ bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const floa } return findCand; } -template<typename MuonPosition> -void StandaloneMuonRec<MuonPosition>::findmuonTrack( const PositionsInStations& hitContainer, const Cache& cache, - std::array<MuonPosition, LHCb::Detector::Muon::nStations>& bestCandidates, const int seed, - std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks ) const { +template <typename MuonPosition> +void StandaloneMuonRec<MuonPosition>::findmuonTrack( + const PositionsInStations& hitContainer, const Cache& cache, + std::array<MuonPosition, LHCb::Detector::Muon::nStations>& bestCandidates, const int seed, + std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks ) const { float xseed = bestCandidates[seed].x(); float yseed = bestCandidates[seed].y(); unsigned int hit_region = bestCandidates[seed].region(); @@ -237,7 +243,7 @@ void StandaloneMuonRec<MuonPosition>::findmuonTrack( const PositionsInStations& bool findAll = false; for ( int ista = seed - 1; ista > -1; ista-- ) { - auto findCandidate = findCoincidence( x, y, ista, hit_region, hitContainer.at(ista), bestCandidates[ ista ] ); + auto findCandidate = findCoincidence( x, y, ista, hit_region, hitContainer.at( ista ), bestCandidates[ista] ); if ( !findCandidate && ( !m_secondLoop || ista < M4 ) ) break; if ( findCandidate && ista == M2 ) { findAll = true; @@ -272,13 +278,13 @@ void StandaloneMuonRec<MuonPosition>::findmuonTrack( const PositionsInStations& muonTracks.push_back( muon ); } } -template<typename MuonPosition> -std::vector<StandaloneMuonTrack<MuonPosition>> StandaloneMuonRec<MuonPosition>::muonSearch( const PositionsInStations& hitContainer, - const Cache& cache ) const { +template <typename MuonPosition> +std::vector<StandaloneMuonTrack<MuonPosition>> +StandaloneMuonRec<MuonPosition>::muonSearch( const PositionsInStations& hitContainer, const Cache& cache ) const { std::vector<StandaloneMuonTrack<MuonPosition>> muonTracks; muonTracks.reserve( 12 ); - const auto& hitsM5 = hitContainer.at(M5); + const auto& hitsM5 = hitContainer.at( M5 ); std::array<MuonPosition, LHCb::Detector::Muon::nStations> bestCandidates; for ( auto& hit : hitsM5 ) { bestCandidates[3] = hit; @@ -301,8 +307,9 @@ std::vector<StandaloneMuonTrack<MuonPosition>> StandaloneMuonRec<MuonPosition>:: } // estimate the momentum of muonTrack -template<typename MuonPosition> -void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosition>& track, const Cache& cache, LHCb::Track& lbtrack ) const { +template <typename MuonPosition> +void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosition>& track, const Cache& cache, + LHCb::Track& lbtrack ) const { const float bdlX = cache.bdl.x(); const float fieldPolarity = cache.fieldPolarity; @@ -370,8 +377,8 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit state.setLocation( LHCb::State::Location::Muon ); endstate.setLocation( LHCb::State::Location::LastMeasurement ); - this-> template debug() << "Muon state = " << state << endmsg; - + this->template debug() << "Muon state = " << state << endmsg; + lbtrack.clearStates(); lbtrack.addToStates( state ); lbtrack.addToStates( endstate ); @@ -380,18 +387,20 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit lbtrack.setNDoF( track.nHits() - 2 + DoFForPointAtZero ); // add one degree of freedom for the point at 0/0/0 for ( int i = 0; i < track.nHits(); i++ ) { - if constexpr(std::is_same_v<MuonPosition,CommonMuonHit>){ + if constexpr ( std::is_same_v<MuonPosition, CommonMuonHit> ) { const auto tile = track.point( i ).tile(); lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); - this-> template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; - }else if constexpr( std::is_same_v<MuonPosition,MuonCluster>){ - const auto tiles = track.point(i).getPadTiles(); - for( const auto tile : tiles){ - lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); - this-> template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; + this->template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " + << track.point( i ).station() << endmsg; + } else if constexpr ( std::is_same_v<MuonPosition, MuonCluster> ) { + const auto tiles = track.point( i ).getPadTiles(); + for ( const auto tile : tiles ) { + lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); + this->template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " + << track.point( i ).station() << endmsg; } - }else{ - this-> template error() << "Incompatible muon position class. Will not add LHCbIDs to the track" << endmsg; + } else { + this->template error() << "Incompatible muon position class. Will not add LHCbIDs to the track" << endmsg; } } @@ -399,8 +408,9 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit lbtrack.setType( LHCb::Track::Types::Muon ); } -template<typename MuonPosition> -void StandaloneMuonRec<MuonPosition>::detectClone( std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks, const Cache& cache ) const { +template <typename MuonPosition> +void StandaloneMuonRec<MuonPosition>::detectClone( std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks, + const Cache& cache ) const { for ( auto itMuonTrackFirst = muonTracks.begin(); itMuonTrackFirst < muonTracks.end(); itMuonTrackFirst++ ) { for ( auto itMuonTrackSecond = itMuonTrackFirst + 1; itMuonTrackSecond < muonTracks.end(); itMuonTrackSecond++ ) { diff --git a/Tr/TrackTools/src/StandaloneMuonTrack.h b/Tr/TrackTools/src/StandaloneMuonTrack.h index 0f86109c532..1e6c92c531a 100644 --- a/Tr/TrackTools/src/StandaloneMuonTrack.h +++ b/Tr/TrackTools/src/StandaloneMuonTrack.h @@ -17,8 +17,8 @@ #include "GaudiKernel/Point3DTypes.h" #include "GaudiKernel/Vector3DTypes.h" -#include <string> #include <boost/container/small_vector.hpp> +#include <string> /** @class StandaloneMuonTrack StandaloneMuonTrack.h * @@ -33,25 +33,24 @@ namespace { enum class FitMode { XZ, YZ }; - - struct FitResult{ - float slope = -1e6; - float trunc = -1e6; - float chi2ndof = -1e6; + + struct FitResult { + float slope = -1e6; + float trunc = -1e6; + float chi2ndof = -1e6; float err_slope = -1e6; float err_trunc = -1e6; - float cov = -1e6; + float cov = -1e6; }; - - - template<typename MuonPositionClass, FitMode fitMode> - FitResult linearFitImpl( boost::container::small_vector<MuonPositionClass, LHCb::Detector::Muon::nStations>& points, float yAt0Err = std::numeric_limits<float>::max()){ + template <typename MuonPositionClass, FitMode fitMode> + FitResult linearFitImpl( boost::container::small_vector<MuonPositionClass, LHCb::Detector::Muon::nStations>& points, + float yAt0Err = std::numeric_limits<float>::max() ) { float sz2, sz, s0, sxz, sx, sx2; sz2 = sz = s0 = sxz = sx = sx2 = 0; FitResult result; - + for ( const auto& point : points ) { const auto z = point.z(); auto x = point.x(); @@ -59,7 +58,6 @@ namespace { if ( fitMode == FitMode::YZ ) { x = point.y(); xerr = 2 * point.dy(); - } sz2 += z * z / xerr / xerr; sz += z / xerr / xerr; @@ -69,36 +67,41 @@ namespace { sx2 += x * x / xerr / xerr; } - if( yAt0Err < std::numeric_limits<float>::max() ) s0 += 1.0 / ( yAt0Err*yAt0Err); // this applies a constraint to 0/0/0 - + if ( yAt0Err < std::numeric_limits<float>::max() ) + s0 += 1.0 / ( yAt0Err * yAt0Err ); // this applies a constraint to 0/0/0 + const float xdet = sz2 * s0 - sz * sz; if ( !LHCb::essentiallyZero( xdet ) ) { - result.slope = ( sxz * s0 - sx * sz ) / xdet; + result.slope = ( sxz * s0 - sx * sz ) / xdet; result.trunc = ( sx * sz2 - sxz * sz ) / xdet; result.err_trunc = sqrt( sz2 / xdet ); result.err_slope = sqrt( s0 / xdet ); result.cov = -sz / xdet; - result.chi2ndof = ( sx2 + result.slope * result.slope * sz2 + result.trunc * result.trunc * s0 - 2. * result.slope * sxz - 2. * result.trunc * sx + - 2 * result.slope * result.trunc * sz ) / - ( points.size() - 2 + (yAt0Err < std::numeric_limits<float>::max()) ); // add one degree of freedom if we add the "point" at 0/0/0 + result.chi2ndof = + ( sx2 + result.slope * result.slope * sz2 + result.trunc * result.trunc * s0 - 2. * result.slope * sxz - + 2. * result.trunc * sx + 2 * result.slope * result.trunc * sz ) / + ( points.size() - 2 + ( yAt0Err < std::numeric_limits<float>::max() ) ); // add one degree of freedom if we + // add the "point" at 0/0/0 } return result; - } } // namespace -template<typename MuonPositionClass> +template <typename MuonPositionClass> class StandaloneMuonTrack final { public: /// Standard constructor - StandaloneMuonTrack() { m_clone = false; m_points.reserve(4); }; + StandaloneMuonTrack() { + m_clone = false; + m_points.reserve( 4 ); + }; virtual ~StandaloneMuonTrack(){}; ///< Destructor void setPoint( unsigned int station, MuonPositionClass point ) { m_points[station] = point; }; - void addPoint( MuonPositionClass point ) { m_points.push_back(point); }; + void addPoint( MuonPositionClass point ) { m_points.push_back( point ); }; MuonPositionClass point( unsigned int station ) const { return m_points[station]; }; @@ -106,8 +109,8 @@ public: bool isClone() const { return m_clone; } // -- used to constrain the straight line fit in y to 0/0/0 - void setYAt0Err(const float yAt0Err){ m_yAt0Err = yAt0Err; } - + void setYAt0Err( const float yAt0Err ) { m_yAt0Err = yAt0Err; } + // Fit with a min chi^2 in the 2 projections xz and yz bool linearFit() { const double dof = nHits() - 2.; @@ -136,14 +139,13 @@ public: inline double errby() const { return m_resultYZ.err_trunc; } inline double covbsy() const { return m_resultYZ.cov; } - inline int nHits() const { return m_points.size(); } + inline int nHits() const { return m_points.size(); } private: - boost::container::small_vector<MuonPositionClass,LHCb::Detector::Muon::nStations> m_points; - bool m_clone; - float m_yAt0Err = std::numeric_limits<float>::max(); - + boost::container::small_vector<MuonPositionClass, LHCb::Detector::Muon::nStations> m_points; + bool m_clone; + float m_yAt0Err = std::numeric_limits<float>::max(); + FitResult m_resultXZ; FitResult m_resultYZ; - }; -- GitLab From fceab0da857391da1bf40a15035c4a22d2d0558a Mon Sep 17 00:00:00 2001 From: Michel De Cian <michel.de.cian@cern.ch> Date: Thu, 13 Feb 2025 08:49:35 +0000 Subject: [PATCH 07/14] use `insert` instead of `push_back` --- Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp index 86ce8741ab3..10cd83545ac 100644 --- a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp +++ b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp @@ -39,8 +39,8 @@ namespace LHCb { CommonMuonHits out; out.reserve( hitContainer.hits( 0 ).size() * LHCb::Detector::Muon::nStations ); for ( int s = 0; s < LHCb::Detector::Muon::nStations; ++s ) { - auto hits = hitContainer.hits( s ); - for ( auto hit : hits ) out.push_back( hit ); + auto const& hits = hitContainer.hits( s ); + out.insert( out.end(), hits.begin(), hits.end() ); } return out; } -- GitLab From 3fca5ede405a8696cf9943c3c701317690d44e7b Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Thu, 13 Feb 2025 10:30:00 +0100 Subject: [PATCH 08/14] use using instead of typedef, fix signed unsigned comparison --- Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp | 2 +- Tr/TrackTools/src/StandaloneMuonRec.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp index 10cd83545ac..c66128b731b 100644 --- a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp +++ b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp @@ -38,7 +38,7 @@ namespace LHCb { CommonMuonHits operator()( const MuonHitContainer& hitContainer ) const override { CommonMuonHits out; out.reserve( hitContainer.hits( 0 ).size() * LHCb::Detector::Muon::nStations ); - for ( int s = 0; s < LHCb::Detector::Muon::nStations; ++s ) { + for ( std::size_t s = 0; s < LHCb::Detector::Muon::nStations; ++s ) { auto const& hits = hitContainer.hits( s ); out.insert( out.end(), hits.begin(), hits.end() ); } diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index 392cab03d60..71357b9b4ca 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -90,8 +90,8 @@ class StandaloneMuonRec LHCb::Algorithm::Traits::usesConditions<Cache>> { public: - typedef std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>> MuonPositionContainer; - typedef std::array<std::vector<MuonPosition>, LHCb::Detector::Muon::nStations> PositionsInStations; + using MuonPositionContainer = std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>>; + using PositionsInStations = std::array<std::vector<MuonPosition>, LHCb::Detector::Muon::nStations>; using base_class_t = LHCb::Algorithm::Transformer<LHCb::Tracks( const MuonPositionContainer&, const Cache& ), LHCb::Algorithm::Traits::usesConditions<Cache>>; -- GitLab From 1590fb55d9a38d8ea6c15cada218db83ac9cab1c Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Thu, 13 Feb 2025 11:15:07 +0100 Subject: [PATCH 09/14] include header with muon constant explicitly --- Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp | 1 + Tr/TrackTools/src/StandaloneMuonRec.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp index c66128b731b..46eb1d5197e 100644 --- a/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp +++ b/Muon/MuonTools/src/MuonHitContainerToCommonMuonHits.cpp @@ -16,6 +16,7 @@ #include "Event/PrHits.h" #include "MuonDAQ/CommonMuonHit.h" #include "MuonDAQ/MuonHitContainer.h" +#include <Detector/Muon/MuonConstants.h> namespace LHCb { diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index 71357b9b4ca..c382fe1ad1d 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -29,6 +29,7 @@ #include "MuonDet/DeMuonDetector.h" #include "MuonDet/MuonNamespace.h" #include "MuonInterfaces/MuonCluster.h" +#include <Detector/Muon/MuonConstants.h> #include "vdt/vdtMath.h" #include "StandaloneMuonTrack.h" -- GitLab From ba72429a7384cd027a034609fcbce7b87373bd97 Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Thu, 13 Feb 2025 15:43:04 +0100 Subject: [PATCH 10/14] remove template keyword which caused trouble with clang --- Tr/TrackTools/src/StandaloneMuonRec.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index c382fe1ad1d..f67f71ab766 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -117,9 +117,9 @@ public: m_bIntegrator->calculateBdlAndCenter( magnet.fieldGrid(), begin, end, 0.0001, 0., cache.zCenter, cache.bdl ); cache.fieldPolarity = magnet.isDown() ? -1 : 1; - this->template debug() << "Integrated B field is " << cache.bdl.x() << " Tm" - << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" - << " with polarity " << cache.fieldPolarity << endmsg; + this->debug() << "Integrated B field is " << cache.bdl.x() << " Tm" + << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" + << " with polarity " << cache.fieldPolarity << endmsg; return cache; } ); } ); @@ -170,7 +170,7 @@ template <typename MuonPosition> LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionContainer& hitContainer, const Cache& cache ) const { - if ( this->template msgLevel( MSG::DEBUG ) ) this->template debug() << "==> Execute" << endmsg; + if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << "==> Execute" << endmsg; PositionsInStations posInStations; for ( auto hit : hitContainer ) { posInStations[hit.station()].push_back( hit ); } @@ -200,8 +200,8 @@ LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionCont } m_countMuCandidates += outputTracks.size(); - if ( this->template msgLevel( MSG::DEBUG ) ) - this->template debug() << " stored candidates " << outputTracks.size() << endmsg; + if ( this->msgLevel( MSG::DEBUG ) ) + this->debug() << " stored candidates " << outputTracks.size() << endmsg; return outputTracks; } @@ -378,7 +378,7 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit state.setLocation( LHCb::State::Location::Muon ); endstate.setLocation( LHCb::State::Location::LastMeasurement ); - this->template debug() << "Muon state = " << state << endmsg; + this->debug() << "Muon state = " << state << endmsg; lbtrack.clearStates(); lbtrack.addToStates( state ); @@ -391,17 +391,17 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit if constexpr ( std::is_same_v<MuonPosition, CommonMuonHit> ) { const auto tile = track.point( i ).tile(); lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); - this->template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " + this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; } else if constexpr ( std::is_same_v<MuonPosition, MuonCluster> ) { const auto tiles = track.point( i ).getPadTiles(); for ( const auto tile : tiles ) { lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); - this->template debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " + this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; } } else { - this->template error() << "Incompatible muon position class. Will not add LHCbIDs to the track" << endmsg; + this->error() << "Incompatible muon position class. Will not add LHCbIDs to the track" << endmsg; } } -- GitLab From b8404c5b8b9e7d2da9a4a6aa1602172356e7b83d Mon Sep 17 00:00:00 2001 From: Gitlab CI <noreply@cern.ch> Date: Thu, 13 Feb 2025 14:59:50 +0000 Subject: [PATCH 11/14] pre-commit fixes patch generated by https://gitlab.cern.ch/lhcb/Rec/-/jobs/50967694 --- Tr/TrackTools/src/StandaloneMuonRec.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index f67f71ab766..ed3037045a3 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -29,8 +29,8 @@ #include "MuonDet/DeMuonDetector.h" #include "MuonDet/MuonNamespace.h" #include "MuonInterfaces/MuonCluster.h" -#include <Detector/Muon/MuonConstants.h> #include "vdt/vdtMath.h" +#include <Detector/Muon/MuonConstants.h> #include "StandaloneMuonTrack.h" @@ -92,7 +92,7 @@ class StandaloneMuonRec public: using MuonPositionContainer = std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>>; - using PositionsInStations = std::array<std::vector<MuonPosition>, LHCb::Detector::Muon::nStations>; + using PositionsInStations = std::array<std::vector<MuonPosition>, LHCb::Detector::Muon::nStations>; using base_class_t = LHCb::Algorithm::Transformer<LHCb::Tracks( const MuonPositionContainer&, const Cache& ), LHCb::Algorithm::Traits::usesConditions<Cache>>; @@ -118,8 +118,8 @@ public: cache.bdl ); cache.fieldPolarity = magnet.isDown() ? -1 : 1; this->debug() << "Integrated B field is " << cache.bdl.x() << " Tm" - << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" - << " with polarity " << cache.fieldPolarity << endmsg; + << " centered at Z=" << cache.zCenter / Gaudi::Units::m << " m" + << " with polarity " << cache.fieldPolarity << endmsg; return cache; } ); } ); @@ -200,8 +200,7 @@ LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionCont } m_countMuCandidates += outputTracks.size(); - if ( this->msgLevel( MSG::DEBUG ) ) - this->debug() << " stored candidates " << outputTracks.size() << endmsg; + if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << " stored candidates " << outputTracks.size() << endmsg; return outputTracks; } @@ -391,14 +390,14 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit if constexpr ( std::is_same_v<MuonPosition, CommonMuonHit> ) { const auto tile = track.point( i ).tile(); lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); - this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " - << track.point( i ).station() << endmsg; + this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() + << endmsg; } else if constexpr ( std::is_same_v<MuonPosition, MuonCluster> ) { const auto tiles = track.point( i ).getPadTiles(); for ( const auto tile : tiles ) { lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); - this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " - << track.point( i ).station() << endmsg; + this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() + << endmsg; } } else { this->error() << "Incompatible muon position class. Will not add LHCbIDs to the track" << endmsg; -- GitLab From 95ac896e67aaaecb2a9491ee00b44e73acc409a4 Mon Sep 17 00:00:00 2001 From: decianm <michel.de.cian@.cern.ch> Date: Tue, 18 Feb 2025 12:33:01 +0100 Subject: [PATCH 12/14] Added a static assert to check the possible muon position classes at compile time --- Tr/TrackTools/src/StandaloneMuonRec.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index ed3037045a3..b8a1a96d9af 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -386,21 +386,22 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit const int DoFForPointAtZero = m_yAt0Error < std::numeric_limits<float>::max(); lbtrack.setNDoF( track.nHits() - 2 + DoFForPointAtZero ); // add one degree of freedom for the point at 0/0/0 + static_assert( std::is_same_v<MuonPosition, CommonMuonHit> || + std::is_same_v<MuonPosition, MuonCluster> , "Muon position must either be a CommonMuonHit or a MuonCluster"); + for ( int i = 0; i < track.nHits(); i++ ) { if constexpr ( std::is_same_v<MuonPosition, CommonMuonHit> ) { const auto tile = track.point( i ).tile(); lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; - } else if constexpr ( std::is_same_v<MuonPosition, MuonCluster> ) { + } else { const auto tiles = track.point( i ).getPadTiles(); for ( const auto tile : tiles ) { lbtrack.addToLhcbIDs( ( LHCb::LHCbID )( tile ) ); this->debug() << " Muon Hit " << i << " tile " << tile << " tiles in station " << track.point( i ).station() << endmsg; } - } else { - this->error() << "Incompatible muon position class. Will not add LHCbIDs to the track" << endmsg; } } -- GitLab From 7d0e1beca55afcf10bd2c7a8c960f73988916fb3 Mon Sep 17 00:00:00 2001 From: Gitlab CI <noreply@cern.ch> Date: Tue, 18 Feb 2025 11:33:45 +0000 Subject: [PATCH 13/14] pre-commit fixes patch generated by https://gitlab.cern.ch/lhcb/Rec/-/jobs/51218383 --- Tr/TrackTools/src/StandaloneMuonRec.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index b8a1a96d9af..e13c0f3ced9 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -386,9 +386,9 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit const int DoFForPointAtZero = m_yAt0Error < std::numeric_limits<float>::max(); lbtrack.setNDoF( track.nHits() - 2 + DoFForPointAtZero ); // add one degree of freedom for the point at 0/0/0 - static_assert( std::is_same_v<MuonPosition, CommonMuonHit> || - std::is_same_v<MuonPosition, MuonCluster> , "Muon position must either be a CommonMuonHit or a MuonCluster"); - + static_assert( std::is_same_v<MuonPosition, CommonMuonHit> || std::is_same_v<MuonPosition, MuonCluster>, + "Muon position must either be a CommonMuonHit or a MuonCluster" ); + for ( int i = 0; i < track.nHits(); i++ ) { if constexpr ( std::is_same_v<MuonPosition, CommonMuonHit> ) { const auto tile = track.point( i ).tile(); -- GitLab From 55f5247969bac758e1e82f28d044e6fccfd51ecf Mon Sep 17 00:00:00 2001 From: Sebastien Ponce <sebastien.ponce@cern.ch> Date: Tue, 18 Feb 2025 15:06:19 +0100 Subject: [PATCH 14/14] Use concepts to enforce MuonPosition being either CommonMuonhit or MuonCluster --- Tr/TrackTools/src/StandaloneMuonRec.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Tr/TrackTools/src/StandaloneMuonRec.cpp b/Tr/TrackTools/src/StandaloneMuonRec.cpp index e13c0f3ced9..5372c690203 100644 --- a/Tr/TrackTools/src/StandaloneMuonRec.cpp +++ b/Tr/TrackTools/src/StandaloneMuonRec.cpp @@ -84,7 +84,12 @@ namespace { }; } // namespace -template <class MuonPosition> +/// MuonPositionConcept makes sure we are dealing either with CommonMuonHit or with MuonCluster +template <typename MuonPosition> +concept MuonPositionConcept = + requires { requires std::is_same_v<MuonPosition, CommonMuonHit> || std::is_same_v<MuonPosition, MuonCluster>; }; + +template <MuonPositionConcept MuonPosition> class StandaloneMuonRec : public LHCb::Algorithm::Transformer< LHCb::Tracks( const std::vector<MuonPosition, LHCb::Allocators::EventLocal<MuonPosition>>&, const Cache& ), @@ -166,7 +171,7 @@ DECLARE_COMPONENT_WITH_ID( StandaloneMuonRec<MuonCluster>, "StandaloneMuonRecWit //============================================================================= // Main execution //============================================================================= -template <typename MuonPosition> +template <MuonPositionConcept MuonPosition> LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionContainer& hitContainer, const Cache& cache ) const { @@ -204,7 +209,7 @@ LHCb::Tracks StandaloneMuonRec<MuonPosition>::operator()( const MuonPositionCont return outputTracks; } -template <typename MuonPosition> +template <MuonPositionConcept MuonPosition> bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const float y, const unsigned int station, const unsigned int regionBefore, const std::vector<MuonPosition>& hits, @@ -230,7 +235,7 @@ bool StandaloneMuonRec<MuonPosition>::findCoincidence( const float x, const floa } return findCand; } -template <typename MuonPosition> +template <MuonPositionConcept MuonPosition> void StandaloneMuonRec<MuonPosition>::findmuonTrack( const PositionsInStations& hitContainer, const Cache& cache, std::array<MuonPosition, LHCb::Detector::Muon::nStations>& bestCandidates, const int seed, @@ -278,7 +283,7 @@ void StandaloneMuonRec<MuonPosition>::findmuonTrack( muonTracks.push_back( muon ); } } -template <typename MuonPosition> +template <MuonPositionConcept MuonPosition> std::vector<StandaloneMuonTrack<MuonPosition>> StandaloneMuonRec<MuonPosition>::muonSearch( const PositionsInStations& hitContainer, const Cache& cache ) const { std::vector<StandaloneMuonTrack<MuonPosition>> muonTracks; @@ -307,7 +312,7 @@ StandaloneMuonRec<MuonPosition>::muonSearch( const PositionsInStations& hitConta } // estimate the momentum of muonTrack -template <typename MuonPosition> +template <MuonPositionConcept MuonPosition> void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosition>& track, const Cache& cache, LHCb::Track& lbtrack ) const { @@ -386,9 +391,6 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit const int DoFForPointAtZero = m_yAt0Error < std::numeric_limits<float>::max(); lbtrack.setNDoF( track.nHits() - 2 + DoFForPointAtZero ); // add one degree of freedom for the point at 0/0/0 - static_assert( std::is_same_v<MuonPosition, CommonMuonHit> || std::is_same_v<MuonPosition, MuonCluster>, - "Muon position must either be a CommonMuonHit or a MuonCluster" ); - for ( int i = 0; i < track.nHits(); i++ ) { if constexpr ( std::is_same_v<MuonPosition, CommonMuonHit> ) { const auto tile = track.point( i ).tile(); @@ -409,7 +411,7 @@ void StandaloneMuonRec<MuonPosition>::recMomentum( StandaloneMuonTrack<MuonPosit lbtrack.setType( LHCb::Track::Types::Muon ); } -template <typename MuonPosition> +template <MuonPositionConcept MuonPosition> void StandaloneMuonRec<MuonPosition>::detectClone( std::vector<StandaloneMuonTrack<MuonPosition>>& muonTracks, const Cache& cache ) const { -- GitLab