ATLAS Offline Software
Loading...
Searching...
No Matches
TimeCompatibilityCheckAlg.cxx
Go to the documentation of this file.
1
10
12
17#include <cmath>
18
19namespace HGTD {
20
22 ISvcLocator* pSvcLocator)
23 : AthReentrantAlgorithm(name, pSvcLocator){}
24
26
27 ATH_CHECK(m_extensionTool.retrieve());
32 ATH_CHECK(m_layerClusterTimeKey.initialize());
37 ATH_CHECK(m_extrapXKey.initialize());
38 ATH_CHECK(m_extrapYKey.initialize());
40 ATH_CHECK(m_lastHitInITkCutKey.initialize());
41 ATH_CHECK(m_holesHGTDKey.initialize());
42 ATH_CHECK(m_holesITkKey.initialize());
43
44 return StatusCode::SUCCESS;
45}
46
49
50StatusCode TimeCompatibilityCheckAlg::execute(const EventContext& ctx) const {
51
52 SG::ReadHandle<xAOD::TrackParticleContainer> trk_ptkl_container_handle(
54 const xAOD::TrackParticleContainer* track_particles = trk_ptkl_container_handle.cptr();
55if (not track_particles) {
56 ATH_MSG_ERROR("[TimeCompatibilityCheckAlg] TrackParticleContainer not found, "
57 "aborting execute!");
58 return StatusCode::FAILURE;
59}
60
66 m_holesITkKey, ctx);
67
81 m_extrapXKey, ctx);
83 m_extrapYKey, ctx);
84
85 for (const auto* track_ptkl : *track_particles) {
86
87// Filling here the decoration with times of the compatible hits per track
88
89 for(const auto hit : getTimeCompatibleHits(track_ptkl)){
90 compatibleHitsTimesHandle(*track_ptkl).push_back(hit.m_time);
91 }
92 lastHitInITkCutHandle(*track_ptkl) = lastHitIsOnLastSurface(*track_ptkl);
93
94 holesITkHandle(*track_ptkl) = (m_extensionTool->getHolesITk(ctx, *track_ptkl)).size();
95
96
110
111 }
112 return StatusCode::SUCCESS;
113}
114
117
118float TimeCompatibilityCheckAlg::calculateChi2(const std::vector<Hit>& hits) const{
119
120 //Calculation of the mean
121 float sum = 0.;
122 for (const auto& hit : hits){
123 sum += hit.m_time;
124 }
125 float mean = sum / (float)hits.size();
126
127 //Calculation of the Chi2
128 float chi2 = 0.;
129 for (size_t i = 0; i < hits.size(); i++) {
130 chi2 += (hits.at(i).m_time - mean) * (hits.at(i).m_time - mean) /
131 (hits.at(i).m_resolution * hits.at(i).m_resolution);
132 }
133 return chi2;
134 }
135
136std::vector<TimeCompatibilityCheckAlg::Hit>
138
140 std::vector<float> times = layerClusterTimeHandle(*track_particle);
141
143 std::vector<char> has_clusters = layerHasExtensionHandle(*track_particle);
144
145 std::vector<Hit> valid_hits;
146 valid_hits.reserve(4);
147
148for (size_t i = 0; i < has_clusters.size(); i++){
149 if (not has_clusters.at(i)) {
150 ATH_MSG_DEBUG("[TimeCompatibilityCheckAlg::getValidHits] NO clusters found");
151 continue;
152 }
153 Hit newhit;
154
155 newhit.m_time = times.at(i);
156
157 valid_hits.push_back(newhit);
158}
159return valid_hits;
160
161}
162
163bool TimeCompatibilityCheckAlg::passesDeltaT(const std::vector<Hit>& hits) const {
164 if (not(hits.size()==2)){
165 return false;
166 }
167// pass if the distance in units of the resolution passes the cut
168if (std::fabs(hits.at(0).m_time - hits.at(1).m_time) <
169 m_delta_cut * std::hypot(hits.at(0).m_resolution, hits.at(1).m_resolution)) {
170 return true;
171 }
172 return false;
173}
174
175std::vector<TimeCompatibilityCheckAlg::Hit> TimeCompatibilityCheckAlg::getTimeCompatibleHits(
176 const xAOD::TrackParticle* track_particle) const {
177// get all available hits (see the struct Hit) in a first step
178auto valid_hits = getValidHits(track_particle);
179
180size_t vts = valid_hits.size();
181
182// if there is only one hit, not time consistency check can be done
183if (vts <= 1) {
184 return valid_hits;
185}
186
187// in case of two hits, check for time consistencyf
188if (vts == 2) {
189 if (passesDeltaT(valid_hits)) {
190 return valid_hits;
191 } else {
192 // if times are too far away form each other, do not accept time
193 return {};
194 }
195}
196
197// if there are 3 or 4 hits, perfome chi2 outlier removal
198// calculate the chi2 value of the available hits in a first step
199float chi2 = calculateChi2(valid_hits);
200
201// if the chi2 value does not surpass the set threshold, the hits are accepted as compatible in time
202if (chi2 < m_chi2_threshold) {
203 return valid_hits;
204}
205
206std::vector<Hit> time_candidates_copy = std::move(valid_hits); // TODO do I need this copy?
207 bool searching = true;
208 while (searching) {
209 // calculate chi2 contribution of each value
210 std::vector<float> chi2_contributions(time_candidates_copy.size(), 0.0);
211 for (size_t i = 0; i < time_candidates_copy.size(); i++) {
212 std::vector<Hit> buff = time_candidates_copy;
213 buff.erase(buff.begin() + i);
214
215 // calculate the chi2 value we would get when removing the i-th hit
216 double local_chi2 = calculateChi2(buff);
217
218 chi2_contributions.at(i) = local_chi2;
219 }
220 // if removing one of the hits gives a much smaller chi2, it should be
221 // removed so find the position where the "local chi2" is the smallest, and
222 // this is the hit that should be removed (since it gave a big
223 // contribution)]
224
225 // find minimum local chi2
226 int position = std::distance(
227 chi2_contributions.begin(),
228 std::min_element(chi2_contributions.begin(), chi2_contributions.end()));
229
230 // and remove it from the hits
231 time_candidates_copy.erase(time_candidates_copy.begin() + position);
232
233 // recompute chi2 value
234 chi2 = calculateChi2(time_candidates_copy);
235
236 // check for accepted chi2
237 if (chi2 < m_chi2_threshold) {
238 // if the threshold is now fulfilled, break out of the while loop
239 searching = false;
240 }
241 // if everything except 2 values has been removed, stop algo
242 if (time_candidates_copy.size() == 2) {
243 if (passesDeltaT(time_candidates_copy)) {
244 return time_candidates_copy;
245 } else {
246 ATH_MSG_DEBUG("[TimeCompatibilityCheckAlg::getValidHits] times of hits are too far away");
247 // if times are too far away, don't accept any TODO maybe accept one,
248 // can the spatial chi2 be used?
249 return {};
250 }
251 }
252 }
253 return time_candidates_copy;
254}
255
256
259
261 track.trackStateOnSurfaces();
262 if (not tsos) {
263 ATH_MSG_ERROR("Failed to retrieve track state on surfaces");
264 return nullptr;
265 }
266 // loop over the associated hits in ITk in reverse order, since we want to
267 // select the one closest to HGTD to start the extrapolation
268 for (auto i = tsos->rbegin(); i != tsos->rend(); ++i) {
269 const auto* curr_last_tsos = *i;
270 if (not curr_last_tsos) {
271 continue;
272 }
273 if (curr_last_tsos->type(Trk::TrackStateOnSurface::Measurement) and
274 curr_last_tsos->trackParameters() and
275 curr_last_tsos->measurementOnTrack()) {
276 return curr_last_tsos->trackParameters();
277 }
278 }
279 return nullptr;
280}
281
283 const Trk::Track* track = track_particle.track();
284 const Trk::TrackParameters* last_hit_param = getLastHitOnTrack(*track);
285 double radius = std::hypot(last_hit_param->position().x(), last_hit_param->position().y());
286 double abs_z = std::fabs(last_hit_param->position().z());
287
288 if (abs_z > 2700) {
289 return true;
290 }
291 if (radius < 350 and abs_z > 2400) {
292 return true;
293 }
294 // region 2
295 if (radius > 205 and radius < 350 and abs_z > 2100) {
296 return true;
297 }
298 // region 3
299 if (radius < 220 and abs_z > 2200) {
300 return true;
301 }
302
303 if (radius < 140 and abs_z > 1890) {
304 return true;
305 }
306
307 return false;
308}
309
310} // namespace HGTD
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
bool hit(const Container &ids, int pdgId)
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
An algorithm that can be simultaneously executed in multiple threads.
Derived DataVector<T>.
Definition DataVector.h:818
const_reverse_iterator rend() const noexcept
Return a const_reverse_iterator pointing at the beginning of the collection.
const_reverse_iterator rbegin() const noexcept
Return a const_reverse_iterator pointing past the end of the collection.
std::vector< TimeCompatibilityCheckAlg::Hit > getValidHits(const xAOD::TrackParticle *track_particle) const
TimeCompatibilityCheckAlg(const std::string &name, ISvcLocator *pSvcLocator)
float calculateChi2(const std::vector< Hit > &hits) const
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_extrapYKey
bool passesDeltaT(const std::vector< Hit > &hits) const
ToolHandle< IHGTD_HolesITkTool > m_extensionTool
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerClusterRawTimeKey
virtual StatusCode initialize() override final
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_compatibleHitsTimesKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerClusterTruthClassKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerExtensionChi2Key
std::vector< TimeCompatibilityCheckAlg::Hit > getTimeCompatibleHits(const xAOD::TrackParticle *track_particle) const
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerClusterTimeKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_lastHitInITkCutKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerClusterShadowedKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_holesHGTDKey
bool lastHitIsOnLastSurface(const xAOD::TrackParticle &track_particle) const
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerClusterMergedKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_extrapXKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerHasExtensionKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackParticleContainerKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerPrimaryExpectedKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_holesITkKey
const Trk::TrackParameters * getLastHitOnTrack(const Trk::Track &track) const
virtual StatusCode execute(const EventContext &ctx) const override final
Handle class for reading a decoration on an object.
const_pointer_type cptr()
Dereference the pointer.
Handle class for adding a decoration to an object.
const Amg::Vector3D & position() const
Access method for the position.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
double chi2(TH1 *h0, TH1 *h1)
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration.
ParametersBase< TrackParametersDim, Charged > TrackParameters
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".