Skip to content
Snippets Groups Projects
Commit ade5e610 authored by Hangyi Wu's avatar Hangyi Wu Committed by Andre Gunther
Browse files

UThit position methods

parent e910d163
No related branches found
No related tags found
1 merge request!4269UThit position methods
......@@ -27,7 +27,8 @@ namespace UT {
public:
// constructor
Hit( LHCb::Detector::UT::ChannelID chanID, unsigned int size, bool highThreshold, double dxDy, double xat0,
double zat0, double yBegin, double yEnd, double cos, double error, unsigned int strip, double fracStrip )
double zat0, double yBegin, double yEnd, double cos, double error, unsigned int strip, double fracStrip,
unsigned int clusterCharge )
: m_cos( cos )
, m_dxDy( dxDy )
, m_weight( 1. / error )
......@@ -40,7 +41,8 @@ namespace UT {
, m_size( size )
, m_highThreshold( highThreshold )
, m_strip( strip )
, m_fracStrip( fracStrip ) {}
, m_fracStrip( fracStrip )
, m_clusterCharge( clusterCharge ) {}
[[nodiscard]] float cos() const { return m_cos; }
[[nodiscard]] float cosT() const {
......@@ -75,7 +77,8 @@ namespace UT {
[[nodiscard]] float yMin() const { return std::min( yBegin(), yEnd() ); }
[[nodiscard]] float zAtYEq0() const { return m_zAtYEq0; }
[[nodiscard]] unsigned int strip() const { return m_strip; }
[[nodiscard]] double fracStrip() const { return m_fracStrip; }
[[nodiscard]] float fracStrip() const { return m_fracStrip; }
[[nodiscard]] unsigned int clusterCharge() const { return m_clusterCharge; }
[[nodiscard]] int pseudoSize() const {
unsigned int cSize = m_size + 1;
if ( cSize == 1 ) {
......@@ -99,7 +102,8 @@ namespace UT {
unsigned int m_size;
bool m_highThreshold;
unsigned int m_strip;
double m_fracStrip;
float m_fracStrip;
unsigned int m_clusterCharge;
};
using Hits = std::vector<const Hit*>;
......
......@@ -38,9 +38,13 @@ namespace LHCb::Pr::UT {
struct zAtYEq0 : Event::float_field {};
struct dxDy : Event::float_field {};
struct cos : Event::float_field {};
struct fracStrip : Event::float_field {};
struct clusterSize : Event::int_field {};
struct clusterCharge : Event::int_field {};
template <typename T>
using uthit_t = Event::SOACollection<T, channelID, weight, xAtYEq0, yBegin, yEnd, zAtYEq0, dxDy, cos>;
using uthit_t = Event::SOACollection<T, channelID, weight, xAtYEq0, yBegin, yEnd, zAtYEq0, dxDy, cos, fracStrip,
clusterSize, clusterCharge>;
} // namespace UTHitsTag
namespace details {
......@@ -52,7 +56,8 @@ namespace LHCb::Pr::UT {
// Method to add Hit in the container
// This should be changed to float, but needs an adaptation of "DeUTSector"
void emplace_back( const DeUTSector& aSector, unsigned int fullChanIdx, unsigned int strip, double fracStrip,
LHCb::Detector::UT::ChannelID chanID, unsigned int /*size*/, bool /*highThreshold*/ ) {
LHCb::Detector::UT::ChannelID chanID, unsigned int clusterSize, bool /*highThreshold*/,
unsigned int clusterCharge ) {
double dxDy{0};
double dzDy{0};
double xAtYEq0{0};
......@@ -60,8 +65,7 @@ namespace LHCb::Pr::UT {
double yBegin{0};
double yEnd{0};
//--- this method allow to set the values
const auto fracStripOvfour = fracStrip / 4;
aSector.trajectory( strip, fracStripOvfour, dxDy, dzDy, xAtYEq0, zAtYEq0, yBegin, yEnd );
aSector.trajectory( strip, fracStrip, dxDy, dzDy, xAtYEq0, zAtYEq0, yBegin, yEnd );
const auto cos = aSector.cosAngle();
// -- should this not depend on the cluster size?
const auto pitch = aSector.pitch();
......@@ -98,6 +102,9 @@ namespace LHCb::Pr::UT {
proxy.field<UTHitsTag::yEnd>().set( (float)yEnd );
proxy.field<UTHitsTag::cos>().set( (float)cos );
proxy.field<UTHitsTag::dxDy>().set( (float)dxDy );
proxy.field<UTHitsTag::fracStrip>().set( (float)fracStrip );
proxy.field<UTHitsTag::clusterSize>().set( (int)clusterSize );
proxy.field<UTHitsTag::clusterCharge>().set( (int)clusterCharge );
// increment the end index for current range
++( indices.second );
......@@ -117,6 +124,9 @@ namespace LHCb::Pr::UT {
store<UTHitsTag::yEnd>( size(), simd::float_v{1e6f} );
store<UTHitsTag::cos>( size(), simd::float_v{1e6f} );
store<UTHitsTag::dxDy>( size(), simd::float_v{1e6f} );
store<UTHitsTag::fracStrip>( size(), simd::float_v{1e6f} );
store<UTHitsTag::clusterSize>( size(), simd::int_v{1} );
store<UTHitsTag::clusterCharge>( size(), simd::int_v{1} );
}
// TODO: isn't there a function for that?
......@@ -140,6 +150,9 @@ namespace LHCb::Pr::UT {
proxy.field<UTHitsTag::yEnd>().set( ahits[at].get<UTHitsTag::yEnd>() );
proxy.field<UTHitsTag::cos>().set( ahits[at].get<UTHitsTag::cos>() );
proxy.field<UTHitsTag::dxDy>().set( ahits[at].get<UTHitsTag::dxDy>() );
proxy.field<UTHitsTag::fracStrip>().set( ahits[at].get<UTHitsTag::fracStrip>() );
proxy.field<UTHitsTag::clusterSize>().set( ahits[at].get<UTHitsTag::clusterSize>() );
proxy.field<UTHitsTag::clusterCharge>().set( ahits[at].get<UTHitsTag::clusterCharge>() );
++( indices.second );
}
......
......@@ -72,6 +72,7 @@ class UTDecoder<UTDAQ::version::v5> final {
}
public:
enum class PositionMethod { MaxAdc = 0, AdcWeighting, GeoWeighting };
explicit UTDecoder( const LHCb::RawBank& bank )
: UTDecoder{bank.range<uint16_t>().subspan( 4 ), bank.range<uint32_t>().first<2>()} {
assert( UTDAQ::version{bank.version()} == UTDAQ::version::v5 );
......@@ -148,8 +149,8 @@ public:
const LHCb::span<const uint16_t> m_bank;
UTDAQ::digiVec m_Digit;
struct Sentinel final {};
bool m_isWeight; // True: ADC weighted position, otherwise center of the strip with maximal ADC
unsigned int m_stripMax; // strip with highest number of ADC
PositionMethod m_positionMethod;
unsigned int m_stripMax; // strip with highest number of ADC
class Iterator final {
const LHCb::span<const uint16_t> m_bank;
......@@ -158,8 +159,8 @@ public:
unsigned int m_pos = 0;
unsigned int m_maxpos = 0;
unsigned int m_pos_nextBegin = 0;
double m_fracStrip = 0.;
bool m_isWeight;
float m_fracStrip = 0.;
PositionMethod m_positionMethod;
unsigned int m_stripMax;
unsigned int m_clusterSize = 0;
unsigned int m_clusterCharge = 0;
......@@ -176,8 +177,9 @@ public:
return pos + ( ( pos % 2 ) ? static_cast<unsigned int>( banksize::right_bit ) : 1u );
}
bool keepClustering() {
unsigned int Optpos = m_pos, maxAdc = adcValue( m_pos ), cstrip = strip( m_pos );
unsigned int adccount( maxAdc ), Optpos_cal( cstrip * adccount ), numstrip( 1u );
unsigned int Optpos = m_pos, maxAdc = adcValue( m_pos ), cstrip = strip( m_pos );
unsigned int adccount( maxAdc ), numstrip( 1u );
unsigned int Optpos_cal = ( m_positionMethod == PositionMethod::GeoWeighting ? cstrip : ( cstrip * adccount ) );
std::map<unsigned int, unsigned int> posvector;
posvector.emplace( cstrip, m_pos );
while ( true ) {
......@@ -191,19 +193,26 @@ public:
maxAdc = adcvalue;
Optpos = m_pos;
}
if ( m_isWeight ) { // perform weightening if it is requested
posvector.emplace( cstrip, m_pos );
Optpos_cal += cstrip * adcvalue;
}
if ( m_positionMethod != PositionMethod::MaxAdc ) posvector.emplace( cstrip, m_pos );
Optpos_cal += ( m_positionMethod == PositionMethod::AdcWeighting ? cstrip * adcvalue : cstrip );
adccount += adcvalue;
}
if ( numstrip <= m_stripMax ) {
if ( m_isWeight && adccount > 0 ) {
unsigned int istrip = floor( static_cast<double>( Optpos_cal ) / static_cast<double>( adccount ) +
0.5 ); // get weighted strip position
m_fracStrip = static_cast<double>( Optpos_cal ) / static_cast<double>( adccount ) - istrip;
auto iter = posvector.find( istrip );
if ( iter != posvector.end() ) Optpos = iter->second;
m_fracStrip = 0; // strip center
if ( numstrip > 1 ) {
if ( m_positionMethod >= PositionMethod::GeoWeighting ) {
unsigned int istrip = floor( static_cast<float>( Optpos_cal ) / static_cast<float>( numstrip ) +
0.5 ); // get weighted strip position
m_fracStrip = static_cast<float>( Optpos_cal ) / static_cast<float>( numstrip ) - istrip;
auto iter = posvector.find( istrip );
if ( iter != posvector.end() ) Optpos = iter->second;
} else if ( m_positionMethod == PositionMethod::AdcWeighting && adccount > 0 ) {
unsigned int istrip = floor( static_cast<float>( Optpos_cal ) / static_cast<float>( adccount ) +
0.5 ); // get weighted strip position
m_fracStrip = static_cast<float>( Optpos_cal ) / static_cast<float>( adccount ) - istrip;
auto iter = posvector.find( istrip );
if ( iter != posvector.end() ) Optpos = iter->second;
}
}
m_pos_nextBegin = std::exchange( m_pos, Optpos ); // if size of the cluster is below maximal value -> accept
m_clusterSize = numstrip;
......@@ -216,9 +225,9 @@ public:
}
public:
Iterator( LHCb::span<const uint16_t> bank, const UTDAQ::digiVec m_Digit, const bool iWeighted,
Iterator( LHCb::span<const uint16_t> bank, const UTDAQ::digiVec m_Digit, PositionMethod positionMethod,
const unsigned int stripMax )
: m_bank{bank}, m_iterDigit{m_Digit}, m_isWeight{iWeighted}, m_stripMax{stripMax} {
: m_bank{bank}, m_iterDigit{m_Digit}, m_positionMethod{positionMethod}, m_stripMax{stripMax} {
auto PosLane =
std::find_if( m_iterDigit.begin(), m_iterDigit.end(), []( unsigned int element ) { return element != 0; } );
if ( PosLane != m_iterDigit.end() ) {
......@@ -279,10 +288,10 @@ public:
};
public:
constexpr posadc_range( LHCb::span<const uint16_t> bank, const UTDAQ::digiVec& ClusterVec, bool isWeight,
unsigned int stripMax )
: m_bank{std::move( bank )}, m_Digit{ClusterVec}, m_isWeight{isWeight}, m_stripMax{stripMax} {}
[[nodiscard]] auto begin() const { return Iterator{m_bank, m_Digit, m_isWeight, m_stripMax}; }
constexpr posadc_range( LHCb::span<const uint16_t> bank, const UTDAQ::digiVec& ClusterVec,
PositionMethod positionMethod, unsigned int stripMax )
: m_bank{std::move( bank )}, m_Digit{ClusterVec}, m_positionMethod{positionMethod}, m_stripMax{stripMax} {}
[[nodiscard]] auto begin() const { return Iterator{m_bank, m_Digit, m_positionMethod, m_stripMax}; }
[[nodiscard]] constexpr auto end() const { return Sentinel{}; }
};
......@@ -294,10 +303,42 @@ public:
[[nodiscard]] constexpr unsigned int getflags() const { return m_header[0]; }
[[nodiscard]] constexpr unsigned int getBXID() const { return m_header[1]; }
[[nodiscard]] auto posRange() const {
// last ADC word in UTTell40 ZS RawBank, it is organized in 16 words long rows (2 ADC words per LANE). First 4
// words in the row are header, thus subtracted
return pos_range{m_bank.first( ( ( nClusters() + 1 ) / 2 ) * 16 - 4 ), m_nDigits};
}
[[nodiscard]] auto posAdcRange( bool isMax, unsigned int stripMax = 252 ) const {
return posadc_range{m_bank.first( ( ( nClusters() + 1 ) / 2 ) * 16 - 4 ), m_nDigits, isMax, stripMax};
[[nodiscard]] auto posAdcRange( PositionMethod positionMethod = PositionMethod::GeoWeighting,
unsigned int stripMax = 252 ) const {
return posadc_range{m_bank.first( ( ( nClusters() + 1 ) / 2 ) * 16 - 4 ), m_nDigits, positionMethod, stripMax};
}
friend std::string toString( PositionMethod e ) {
switch ( e ) {
case PositionMethod::MaxAdc:
return "MaxAdc";
case PositionMethod::AdcWeighting:
return "AdcWeighting";
case PositionMethod::GeoWeighting:
return "GeoWeighting";
}
};
friend std::ostream& toStream( PositionMethod e, std::ostream& os ) {
return os << std::quoted( toString( e ), '\'' );
}
friend std::ostream& operator<<( std::ostream& s, PositionMethod e ) { return toStream( e, s ); }
friend StatusCode parse( PositionMethod& result, std::string_view input ) {
if ( ( input.front() == '"' || input.back() == '\'' ) && input.front() == input.back() ) {
input.remove_prefix( 1 );
input.remove_suffix( 1 );
}
for ( PositionMethod m : {PositionMethod::MaxAdc, PositionMethod::AdcWeighting, PositionMethod::GeoWeighting} ) {
if ( input == toString( m ) ) {
result = m;
return StatusCode::SUCCESS;
}
}
return StatusCode::FAILURE;
}
private:
......@@ -308,6 +349,8 @@ private:
template <>
class UTDecoder<UTDAQ::version::v2> final {
using PositionMethod = UTDecoder<UTDAQ::version::v5>::PositionMethod;
public:
explicit UTDecoder( const LHCb::RawBank& bank ) {
assert( UTDAQ::version{bank.version()} == UTDAQ::version::v2 );
......@@ -325,8 +368,8 @@ public:
return m_v5decoder->nClusters( laneID );
}
[[nodiscard]] auto posRange() const { return m_v5decoder->posRange(); }
[[nodiscard]] auto posAdcRange( bool isMax, unsigned int stripMax = 252 ) const {
return m_v5decoder->posAdcRange( isMax, stripMax );
[[nodiscard]] auto posAdcRange( PositionMethod positionMethod, unsigned int stripMax = 252 ) const {
return m_v5decoder->posAdcRange( positionMethod, stripMax );
}
[[nodiscard]] constexpr unsigned int getflags() const { return m_v5decoder->getflags(); }
[[nodiscard]] constexpr unsigned int getBXID() const { return m_v5decoder->getBXID(); }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment