ATLAS Offline Software
Loading...
Searching...
No Matches
DeltaRMatchingTool.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5/**
6 * @file DeltaRMatchingTool.icc
7 * @author Marco Aparo, Thomas Strebler
8 **/
9
10/// local includes
11#include "TrackMatchingLookup.h"
12#include "TrackParametersHelper.h"
13
14/// STL include(s)
15#include <cmath> // std::fabs
16#include <algorithm> // for std::sort, std::lower_bound, std::upper_bound, std::set_intersection
17#include <iterator> // std::back_inserter
18
19
20/// ------------------------
21/// ----- matchVectors -----
22/// ------------------------
23template< typename T, typename R >
24StatusCode IDTPM::DeltaRMatchingToolBase<T, R>::matchVectors(
25 const std::vector< const T* >& vTest,
26 const std::vector< const R* >& vRef,
27 ITrackMatchingLookup& matches ) const
28{
29 for( const T* t : vTest ) {
30 /// Skip invalid test
31 if( not t ) continue;
32
33 /// intialising large distance
34 float dist(999.);
35
36 /// Find matched reference
37 const R* r = getMatchedRef( *t, vRef, dist );
38
39 /// Skip if no reference is found
40 if( not r ) continue;
41
42 ATH_MSG_DEBUG( "Found matched reference with pT = " << pT(*r) <<
43 " with dist = " << dist );
44
45 /// Updating lookup table with new match
46 ATH_CHECK( matches.update( *t, *r, dist ) );
47 } // loop over vTest
48
49 return StatusCode::SUCCESS;
50}
51
52
53/// -------------------------
54/// ----- getMatchedRef -----
55/// -------------------------
56template< typename T, typename R >
57const R* IDTPM::DeltaRMatchingToolBase<T, R>::getMatchedRef(
58 const T& t, const std::vector< const R* >& vRef, float& dist ) const
59{
60 ATH_MSG_DEBUG( "Reference vector size before sorting = " << vRef.size() );
61
62 /// Initially making copies of the whole reference vector
63 std::vector< const R* > vec_pt( vRef );
64 std::vector< const R* > vec_eta( vRef );
65 std::vector< const R* > vec_phi( vRef );
66
67 /// Sorting vec_pt by increasing pT
68 std::sort( vec_pt.begin(), vec_pt.end(),
69 []( const R* r1, const R* r2 ) -> bool{
70 return ( pT(*r1) < pT(*r2) ); } );
71
72 /// Sorting vec_eta by increasing eta
73 std::sort( vec_eta.begin(), vec_eta.end(),
74 []( const R* r1, const R* r2 ) -> bool{
75 return ( eta(*r1) < eta(*r2) ); } );
76
77 /// Sorting vec_phi by increasing phi
78 std::sort( vec_phi.begin(), vec_phi.end(),
79 []( const R* r1, const R* r2 ) -> bool{
80 return ( phi(*r1) < phi(*r2) ); } );
81
82 ATH_MSG_DEBUG( "Reference vector size after pT sorting = " << vec_pt.size() );
83 ATH_MSG_DEBUG( "Reference vector size after eta sorting = " << vec_eta.size() );
84 ATH_MSG_DEBUG( "Reference vector size after phi sorting = " << vec_phi.size() );
85
86 /// Perform search in reference vectors to select the references
87 /// in the [eta(t)-dR, eta(t)+dR], [phi(t)-dR, phi(t)+dR] ranges
88 /// and, if applicable, in the [pT(t)*(1-pTres),pT(t)*(1+pTres)] range
89 typename std::vector< const R* >::iterator it_pt_lower =
90 m_pTResMax < 0 ? vec_pt.begin() :
91 std::lower_bound( vec_pt.begin(), vec_pt.end(),
92 pT(t) * ( 1. - m_pTResMax ),
93 []( const R* r, const float& val ) -> bool{
94 return pT(*r) < val; } );
95
96 typename std::vector< const R* >::iterator it_pt_upper =
97 m_pTResMax < 0 ? vec_pt.end() :
98 std::upper_bound( vec_pt.begin(), vec_pt.end(),
99 pT(t) * ( 1. + m_pTResMax ),
100 []( const float& val, const R* r ) -> bool{
101 return val < pT(*r); } );
102
103 typename std::vector< const R* >::iterator it_eta_lower =
104 m_dRmax < 0 ? vec_eta.begin() :
105 std::lower_bound( vec_eta.begin(), vec_eta.end(),
106 eta(t) - m_dRmax,
107 []( const R* r, const float& val ) -> bool{
108 return eta(*r) < val; } );
109
110 typename std::vector< const R* >::iterator it_eta_upper =
111 m_dRmax < 0 ? vec_eta.end() :
112 std::upper_bound( vec_eta.begin(), vec_eta.end(),
113 eta(t) + m_dRmax,
114 []( const float& val, const R* r ) -> bool{
115 return val < eta(*r); } );
116
117 /// Dealing with cyclic nature of phi:
118 /// Determining whether phi range wraps around +-PI
119 bool wrapLow = phi(t) - m_dRmax < -M_PI;
120 bool wrapHigh = phi(t) + m_dRmax > M_PI;
121 bool wrap = wrapLow or wrapHigh;
122
123 typename std::vector< const R* >::iterator it_phi_lower =
124 m_dRmax < 0 ? vec_phi.begin() :
125 std::lower_bound( vec_phi.begin(), vec_phi.end(),
126 phi(t) - m_dRmax + ( wrapLow ? 2.*M_PI : 0 ),
127 []( const R* r, const float& val ) -> bool{
128 return phi(*r) < val; } );
129
130 typename std::vector< const R* >::iterator it_phi_upper =
131 m_dRmax < 0 ? vec_phi.end() :
132 std::upper_bound( vec_phi.begin(), vec_phi.end(),
133 phi(t) + m_dRmax + ( wrapHigh ? -2.*M_PI : 0 ),
134 []( const float& val, const R* r ) -> bool{
135 return val < phi(*r); } );
136
137 /// Break early if no reference track passed the selection
138 if( m_pTResMax > 0 and it_pt_upper < it_pt_lower ) {
139 ATH_MSG_DEBUG( "Break early: out of pTres range" );
140 return nullptr;
141 }
142
143 if( m_dRmax > 0 and it_eta_upper < it_eta_lower ) {
144 ATH_MSG_DEBUG( "Break early: out of eta range" );
145 return nullptr;
146 }
147
148 if( m_dRmax > 0 and ( ( !wrap and it_phi_upper < it_phi_lower ) or
149 ( wrap and it_phi_upper > it_phi_lower ) ) ) {
150 ATH_MSG_DEBUG( "Break early: out of phi range" );
151 return nullptr;
152 }
153
154 /// Initialise base set
155 std::vector< const R* > set( vec_pt );
156
157 /// Sort, pointer-based; necessary for set_intersection
158 std::sort( set.begin(), set.end() );
159
160 /// Compute subset of selected truth particles
161 std::vector< const R* > subset_pt( it_pt_lower, it_pt_upper );
162 std::vector< const R* > subset_eta( it_eta_lower, it_eta_upper );
163 std::vector< const R* > subset_phi;
164 if( !wrap ) {
165 subset_phi = std::vector< const R* >( it_phi_lower, it_phi_upper );
166 } else {
167 subset_phi = std::vector< const R* >( vec_phi.begin(), it_phi_upper );
168 subset_phi.insert( subset_phi.end(), it_phi_lower, vec_phi.end() );
169 }
170
171 ATH_MSG_DEBUG( "Reference vector subset_pt size = " << subset_pt.size() );
172 ATH_MSG_DEBUG( "Reference vector subset_eta size = " << subset_eta.size() );
173 ATH_MSG_DEBUG( "Reference vector subset_phi size = " << subset_phi.size() );
174
175 /// Add subsets according to specified cut values
176 std::vector< std::vector< const R* > > subsets;
177 if( m_pTResMax > 0 ) {
178 subsets.push_back( subset_pt );
179 }
180 if( m_dRmax > 0 ) {
181 subsets.push_back( subset_eta );
182 subsets.push_back( subset_phi );
183 }
184
185 /// Compute successive intersections between base set and subset
186 for( std::vector< const R* > subset : subsets ) {
187
188 /// -- Sort, pointer-based; necessary for set::set_intersection
189 std::sort( subset.begin(), subset.end() );
190
191 /// -- Set intersection
192 std::vector< const R* > intersection;
193 std::set_intersection(
194 set.begin(), set.end(),
195 subset.begin(), subset.end(),
196 std::back_inserter( intersection ) );
197
198 /// -- Break early if intersection is empty
199 if( intersection.empty() ) {
200 ATH_MSG_DEBUG( "Break early: empty intersection" );
201 return nullptr;
202 }
203 set = intersection;
204 }
205
206 /// vector "set" now contains all matched reference tracks
207 ATH_MSG_DEBUG( "Reference vector subsets intersection size = " << set.size() );
208 /// Now picking the best match...
209
210 /// If only pT-matching, return the closest track in pTres
211 if( m_dRmax < 0 ) {
212 int i_pTres_best(-1);
213 float pTres_best(999.);
214 for( size_t i=0 ; i<set.size() ; i++ ) {
215 float pTres_tmp =
216 std::fabs( pT(t) - pT( *(set.at(i)) ) ) / std::fabs( pT(t) );
217 if( pTres_tmp < pTres_best ) {
218 pTres_best = pTres_tmp;
219 i_pTres_best = i;
220 }
221 }
222 if( i_pTres_best < 0 ) return nullptr;
223 dist = pTres_best;
224 return set.at( i_pTres_best );
225 }
226
227 /// Otherwise, compute dR for all remaining reference tracks
228 /// and return the closest one in dR
229 int i_dR_best(-1);
230 float dR_best(999.);
231 for( size_t i=0 ; i<set.size() ; i++ ) {
232 float dR_tmp = deltaR( t, *(set.at(i)) );
233 if( dR_tmp < dR_best and dR_tmp < m_dRmax ) {
234 dR_best = dR_tmp;
235 i_dR_best = i;
236 }
237 }
238 if( i_dR_best < 0 ) return nullptr;
239 dist = dR_best;
240 return set.at(i_dR_best);
241}