From a9220bacd8b6fe6537fdf3bf48149de1914f967a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20G=C3=BCnther?=
Date: Fri, 5 May 2023 13:49:05 +0200
Subject: [PATCH 1/4] Move PrVeloUT into its own namespace and restructure and
clean it
---
Pr/PrVeloUT/src/PrVeloUT.cpp | 598 ++++++++++++++++-------------------
1 file changed, 281 insertions(+), 317 deletions(-)
diff --git a/Pr/PrVeloUT/src/PrVeloUT.cpp b/Pr/PrVeloUT/src/PrVeloUT.cpp
index c848a7904e8..51606bef095 100644
--- a/Pr/PrVeloUT/src/PrVeloUT.cpp
+++ b/Pr/PrVeloUT/src/PrVeloUT.cpp
@@ -1,5 +1,5 @@
-/***************************************************************************** \
-* (c) Copyright 2000-2022 CERN for the benefit of the LHCb Collaboration *
+/*****************************************************************************\
+* (c) Copyright 2024 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". *
@@ -8,299 +8,179 @@
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
+
#include "PrUTMagnetTool.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/** @class PrVeloUT PrVeloUT.h
- *
- * PrVeloUT algorithm. This is just a wrapper,
- * the actual pattern recognition is done in the 'PrVeloUTTool'.
- *
- * - InputTracksName: Input location for Velo tracks
- * - OutputTracksName: Output location for VeloTT tracks
- * - TimingMeasurement: Do a timing measurement?
- *
- * @author Mariusz Witek
- * @date 2007-05-08
- * @update for A-Team framework 2007-08-20 SHM
- *
- * 2017-03-01: Christoph Hasse (adapt to future framework)
- * 2019-04-26: Arthur Hennequin (change data Input/Output)
- * 2020-08-26: Peilian Li (change data Input/Output to SOACollection)
- */
-
-namespace LHCb::Pr {
-
- using simd = SIMDWrapper::best::types;
- using scalar = SIMDWrapper::scalar::types;
-
- constexpr auto nanMomentum = std::numeric_limits::quiet_NaN();
-
- constexpr static int batchSize = 2 * simd::size;
- const int totalUTLayers = static_cast( UTInfo::DetectorNumbers::TotalLayers );
-
- struct ProtoTracks final {
-
- std::array wbs;
- std::array xMidFields;
- std::array invKinkVeloDists;
-
- // -- this is for the hits
- // -- this does _not_ include overlap hits, so only 4 per track
- std::array xs;
- std::array zs;
- std::array weightss{}; // this needs to be zero-initialized
- std::array sins;
- std::array ids;
- std::array hitIndexs;
-
- // -- this is the output of the fit
- std::array qps;
- std::array chi2TTs;
- std::array xTTs;
- std::array xSlopeTTs;
- std::array ys;
-
- // -- and this the original state (in the Velo)
- std::array statePoss;
- std::array stateDirs;
- std::array ancestorIndexs;
-
- // -- and this an index to find the hit containers
- std::array hitContIndexs;
-
- std::size_t size{0};
- SOA_ACCESSOR_VAR( x, &( xs[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( z, &( zs[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( weight, &( weightss[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( sin, &( sins[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( id, &( ids[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( hitIndex, &( hitIndexs[pos * batchSize] ), int pos )
-
- SOA_ACCESSOR( qp, qps.data() )
- SOA_ACCESSOR( chi2TT, chi2TTs.data() )
- SOA_ACCESSOR( xTT, xTTs.data() )
- SOA_ACCESSOR( xSlopeTT, xSlopeTTs.data() )
- SOA_ACCESSOR( y, ys.data() )
-
- SOA_ACCESSOR( ancestorIndex, ancestorIndexs.data() )
- SOA_ACCESSOR( hitContIndex, hitContIndexs.data() )
- VEC3_SOA_ACCESSOR( pos, (float*)&( statePoss[0] ), (float*)&( statePoss[batchSize] ),
- (float*)&( statePoss[2 * batchSize] ) )
- VEC3_XY_SOA_ACCESSOR( dir, (float*)&( stateDirs[0] ), (float*)&( stateDirs[batchSize] ), 1.0f )
-
- SOA_ACCESSOR( wb, wbs.data() )
- SOA_ACCESSOR( xMidField, xMidFields.data() )
- SOA_ACCESSOR( invKinkVeloDist, invKinkVeloDists.data() )
-
- void initTracks( int indexVal, float maxPseudoChi2 ) {
- hitIndexs.fill( indexVal );
- chi2TTs.fill( maxPseudoChi2 );
- size = 0;
- }
- template
- void fillHelperParams( Vec3 pos, Vec3 dir, const float zKink,
- const float sigmaVeloSlope ) {
+#include
+#include
+#include
+#include
+
+#include "Gaudi/Accumulators.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+#include "DetDesc/GenericConditionAccessorHolder.h"
+#include "Magnet/DeMagnet.h"
+#include "UTDet/DeUTDetector.h"
+
+#include "Event/PrHits.h"
+#include "Event/PrUpstreamTracks.h"
+#include "Event/PrVeloTracks.h"
+#include "Event/UTSectorHelper.h"
+#include "Event/UTTrackUtils.h"
+#include "Event/ZipUtils.h"
+#include "Kernel/STLExtensions.h"
+#include "LHCbAlgs/Transformer.h"
+#include "LHCbMath/GeomFun.h"
+#include "LHCbMath/SIMDWrapper.h"
+
+#include "PrKernel/PrMutUTHits.h"
+#include "UTDAQ/UTDAQHelper.h"
+#include "UTDAQ/UTInfo.h"
+
+#include "vdt/sqrt.h"
+
+namespace LHCb::Pr::VeloUT {
+ namespace {
+ using simd = SIMDWrapper::best::types;
+ using scalar = SIMDWrapper::scalar::types;
+ using TracksTag = Upstream::Tag;
+ namespace HitTag = UT::Mut::HitTag;
+
+ constexpr auto nanMomentum = std::numeric_limits::quiet_NaN();
+ constexpr auto batchSize = 2 * simd::size;
+ constexpr auto totalUTLayers = static_cast( UTInfo::DetectorNumbers::TotalLayers );
+
+ struct ProtoTracks final {
+
+ std::array wbs;
+ std::array xMidFields;
+ std::array invKinkVeloDists;
+
+ // -- this is for the hits
+ // -- this does _not_ include overlap hits, so only 4 per track
+ std::array xs;
+ std::array zs;
+ std::array weightss{}; // this needs to be zero-initialized
+ std::array sins;
+ std::array ids;
+ std::array hitIndexs;
+
+ // -- this is the output of the fit
+ std::array qps;
+ std::array chi2TTs;
+ std::array xTTs;
+ std::array xSlopeTTs;
+ std::array ys;
+
+ // -- and this the original state (in the Velo)
+ std::array statePoss;
+ std::array stateDirs;
+ std::array ancestorIndexs;
+
+ // -- and this an index to find the hit containers
+ std::array hitContIndexs;
+
+ std::size_t size{0};
+ SOA_ACCESSOR_VAR( x, &( xs[pos * batchSize] ), int pos )
+ SOA_ACCESSOR_VAR( z, &( zs[pos * batchSize] ), int pos )
+ SOA_ACCESSOR_VAR( weight, &( weightss[pos * batchSize] ), int pos )
+ SOA_ACCESSOR_VAR( sin, &( sins[pos * batchSize] ), int pos )
+ SOA_ACCESSOR_VAR( id, &( ids[pos * batchSize] ), int pos )
+ SOA_ACCESSOR_VAR( hitIndex, &( hitIndexs[pos * batchSize] ), int pos )
+
+ SOA_ACCESSOR( qp, qps.data() )
+ SOA_ACCESSOR( chi2TT, chi2TTs.data() )
+ SOA_ACCESSOR( xTT, xTTs.data() )
+ SOA_ACCESSOR( xSlopeTT, xSlopeTTs.data() )
+ SOA_ACCESSOR( y, ys.data() )
+
+ SOA_ACCESSOR( ancestorIndex, ancestorIndexs.data() )
+ SOA_ACCESSOR( hitContIndex, hitContIndexs.data() )
+ VEC3_SOA_ACCESSOR( pos, (float*)&( statePoss[0] ), (float*)&( statePoss[batchSize] ),
+ (float*)&( statePoss[2 * batchSize] ) )
+ VEC3_XY_SOA_ACCESSOR( dir, (float*)&( stateDirs[0] ), (float*)&( stateDirs[batchSize] ), 1.0f )
+
+ SOA_ACCESSOR( wb, wbs.data() )
+ SOA_ACCESSOR( xMidField, xMidFields.data() )
+ SOA_ACCESSOR( invKinkVeloDist, invKinkVeloDists.data() )
+
+ void initTracks( int indexVal, float maxPseudoChi2 ) {
+ hitIndexs.fill( indexVal );
+ chi2TTs.fill( maxPseudoChi2 );
+ size = 0;
+ }
+
+ template
+ void fillHelperParams( Vec3 pos, Vec3 dir, const float zKink,
+ const float sigmaVeloSlope ) {
- using F = typename dType::float_v;
+ using F = typename dType::float_v;
- F( pos.x + dir.x * ( zKink - pos.z ) ).store( xMidFields.data() );
- F a = sigmaVeloSlope * ( zKink - pos.z );
- F( 1.0f / ( a * a ) ).store( wbs.data() );
- F( 1.0f / ( zKink - pos.z ) ).store( invKinkVeloDists.data() );
- }
+ F( pos.x + dir.x * ( zKink - pos.z ) ).store( xMidFields.data() );
+ F a = sigmaVeloSlope * ( zKink - pos.z );
+ F( 1.0f / ( a * a ) ).store( wbs.data() );
+ F( 1.0f / ( zKink - pos.z ) ).store( invKinkVeloDists.data() );
+ }
- template
- void storeSimpleFitInfo( typename dType::float_v chi2TT, typename dType::float_v qp, typename dType::float_v xTT,
- typename dType::float_v xSlopeTT, unsigned int trackIndex ) {
+ template
+ void storeSimpleFitInfo( typename dType::float_v chi2TT, typename dType::float_v qp, typename dType::float_v xTT,
+ typename dType::float_v xSlopeTT, unsigned int trackIndex ) {
- using F = typename dType::float_v;
+ using F = typename dType::float_v;
- F( chi2TT ).store( &chi2TTs[trackIndex] );
- F( qp ).store( &qps[trackIndex] );
- F( xTT ).store( &xTTs[trackIndex] );
- F( xSlopeTT ).store( &xSlopeTTs[trackIndex] );
- }
+ F( chi2TT ).store( &chi2TTs[trackIndex] );
+ F( qp ).store( &qps[trackIndex] );
+ F( xTT ).store( &xTTs[trackIndex] );
+ F( xSlopeTT ).store( &xSlopeTTs[trackIndex] );
+ }
- // -- this runs over all 4 layers, even if no hit was found
- // -- but it fills a weight of 0
- // -- Note: These are not "physical" layers, as the hits are ordered such that only
- // -- the last one can be not filled.
- template
- void fillHitInfo( const LHCb::Event::Zip& hitsInL,
- unsigned int trackIndex ) {
-
- using F = typename dType::float_v;
- using I = typename dType::int_v;
- auto nValid{0};
- if ( hitsInL.size() != 0 ) {
- for ( int i = 0; i < totalUTLayers; ++i ) {
- int hitI = hitIndexs[trackIndex + i * batchSize];
- const auto valid = ( hitI != -1 );
- const auto weight = valid ? hitsInL[hitI].weight().cast() : 0.0f;
- nValid += valid;
- hitI = std::max( 0, hitI );
- LHCb::LHCbID id( LHCb::Detector::UT::ChannelID( hitsInL[hitI].channelID().cast() ) );
-
- F( weight ).store( &weightss[trackIndex + i * batchSize] );
- F( hitsInL[hitI].x() ).store( &xs[trackIndex + i * batchSize] );
- F( hitsInL[hitI].z() ).store( &zs[trackIndex + i * batchSize] );
- F( hitsInL[hitI].sin() ).store( &sins[trackIndex + i * batchSize] );
- I( hitsInL[hitI].index() ).store( &hitIndexs[trackIndex + i * batchSize] );
- I( id.lhcbID() ).store( &ids[trackIndex + i * batchSize] );
+ // -- this runs over all 4 layers, even if no hit was found
+ // -- but it fills a weight of 0
+ // -- Note: These are not "physical" layers, as the hits are ordered such that only
+ // -- the last one can be not filled.
+ template
+ void fillHitInfo( const LHCb::Event::Zip& hitsInL,
+ unsigned int trackIndex ) {
+
+ using F = typename dType::float_v;
+ using I = typename dType::int_v;
+ auto nValid{0};
+ if ( hitsInL.size() != 0 ) {
+ for ( int i = 0; i < totalUTLayers; ++i ) {
+ int hitI = hitIndexs[trackIndex + i * batchSize];
+ const auto valid = ( hitI != -1 );
+ const auto weight = valid ? hitsInL[hitI].weight().cast() : 0.0f;
+ nValid += valid;
+ hitI = std::max( 0, hitI );
+ LHCb::LHCbID id( LHCb::Detector::UT::ChannelID( hitsInL[hitI].channelID().cast() ) );
+
+ F( weight ).store( &weightss[trackIndex + i * batchSize] );
+ F( hitsInL[hitI].x() ).store( &xs[trackIndex + i * batchSize] );
+ F( hitsInL[hitI].z() ).store( &zs[trackIndex + i * batchSize] );
+ F( hitsInL[hitI].sin() ).store( &sins[trackIndex + i * batchSize] );
+ I( hitsInL[hitI].index() ).store( &hitIndexs[trackIndex + i * batchSize] );
+ I( id.lhcbID() ).store( &ids[trackIndex + i * batchSize] );
+ }
}
+ // this is useful in filterMode
+ if ( !nValid ) { F( nanMomentum ).store( &qps[trackIndex] ); }
}
- // this is useful in filterMode
- if ( !nValid ) { F( nanMomentum ).store( &qps[trackIndex] ); }
- }
- };
+ };
- namespace {
- struct VeloUTGeomCache final {
- VeloUTGeomCache( const DeUTDetector& det, const UTMagnetTool::Cache& magtoolcache ) : common( det ) {
+ struct VeloUTGeomCache {
+ VeloUTGeomCache( const DeUTDetector& det, const UTMagnetTool::Cache& magtoolcache ) : common{det} {
// m_zMidUT is a position of normalization plane which should to be close to z middle of UT ( +- 5 cm ).
// Cached once in VeloUTTool at initialization. No need to update with small UT movement.
zMidUT = magtoolcache.zCenterUT;
// zMidField and distToMomentum is properly recalculated in PrUTMagnetTool when B field changes
distToMomentum = 1.0f / magtoolcache.dist2mom;
}
- VeloUTGeomCache() = default;
UTDAQ::GeomCache common;
- float zMidUT{0.}, distToMomentum{0.};
+ float zMidUT{0.f};
+ float distToMomentum{0.f};
};
- } // namespace
-
- class VeloUT
- : public LHCb::Algorithm::Transformer> {
-
- public:
- /// Standard constructor
- using base_class_t =
- LHCb::Algorithm::Transformer>;
-
- VeloUT( const std::string& name, ISvcLocator* pSvcLocator )
- : base_class_t( name, pSvcLocator,
- {KeyValue{"InputTracksName", "Rec/Track/Velo"}, KeyValue{"UTHits", UTInfo::HitLocation},
- KeyValue{"GeometryInfo", "AlgorithmSpecific-" + name + "-UTGeometryInfo"},
- KeyValue{"Magnet", LHCb::Det::Magnet::det_path}},
- KeyValue{"OutputTracksName", "Rec/Track/UT"} ) {}
-
- StatusCode initialize() override {
- return Transformer::initialize().andThen( [&] {
- addConditionDerivation( {DeUTDetLocation::location(), m_PrUTMagnetTool->cacheLocation()},
- inputLocation(),
- []( const DeUTDetector& det, const UTMagnetTool::Cache& magtoolcache ) {
- return VeloUTGeomCache( det, magtoolcache );
- } );
- } );
- }
-
- Upstream::Tracks operator()( const EventContext&, const Velo::Tracks&, const LHCb::Pr::UT::Hits&,
- const VeloUTGeomCache&, const DeMagnet& ) const override final;
-
- private:
- Gaudi::Property m_minMomentum{this, "MinMomentum", 1500.f * Gaudi::Units::MeV};
- Gaudi::Property m_minPT{this, "MinPT", 300.f * Gaudi::Units::MeV};
- Gaudi::Property m_minMomentumFinal{this, "MinMomentumFinal", 2500.f * Gaudi::Units::MeV};
- Gaudi::Property m_minPTFinal{this, "MinPTFinal", 425.f * Gaudi::Units::MeV};
- Gaudi::Property m_maxPseudoChi2{this, "MaxPseudoChi2", 1280.};
- Gaudi::Property m_yTol{this, "YTolerance", 0.5 * Gaudi::Units::mm}; // 0.8
- Gaudi::Property m_yTolSlope{this, "YTolSlope", 0.08}; // 0.2
- Gaudi::Property m_hitTol{this, "HitTol", 0.8 * Gaudi::Units::mm}; // 0.8
- Gaudi::Property m_deltaTx{this, "DeltaTx", 0.018}; // 0.02
- Gaudi::Property m_maxXSlope{this, "MaxXSlope", 0.350};
- Gaudi::Property m_maxYSlope{this, "MaxYSlope", 0.300};
- Gaudi::Property m_centralHoleSize{this, "CentralHoleSize", 33. * Gaudi::Units::mm};
- Gaudi::Property m_intraLayerDist{this, "IntraLayerDist", 15.0 * Gaudi::Units::mm};
- Gaudi::Property m_overlapTol{this, "OverlapTol", 0.5 * Gaudi::Units::mm};
- Gaudi::Property m_passHoleSize{this, "PassHoleSize", 40. * Gaudi::Units::mm};
- Gaudi::Property m_LD3Hits{this, "LD3HitsMin", -0.5};
- Gaudi::Property m_LD4Hits{this, "LD4HitsMin", -0.5};
- Gaudi::Property m_minLayers{this, "MinLayers", 3};
-
- Gaudi::Property m_printVariables{this, "PrintVariables", false};
- Gaudi::Property m_passTracks{this, "PassTracks", false};
- Gaudi::Property m_finalFit{this, "FinalFit", true};
- Gaudi::Property m_fiducialCuts{this, "FiducialCuts", true};
- Gaudi::Property m_looseSectorSearch{this, "LooseSectorSearch", false};
- Gaudi::Property m_filterMode{this, "FilterMode", false};
-
- mutable Gaudi::Accumulators::SummingCounter m_seedsCounter{this, "#seeds"};
- mutable Gaudi::Accumulators::SummingCounter m_tracksCounter{this, "#tracks"};
-
- LHCb::UT::TrackUtils::MiniStates getStates( const Velo::Tracks& inputTracks, Upstream::Tracks& outputTracks,
- float zMidUT ) const;
-
- template
- bool getHitsScalar( const LHCb::Pr::UT::Hits& hh, const LHCb::UT::TrackUtils::MiniStates& filteredStates,
- const std::array& compBoundsArray, LHCb::Pr::UT::Mut::Hits& hitsInLayers,
- const std::size_t t, float zMidUT, int minLayers = totalUTLayers - 1 ) const;
-
- inline void findHits( const LHCb::Pr::UT::Hits& hh, const simd::float_v& yProto, const simd::float_v& ty,
- const simd::float_v& tx, const simd::float_v& xOnTrackProto, const simd::float_v& tolProto,
- const simd::float_v& xTolNormFact, LHCb::Pr::UT::Mut::Hits& mutHits,
- const simd::float_v& yTol, const int firstIndex, const int lastIndex ) const;
-
- template
- bool formClusters( const LHCb::Pr::UT::Mut::Hits& hitsInLayers, ProtoTracks& pTracks, const int trackIndex,
- float zMidUT ) const;
-
- template
- void prepareOutputTrackSIMD( const ProtoTracks& protoTracks,
- const std::array& hitsInLayers,
- Upstream::Tracks& outputTracks, const Velo::Tracks& inputTracks,
- const BdlTable& bdlTable, const DeMagnet& magnet, float zMidUT ) const;
-
- /// Multipurpose tool for Bdl and deflection
- ToolHandle m_PrUTMagnetTool{this, "PrUTMagnetTool", "PrUTMagnetTool"};
-
- mutable Gaudi::Accumulators::MsgCounter m_too_much_in_filtered{
- this, "Reached the maximum number of tracks in filteredStates!!"};
- mutable Gaudi::Accumulators::MsgCounter m_too_much_in_boundaries{
- this, "Reached the maximum number of tracks in Boundaries!!"};
-
- constexpr static float c_zKink{1780.0};
- constexpr static float c_sigmaVeloSlope{0.10 * Gaudi::Units::mrad};
- constexpr static float c_invSigmaVeloSlope{10.0 / Gaudi::Units::mrad};
- };
-} // namespace LHCb::Pr
-
-//-----------------------------------------------------------------------------
-// Implementation file for class : PrVeloUT
-//
-// 2007-05-08: Mariusz Witek
-// 2017-03-01: Christoph Hasse (adapt to future framework)
-// 2019-04-26: Arthur Hennequin (change data Input/Output)
-//-----------------------------------------------------------------------------
-
-// Declaration of the Algorithm Factory
-DECLARE_COMPONENT_WITH_ID( LHCb::Pr::VeloUT, "PrVeloUT" )
-
-using TracksTag = LHCb::Pr::Upstream::Tag;
-namespace HitTag = LHCb::Pr::UT::Mut::HitTag;
-namespace LHCb::Pr {
- namespace {
simd::mask_v CholeskyDecomposition3( const std::array& mat, std::array& rhs ) {
// -- copied from Root::Math::CholeskyDecomp
@@ -334,17 +214,16 @@ namespace LHCb::Pr {
return mask;
}
- // -- parameters that describe the z position of the kink point as a function of ty in a 4th order polynomial (even
- // terms only)
- constexpr auto magFieldParams = std::array{2010.0f, -2240.0f, -71330.f};
-
// perform a fit using trackhelper's best hits with y correction, improve qop estimate
simd::float_v fastfitterSIMD( std::array& improvedParams, const ProtoTracks& protoTracks,
const float zMidUT, const simd::float_v qpxz2p, const int t,
simd::mask_v& goodFitMask ) {
-
- const Vec3 pos = protoTracks.pos( t );
- const Vec3 dir = protoTracks.dir( t );
+ // -- parameters that describe the z position of the kink point as a function of ty in a 4th order polynomial
+ // (even
+ // terms only)
+ constexpr auto magFieldParams = std::array{2010.0f, -2240.0f, -71330.f};
+ const Vec3 pos = protoTracks.pos( t );
+ const Vec3 dir = protoTracks.dir( t );
const simd::float_v x = pos.x;
const simd::float_v y = pos.y;
@@ -440,11 +319,6 @@ namespace LHCb::Pr {
coeffs[2] * log( inputValues[1] ) + coeffs[3] * log( inputValues[2] );
}
- /*
- simd::float_v calcXTol( const simd::float_v minMom, const simd::float_v ty ) {
- return ( 38000.0f / minMom + 0.25f ) * ( 1.0f + ty * ty * 0.8f );
- }
- */
// --------------------------------------------------------------------
// -- Helper function to calculate the planeCode: 0 - 1 - 2 - 3
// --------------------------------------------------------------------
@@ -476,10 +350,6 @@ namespace LHCb::Pr {
return ( index3 * 11 + index2 ) * 31 + index1;
}
- constexpr auto minValsBdl = std::array{-0.3f, -250.0f, 0.0f};
- constexpr auto maxValsBdl = std::array{0.3f, 250.0f, 800.0f};
- constexpr auto deltaBdl = std::array{0.02f, 50.0f, 80.0f};
- // constexpr auto dxDyHelper = std::array{0.0f, 1.0f, -1.0f, 0.0f};
// ===========================================================================================
// -- 2 helper functions for fit
// -- Pseudo chi2 fit, templated for 3 or 4 hits
@@ -497,6 +367,7 @@ namespace LHCb::Pr {
rhs[0] += wi * ui;
rhs[1] += wi * ui * dz;
}
+
template
inline __attribute__( ( always_inline ) ) void
simpleFit( const std::array& indices, const LHCb::Pr::UT::Mut::Hits& hits, ProtoTracks& pTracks,
@@ -555,12 +426,103 @@ namespace LHCb::Pr {
}
} // namespace
- //=============================================================================
- // Main execution
- //=============================================================================
- Upstream::Tracks VeloUT::operator()( const EventContext& evtCtx, const Velo::Tracks& inputTracks,
- const LHCb::Pr::UT::Hits& hh, const VeloUTGeomCache& velogeom,
- const DeMagnet& magnet ) const {
+ class PrVeloUT
+ : public Algorithm::Transformer> {
+
+ public:
+ PrVeloUT( const std::string& name, ISvcLocator* pSvcLocator )
+ : Transformer( name, pSvcLocator,
+ {KeyValue{"InputTracksName", "Rec/Track/Velo"}, KeyValue{"UTHits", UTInfo::HitLocation},
+ KeyValue{"GeometryInfo", "AlgorithmSpecific-" + name + "-UTGeometryInfo"},
+ KeyValue{"Magnet", Det::Magnet::det_path}},
+ KeyValue{"OutputTracksName", "Rec/Track/UT"} ) {}
+
+ StatusCode initialize() override {
+ return Transformer::initialize().andThen( [&] {
+ addConditionDerivation( {DeUTDetLocation::location(), m_PrUTMagnetTool->cacheLocation()},
+ inputLocation(),
+ []( const DeUTDetector& det, const UTMagnetTool::Cache& magtoolcache ) {
+ return VeloUTGeomCache( det, magtoolcache );
+ } );
+ } );
+ }
+
+ Upstream::Tracks operator()( const EventContext&, const Velo::Tracks&, const LHCb::Pr::UT::Hits&,
+ const VeloUTGeomCache&, const DeMagnet& ) const override final;
+
+ private:
+ Gaudi::Property m_minMomentum{this, "MinMomentum", 1500.f * Gaudi::Units::MeV};
+ Gaudi::Property m_minPT{this, "MinPT", 300.f * Gaudi::Units::MeV};
+ Gaudi::Property m_minMomentumFinal{this, "MinMomentumFinal", 2500.f * Gaudi::Units::MeV};
+ Gaudi::Property m_minPTFinal{this, "MinPTFinal", 425.f * Gaudi::Units::MeV};
+ Gaudi::Property m_maxPseudoChi2{this, "MaxPseudoChi2", 1280.};
+ Gaudi::Property m_yTol{this, "YTolerance", 0.5 * Gaudi::Units::mm}; // 0.8
+ Gaudi::Property m_yTolSlope{this, "YTolSlope", 0.08}; // 0.2
+ Gaudi::Property m_hitTol{this, "HitTol", 0.8 * Gaudi::Units::mm}; // 0.8
+ Gaudi::Property m_deltaTx{this, "DeltaTx", 0.018}; // 0.02
+ Gaudi::Property m_maxXSlope{this, "MaxXSlope", 0.350};
+ Gaudi::Property m_maxYSlope{this, "MaxYSlope", 0.300};
+ Gaudi::Property m_centralHoleSize{this, "CentralHoleSize", 33. * Gaudi::Units::mm};
+ Gaudi::Property m_intraLayerDist{this, "IntraLayerDist", 15.0 * Gaudi::Units::mm};
+ Gaudi::Property m_overlapTol{this, "OverlapTol", 0.5 * Gaudi::Units::mm};
+ Gaudi::Property m_passHoleSize{this, "PassHoleSize", 40. * Gaudi::Units::mm};
+ Gaudi::Property m_LD3Hits{this, "LD3HitsMin", -0.5};
+ Gaudi::Property m_LD4Hits{this, "LD4HitsMin", -0.5};
+ Gaudi::Property m_minLayers{this, "MinLayers", 3};
+
+ Gaudi::Property m_printVariables{this, "PrintVariables", false};
+ Gaudi::Property m_passTracks{this, "PassTracks", false};
+ Gaudi::Property m_finalFit{this, "FinalFit", true};
+ Gaudi::Property m_fiducialCuts{this, "FiducialCuts", true};
+ Gaudi::Property m_filterMode{this, "FilterMode", false};
+
+ mutable Gaudi::Accumulators::SummingCounter m_seedsCounter{this, "#seeds"};
+ mutable Gaudi::Accumulators::SummingCounter m_tracksCounter{this, "#tracks"};
+
+ LHCb::UT::TrackUtils::MiniStates getStates( const Velo::Tracks& inputTracks, Upstream::Tracks& outputTracks,
+ float zMidUT ) const;
+
+ bool getHitsScalar( const LHCb::Pr::UT::Hits& hh, const LHCb::UT::TrackUtils::MiniStates& filteredStates,
+ const std::array& compBoundsArray,
+ LHCb::Pr::UT::Mut::Hits& hitsInLayers, const std::size_t t, float zMidUT,
+ int minLayers = totalUTLayers - 1 ) const;
+
+ inline void findHits( const LHCb::Pr::UT::Hits& hh, const simd::float_v& yProto, const simd::float_v& ty,
+ const simd::float_v& tx, const simd::float_v& xOnTrackProto, const simd::float_v& tolProto,
+ const simd::float_v& xTolNormFact, LHCb::Pr::UT::Mut::Hits& mutHits,
+ const simd::float_v& yTol, const int firstIndex, const int lastIndex ) const;
+
+ template
+ bool formClusters( const LHCb::Pr::UT::Mut::Hits& hitsInLayers, ProtoTracks& pTracks, const int trackIndex,
+ float zMidUT ) const;
+
+ template
+ void prepareOutputTrackSIMD( const ProtoTracks& protoTracks,
+ const std::array& hitsInLayers,
+ Upstream::Tracks& outputTracks, const Velo::Tracks& inputTracks,
+ const BdlTable& bdlTable, const DeMagnet& magnet, float zMidUT ) const;
+
+ /// Multipurpose tool for Bdl and deflection
+ ToolHandle m_PrUTMagnetTool{this, "PrUTMagnetTool", "PrUTMagnetTool"};
+
+ mutable Gaudi::Accumulators::MsgCounter m_too_much_in_filtered{
+ this, "Reached the maximum number of tracks in filteredStates!!"};
+ mutable Gaudi::Accumulators::MsgCounter m_too_much_in_boundaries{
+ this, "Reached the maximum number of tracks in Boundaries!!"};
+
+ constexpr static float c_zKink{1780.0};
+ constexpr static float c_sigmaVeloSlope{0.10 * Gaudi::Units::mrad};
+ constexpr static float c_invSigmaVeloSlope{10.0 / Gaudi::Units::mrad};
+ };
+
+ // Declaration of the Algorithm Factory
+ DECLARE_COMPONENT_WITH_ID( PrVeloUT, "PrVeloUT" )
+
+ Upstream::Tracks PrVeloUT::operator()( const EventContext& evtCtx, const Velo::Tracks& inputTracks,
+ const LHCb::Pr::UT::Hits& hh, const VeloUTGeomCache& velogeom,
+ const DeMagnet& magnet ) const {
Upstream::Tracks outputTracks{&inputTracks, Zipping::generateZipIdentifier(), LHCb::getMemResource( evtCtx )};
outputTracks.reserve( inputTracks.size() );
@@ -688,11 +650,12 @@ namespace LHCb::Pr {
m_tracksCounter += outputTracks.size();
return outputTracks;
}
+
//=============================================================================
// Get the state, do some cuts
//=============================================================================
__attribute__( ( flatten ) ) LHCb::UT::TrackUtils::MiniStates
- VeloUT::getStates( const Velo::Tracks& inputTracks, Upstream::Tracks& outputTracks, float zMidUT ) const {
+ PrVeloUT::getStates( const Velo::Tracks& inputTracks, Upstream::Tracks& outputTracks, float zMidUT ) const {
LHCb::UT::TrackUtils::MiniStates filteredStates{Zipping::generateZipIdentifier(),
{inputTracks.get_allocator().resource()}};
@@ -748,10 +711,10 @@ namespace LHCb::Pr {
//=============================================================================
template
inline __attribute__( ( always_inline ) ) bool
- VeloUT::getHitsScalar( const LHCb::Pr::UT::Hits& hh, const LHCb::UT::TrackUtils::MiniStates& filteredStates,
- const std::array& compBoundsArray,
- LHCb::Pr::UT::Mut::Hits& hitsInLayers, const std::size_t t, float zMidUT,
- int minLayers ) const {
+ PrVeloUT::getHitsScalar( const LHCb::Pr::UT::Hits& hh, const LHCb::UT::TrackUtils::MiniStates& filteredStates,
+ const std::array& compBoundsArray,
+ LHCb::Pr::UT::Mut::Hits& hitsInLayers, const std::size_t t, float zMidUT,
+ int minLayers ) const {
// -- This is for some sanity checks later
[[maybe_unused]] const int maxNumSectors = m_looseSectorSearch
@@ -840,10 +803,10 @@ namespace LHCb::Pr {
// -- Method that finds the hits in a given layer within a certain range
// ==============================================================================
inline __attribute__( ( always_inline ) ) void
- VeloUT::findHits( const LHCb::Pr::UT::Hits& hh, const simd::float_v& yProto, const simd::float_v& ty,
- const simd::float_v& tx, const simd::float_v& xOnTrackProto, const simd::float_v& tolProto,
- const simd::float_v& xTolNormFact, LHCb::Pr::UT::Mut::Hits& mutHits, const simd::float_v& yTol,
- const int firstIndex, const int lastIndex ) const {
+ PrVeloUT::findHits( const LHCb::Pr::UT::Hits& hh, const simd::float_v& yProto, const simd::float_v& ty,
+ const simd::float_v& tx, const simd::float_v& xOnTrackProto, const simd::float_v& tolProto,
+ const simd::float_v& xTolNormFact, LHCb::Pr::UT::Mut::Hits& mutHits, const simd::float_v& yTol,
+ const int firstIndex, const int lastIndex ) const {
const auto& myHits = hh;
const auto myHs = myHits.simd();
@@ -887,9 +850,9 @@ namespace LHCb::Pr {
// Form clusters
//=========================================================================
template
- inline __attribute__( ( always_inline ) ) bool VeloUT::formClusters( const LHCb::Pr::UT::Mut::Hits& hitsInLayers,
- ProtoTracks& pTracks, const int trackIndex,
- float zMidUT ) const {
+ inline __attribute__( ( always_inline ) ) bool PrVeloUT::formClusters( const LHCb::Pr::UT::Mut::Hits& hitsInLayers,
+ ProtoTracks& pTracks, const int trackIndex,
+ float zMidUT ) const {
const int begin0 = forward ? hitsInLayers.layerIndices[0] : hitsInLayers.layerIndices[3];
const int end0 = forward ? hitsInLayers.layerIndices[1] : hitsInLayers.size();
@@ -986,10 +949,10 @@ namespace LHCb::Pr {
//=========================================================================
template
inline __attribute__( ( always_inline ) ) __attribute__( ( flatten ) ) void
- VeloUT::prepareOutputTrackSIMD( const ProtoTracks& protoTracks,
- const std::array& hitsInLayers,
- Upstream::Tracks& outputTracks, const Velo::Tracks& inputTracks,
- const BdlTable& bdlTable, const DeMagnet& magnet, float zMidUT ) const {
+ PrVeloUT::prepareOutputTrackSIMD( const ProtoTracks& protoTracks,
+ const std::array& hitsInLayers,
+ Upstream::Tracks& outputTracks, const Velo::Tracks& inputTracks,
+ const BdlTable& bdlTable, const DeMagnet& magnet, float zMidUT ) const {
auto const velozipped = inputTracks.simd();
const auto pSize = protoTracks.size;
@@ -1005,8 +968,6 @@ namespace LHCb::Pr {
// -- this is to filter tracks where the fit had a too large chi2
simd::mask_v fourHitTrack = protoTracks.weight( t, 3 ) > 0.0001f;
- // const float bdl1 = m_PrUTMagnetTool->bdlIntegral(helper.state.ty,zOrigin,helper.state.z);
-
// -- These are calculations, copied and simplified from PrTableForFunction
// -- FIXME: these rely on the internal details of PrTableForFunction!!!
// and should at least be put back in there, and used from here
@@ -1025,6 +986,9 @@ namespace LHCb::Pr {
gather( bdlTable.table().data(), masterIndexSIMD( index1, index2 + 1, index3 ) ),
gather( bdlTable.table().data(), masterIndexSIMD( index1, index2, index3 + 1 ) )};
+ constexpr auto minValsBdl = std::array{-0.3f, -250.0f, 0.0f};
+ constexpr auto maxValsBdl = std::array{0.3f, 250.0f, 800.0f};
+ constexpr auto deltaBdl = std::array{0.02f, 50.0f, 80.0f};
const std::array boundaries = {-0.3f + simd::float_v{index1} * deltaBdl[0],
-250.0f + simd::float_v{index2} * deltaBdl[1],
0.0f + simd::float_v{index3} * deltaBdl[2]};
@@ -1215,4 +1179,4 @@ namespace LHCb::Pr {
}
} // loop on t
}
-} // namespace LHCb::Pr
+} // namespace LHCb::Pr::VeloUT
--
GitLab
From e5a5a693a4a53077ba54637b8e43ba5423c2e0bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20G=C3=BCnther?=
Date: Fri, 5 May 2023 14:17:11 +0200
Subject: [PATCH 2/4] Use SOACollection for ProtoTracks in PrVeloUT
---
Pr/PrVeloUT/src/PrVeloUT.cpp | 806 +++++++++++++++--------------------
1 file changed, 351 insertions(+), 455 deletions(-)
diff --git a/Pr/PrVeloUT/src/PrVeloUT.cpp b/Pr/PrVeloUT/src/PrVeloUT.cpp
index 51606bef095..935980bfccd 100644
--- a/Pr/PrVeloUT/src/PrVeloUT.cpp
+++ b/Pr/PrVeloUT/src/PrVeloUT.cpp
@@ -27,6 +27,7 @@
#include "Event/PrHits.h"
#include "Event/PrUpstreamTracks.h"
#include "Event/PrVeloTracks.h"
+#include "Event/SOACollection.h"
#include "Event/UTSectorHelper.h"
#include "Event/UTTrackUtils.h"
#include "Event/ZipUtils.h"
@@ -43,130 +44,69 @@
namespace LHCb::Pr::VeloUT {
namespace {
- using simd = SIMDWrapper::best::types;
- using scalar = SIMDWrapper::scalar::types;
- using TracksTag = Upstream::Tag;
+ using simd = SIMDWrapper::best::types;
+ using scalar = SIMDWrapper::scalar::types;
+ using TracksTag = Upstream::Tag;
+
namespace HitTag = UT::Mut::HitTag;
+ namespace TU = LHCb::UT::TrackUtils;
+ constexpr auto EndVelo = Event::Enum::State::Location::EndVelo;
constexpr auto nanMomentum = std::numeric_limits::quiet_NaN();
- constexpr auto batchSize = 2 * simd::size;
constexpr auto totalUTLayers = static_cast( UTInfo::DetectorNumbers::TotalLayers );
-
- struct ProtoTracks final {
-
- std::array wbs;
- std::array xMidFields;
- std::array invKinkVeloDists;
-
+ // -- Used for the calculation of the size of the search windows
+ constexpr std::array normFact{0.95f, 1.0f, 1.36f, 1.41f};
+ using LooseBounds = std::array;
+ using NominalBounds = std::array;
+
+ struct ProtoTrackTag {
+ struct InitialWeight : Event::float_field {};
+ struct XMidField : Event::float_field {};
+ struct InvKinkVeloDist : Event::float_field {};
// -- this is for the hits
// -- this does _not_ include overlap hits, so only 4 per track
- std::array xs;
- std::array zs;
- std::array weightss{}; // this needs to be zero-initialized
- std::array sins;
- std::array ids;
- std::array hitIndexs;
-
- // -- this is the output of the fit
- std::array qps;
- std::array chi2TTs;
- std::array xTTs;
- std::array xSlopeTTs;
- std::array ys;
-
+ struct X : Event::floats_field<4> {};
+ struct Z : Event::floats_field<4> {};
+ struct Weight : Event::floats_field<4> {};
+ struct Sin : Event::floats_field<4> {};
+ struct ID : Event::ints_field<4> {};
+ struct HitIndex : Event::ints_field<4> {};
+ // fit output
+ struct QOverP : Event::float_field {};
+ struct Chi2 : Event::float_field {};
+ struct XOffset : Event::float_field {};
+ struct XSlope : Event::float_field {};
+ struct YSlope : Event::float_field {};
// -- and this the original state (in the Velo)
- std::array statePoss;
- std::array stateDirs;
- std::array ancestorIndexs;
-
+ struct VeloState : Event::pos_dir_field {};
// -- and this an index to find the hit containers
- std::array hitContIndexs;
-
- std::size_t size{0};
- SOA_ACCESSOR_VAR( x, &( xs[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( z, &( zs[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( weight, &( weightss[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( sin, &( sins[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( id, &( ids[pos * batchSize] ), int pos )
- SOA_ACCESSOR_VAR( hitIndex, &( hitIndexs[pos * batchSize] ), int pos )
-
- SOA_ACCESSOR( qp, qps.data() )
- SOA_ACCESSOR( chi2TT, chi2TTs.data() )
- SOA_ACCESSOR( xTT, xTTs.data() )
- SOA_ACCESSOR( xSlopeTT, xSlopeTTs.data() )
- SOA_ACCESSOR( y, ys.data() )
-
- SOA_ACCESSOR( ancestorIndex, ancestorIndexs.data() )
- SOA_ACCESSOR( hitContIndex, hitContIndexs.data() )
- VEC3_SOA_ACCESSOR( pos, (float*)&( statePoss[0] ), (float*)&( statePoss[batchSize] ),
- (float*)&( statePoss[2 * batchSize] ) )
- VEC3_XY_SOA_ACCESSOR( dir, (float*)&( stateDirs[0] ), (float*)&( stateDirs[batchSize] ), 1.0f )
-
- SOA_ACCESSOR( wb, wbs.data() )
- SOA_ACCESSOR( xMidField, xMidFields.data() )
- SOA_ACCESSOR( invKinkVeloDist, invKinkVeloDists.data() )
-
- void initTracks( int indexVal, float maxPseudoChi2 ) {
- hitIndexs.fill( indexVal );
- chi2TTs.fill( maxPseudoChi2 );
- size = 0;
- }
-
- template
- void fillHelperParams( Vec3 pos, Vec3 dir, const float zKink,
- const float sigmaVeloSlope ) {
+ struct Ancestor : Event::int_field {};
+ struct HitIndexContainer : Event::int_field {};
- using F = typename dType::float_v;
-
- F( pos.x + dir.x * ( zKink - pos.z ) ).store( xMidFields.data() );
- F a = sigmaVeloSlope * ( zKink - pos.z );
- F( 1.0f / ( a * a ) ).store( wbs.data() );
- F( 1.0f / ( zKink - pos.z ) ).store( invKinkVeloDists.data() );
- }
+ template
+ using prototrack_t =
+ Event::SOACollection;
+ };
- template
- void storeSimpleFitInfo( typename dType::float_v chi2TT, typename dType::float_v qp, typename dType::float_v xTT,
- typename dType::float_v xSlopeTT, unsigned int trackIndex ) {
+ struct ProtoTracks : ProtoTrackTag::prototrack_t {
+ using base_t = typename ProtoTrackTag::prototrack_t;
+ using base_t::allocator_type;
+ using base_t::base_t;
- using F = typename dType::float_v;
+ template
+ struct ProtoTrackProxy : Event::Proxy {
+ using base_t = typename Event::Proxy;
+ using base_t::base_t;
+ auto isInvalid() const { return this->template field( 0 ).get() == -1; }
+ };
- F( chi2TT ).store( &chi2TTs[trackIndex] );
- F( qp ).store( &qps[trackIndex] );
- F( xTT ).store( &xTTs[trackIndex] );
- F( xSlopeTT ).store( &xSlopeTTs[trackIndex] );
- }
+ template
+ using proxy_type = ProtoTrackProxy;
+ };
- // -- this runs over all 4 layers, even if no hit was found
- // -- but it fills a weight of 0
- // -- Note: These are not "physical" layers, as the hits are ordered such that only
- // -- the last one can be not filled.
- template
- void fillHitInfo( const LHCb::Event::Zip& hitsInL,
- unsigned int trackIndex ) {
-
- using F = typename dType::float_v;
- using I = typename dType::int_v;
- auto nValid{0};
- if ( hitsInL.size() != 0 ) {
- for ( int i = 0; i < totalUTLayers; ++i ) {
- int hitI = hitIndexs[trackIndex + i * batchSize];
- const auto valid = ( hitI != -1 );
- const auto weight = valid ? hitsInL[hitI].weight().cast() : 0.0f;
- nValid += valid;
- hitI = std::max( 0, hitI );
- LHCb::LHCbID id( LHCb::Detector::UT::ChannelID( hitsInL[hitI].channelID().cast() ) );
-
- F( weight ).store( &weightss[trackIndex + i * batchSize] );
- F( hitsInL[hitI].x() ).store( &xs[trackIndex + i * batchSize] );
- F( hitsInL[hitI].z() ).store( &zs[trackIndex + i * batchSize] );
- F( hitsInL[hitI].sin() ).store( &sins[trackIndex + i * batchSize] );
- I( hitsInL[hitI].index() ).store( &hitIndexs[trackIndex + i * batchSize] );
- I( id.lhcbID() ).store( &ids[trackIndex + i * batchSize] );
- }
- }
- // this is useful in filterMode
- if ( !nValid ) { F( nanMomentum ).store( &qps[trackIndex] ); }
- }
+ struct VeloState {
+ float x, y, z, tx, ty;
};
struct VeloUTGeomCache {
@@ -215,49 +155,48 @@ namespace LHCb::Pr::VeloUT {
}
// perform a fit using trackhelper's best hits with y correction, improve qop estimate
- simd::float_v fastfitterSIMD( std::array& improvedParams, const ProtoTracks& protoTracks,
- const float zMidUT, const simd::float_v qpxz2p, const int t,
- simd::mask_v& goodFitMask ) {
+ template
+ simd::float_v fastfitterSIMD( std::array& improvedParams, Proxy pTrack, const float zMidUT,
+ const simd::float_v qpxz2p, simd::mask_v& goodFitMask ) {
// -- parameters that describe the z position of the kink point as a function of ty in a 4th order polynomial
// (even
// terms only)
- constexpr auto magFieldParams = std::array{2010.0f, -2240.0f, -71330.f};
- const Vec3 pos = protoTracks.pos( t );
- const Vec3 dir = protoTracks.dir( t );
-
- const simd::float_v x = pos.x;
- const simd::float_v y = pos.y;
- const simd::float_v z = pos.z;
- const simd::float_v tx = dir.x;
- const simd::float_v ty = dir.y;
- const simd::float_v zKink =
- magFieldParams[0] - ty * ty * magFieldParams[1] - ty * ty * ty * ty * magFieldParams[2];
- const simd::float_v xMidField = x + tx * ( zKink - z );
-
- const simd::float_v zDiff = 0.001f * ( zKink - zMidUT );
+ constexpr auto magFieldParams = std::array{2010.0f, -2240.0f, -71330.f};
+ const auto ty = pTrack.template field().ty();
+ const auto tx = pTrack.template field().tx();
+ const auto z = pTrack.template field().z();
+ const auto y = pTrack.template field().y();
+ const auto x = pTrack.template field().x();
+ const auto ty2 = ty * ty;
+ const auto zKink = magFieldParams[0] - ty2 * magFieldParams[1] - ty2 * ty2 * magFieldParams[2];
+ const auto xMidField = x + tx * ( zKink - z );
+ const auto zDiff = 0.001f * ( zKink - zMidUT );
// -- This is to avoid division by zero...
- const simd::float_v pHelper = max( abs( protoTracks.qp( t ) * qpxz2p ), 1e-9f );
- const simd::float_v invP = pHelper * 1.f / sqrt( 1.0f + ty * ty );
+ const auto qop = pTrack.template field().get();
+ const auto pHelper = max( abs( qop * qpxz2p ), 1e-9f );
+ const auto invP = pHelper * 1.f / sqrt( 1.0f + ty2 );
// these resolution are semi-empirical, could be tuned and might not be correct for low momentum.
- const simd::float_v error1 =
- 0.14f + 10000.0f * invP; // this is the resolution due to multiple scattering between Velo and UT
- const simd::float_v error2 = 0.12f + 3000.0f * invP; // this is the resolution due to the finite Velo resolution
- const simd::float_v error = error1 * error1 + error2 * error2;
- const simd::float_v weight = 1.0f / error;
+ // this is the resolution due to multiple scattering between Velo and UT
+ const auto error1 = 0.14f + 10000.0f * invP;
+ // this is the resolution due to the finite Velo resolution
+ const auto error2 = 0.12f + 3000.0f * invP;
+
+ const auto error = error1 * error1 + error2 * error2;
+ const auto weight = 1.0f / error;
std::array mat = {weight, weight * zDiff, weight * zDiff * zDiff, 0.0f, 0.0f, 0.0f};
std::array rhs = {weight * xMidField, weight * xMidField * zDiff, 0.0f};
- for ( int i = 0; i < 4; ++i ) {
+ for ( int i = 0; i < totalUTLayers; ++i ) {
// -- there are 3-hit candidates, but we'll
// -- just treat them like 4-hit candidates
// -- with 0 weight for the last hit
- const simd::float_v ui = protoTracks.x( t, i );
- const simd::float_v dz = 0.001f * ( protoTracks.z( t, i ) - zMidUT );
- const simd::float_v w = protoTracks.weight( t, i );
- const simd::float_v ta = protoTracks.sin( t, i );
+ const auto ui = pTrack.template field( i ).get();
+ const auto dz = 0.001f * ( pTrack.template field( i ).get() - zMidUT );
+ const auto w = pTrack.template field( i ).get();
+ const auto ta = pTrack.template field( i ).get();
mat[0] += w;
mat[1] += w * dz;
mat[2] += w * dz * dz;
@@ -268,46 +207,43 @@ namespace LHCb::Pr::VeloUT {
rhs[1] += w * ui * dz;
rhs[2] += w * ui * ta;
}
-
+ // TODO: this is overkill for dimension 3, vanilla matrix inversion should be fine
goodFitMask = !CholeskyDecomposition3( mat, rhs );
- const simd::float_v xUTFit = rhs[0];
- const simd::float_v xSlopeUTFit = 0.001f * rhs[1];
- const simd::float_v offsetY = rhs[2];
+ const auto xUTFit = rhs[0];
+ const auto xSlopeUTFit = 0.001f * rhs[1];
+ const auto offsetY = rhs[2];
- const simd::float_v distX = ( xMidField - xUTFit - xSlopeUTFit * ( zKink - zMidUT ) );
+ const auto distX = xMidField - xUTFit - xSlopeUTFit * ( zKink - zMidUT );
// -- This takes into account that the distance between a point and track is smaller than the distance on the
// x-axis
- const simd::float_v distCorrectionX2 = 1.0f / ( 1 + xSlopeUTFit * xSlopeUTFit );
- simd::float_v chi2 = weight * ( distX * distX * distCorrectionX2 + offsetY * offsetY / ( 1.0f + ty * ty ) );
-
- for ( int i = 0; i < 4; ++i ) {
-
- const simd::float_v dz = protoTracks.z( t, i ) - zMidUT;
- const simd::float_v w = protoTracks.weight( t, i );
- const simd::float_v dist = ( protoTracks.x( t, i ) - xUTFit - xSlopeUTFit * dz -
- offsetY * protoTracks.sin( t, i ) );
-
+ const auto distCorrectionX2 = 1.0f / ( 1 + xSlopeUTFit * xSlopeUTFit );
+ auto chi2 = weight * ( distX * distX * distCorrectionX2 + offsetY * offsetY / ( 1.0f + ty2 ) );
+ for ( int i = 0; i < totalUTLayers; ++i ) {
+ const auto dz = pTrack.template field( i ).get() - zMidUT;
+ const auto w = pTrack.template field( i ).get();
+ const auto x = pTrack.template field( i ).get();
+ const auto sin = pTrack.template field( i ).get();
+ const auto dist = x - xUTFit - xSlopeUTFit * dz - offsetY * sin;
chi2 += w * dist * dist * distCorrectionX2;
}
// new VELO slope x
- const simd::float_v xb =
- 0.5f * ( ( xUTFit + xSlopeUTFit * ( zKink - zMidUT ) ) + xMidField ); // the 0.5 is empirical
- const simd::float_v xSlopeVeloFit = ( xb - x ) / ( zKink - z );
+ const auto xb = 0.5f * ( ( xUTFit + xSlopeUTFit * ( zKink - zMidUT ) ) + xMidField ); // the 0.5 is empirical
+ const auto xSlopeVeloFit = ( xb - x ) / ( zKink - z );
improvedParams = {xUTFit, xSlopeUTFit, y + ty * ( zMidUT - z ) + offsetY, chi2};
// calculate q/p
- const simd::float_v sinInX = xSlopeVeloFit / sqrt( 1.0f + xSlopeVeloFit * xSlopeVeloFit + ty * ty );
- const simd::float_v sinOutX = xSlopeUTFit / sqrt( 1.0f + xSlopeUTFit * xSlopeUTFit + ty * ty );
+ const auto sinInX = xSlopeVeloFit / sqrt( 1.0f + xSlopeVeloFit * xSlopeVeloFit + ty2 );
+ const auto sinOutX = xSlopeUTFit / sqrt( 1.0f + xSlopeUTFit * xSlopeUTFit + ty2 );
return ( sinInX - sinOutX );
}
// -- Evaluate the linear discriminant
// -- Coefficients derived with LD method for p, pT and chi2 with TMVA
template
- simd::float_v evaluateLinearDiscriminantSIMD( const std::array& inputValues ) {
+ simd::float_v evaluateLinearDiscriminantSIMD( std::array inputValues ) {
constexpr auto coeffs =
( nHits == 3 ? std::array{0.162880166064f, -0.107081172665f, 0.134153123662f, -0.137764853657f}
@@ -343,7 +279,7 @@ namespace LHCb::Pr::VeloUT {
}
// --------------------------------------------------------------------
- // -- These things are all hardcopied from the PrTableForFunction
+ // -- TODO: These things are all hardcopied from the PrTableForFunction
// -- and PrUTMagnetTool
// -- If the granularity or whatever changes, this will give wrong results
simd::int_v masterIndexSIMD( const simd::int_v index1, const simd::int_v index2, const simd::int_v index3 ) {
@@ -354,8 +290,7 @@ namespace LHCb::Pr::VeloUT {
// -- 2 helper functions for fit
// -- Pseudo chi2 fit, templated for 3 or 4 hits
// ===========================================================================================
- inline __attribute__( ( always_inline ) ) void
- addHit( span mat, span rhs, const LHCb::Pr::UT::Mut::Hits& hits, int index, float zMidUT ) {
+ void addHit( span mat, span rhs, const UT::Mut::Hits& hits, int index, float zMidUT ) {
const auto& hit = hits.scalar()[index];
const float ui = hit.x().cast();
const float ci = hit.cos().cast();
@@ -368,28 +303,27 @@ namespace LHCb::Pr::VeloUT {
rhs[1] += wi * ui * dz;
}
- template
- inline __attribute__( ( always_inline ) ) void
- simpleFit( const std::array& indices, const LHCb::Pr::UT::Mut::Hits& hits, ProtoTracks& pTracks,
- const int trackIndex, float zMidUT, float zKink, float invSigmaVeloSlope ) {
+ template
+ [[gnu::always_inline]] inline void simpleFit( const std::array& indices, const UT::Mut::Hits& hits,
+ Proxy pTrack, float zMidUT, float zKink, float invSigmaVeloSlope ) {
static_assert( N == 3 || N == 4 );
// -- Scale the z-component, to not run into numerical problems
// -- with floats
- const float wb = pTracks.wb( 0 ).cast();
- const float xMidField = pTracks.xMidField( 0 ).cast();
- const float invKinkVeloDist = pTracks.invKinkVeloDist( 0 ).cast();
- const float stateX = pTracks.pos