ATLAS Offline Software
Loading...
Searching...
No Matches
TimeCompatibilityCheckAlg.cxx
Go to the documentation of this file.
1
10
12
17
18namespace HGTD {
19
21 ISvcLocator* pSvcLocator)
22 : AthReentrantAlgorithm(name, pSvcLocator){}
23
25
26 ATH_CHECK(m_extensionTool.retrieve());
31 ATH_CHECK(m_layerClusterTimeKey.initialize());
36 ATH_CHECK(m_extrapXKey.initialize());
37 ATH_CHECK(m_extrapYKey.initialize());
39 ATH_CHECK(m_lastHitInITkCutKey.initialize());
40 ATH_CHECK(m_holesHGTDKey.initialize());
41 ATH_CHECK(m_holesITkKey.initialize());
42
43 return StatusCode::SUCCESS;
44}
45
48
49StatusCode TimeCompatibilityCheckAlg::execute(const EventContext& ctx) const {
50
51 SG::ReadHandle<xAOD::TrackParticleContainer> trk_ptkl_container_handle(
53 const xAOD::TrackParticleContainer* track_particles = trk_ptkl_container_handle.cptr();
54if (not track_particles) {
55 ATH_MSG_ERROR("[TimeCompatibilityCheckAlg] TrackParticleContainer not found, "
56 "aborting execute!");
57 return StatusCode::FAILURE;
58}
59
65 m_holesITkKey, ctx);
66
80 m_extrapXKey, ctx);
82 m_extrapYKey, ctx);
83
84 for (const auto* track_ptkl : *track_particles) {
85
86// Filling here the decoration with times of the compatible hits per track
87
88 for(const auto hit : getTimeCompatibleHits(track_ptkl)){
89 compatibleHitsTimesHandle(*track_ptkl).push_back(hit.m_time);
90 }
91 lastHitInITkCutHandle(*track_ptkl) = lastHitIsOnLastSurface(*track_ptkl);
92
93 holesITkHandle(*track_ptkl) = (m_extensionTool->getHolesITk(ctx, *track_ptkl)).size();
94
95
109
110 }
111 return StatusCode::SUCCESS;
112}
113
116
117float TimeCompatibilityCheckAlg::calculateChi2(const std::vector<Hit>& hits) const{
118
119 //Calculation of the mean
120 float sum = 0.;
121 for (const auto& hit : hits){
122 sum += hit.m_time;
123 }
124 float mean = sum / (float)hits.size();
125
126 //Calculation of the Chi2
127 float chi2 = 0.;
128 for (size_t i = 0; i < hits.size(); i++) {
129 chi2 += (hits.at(i).m_time - mean) * (hits.at(i).m_time - mean) /
130 (hits.at(i).m_resolution * hits.at(i).m_resolution);
131 }
132 return chi2;
133 }
134
135std::vector<TimeCompatibilityCheckAlg::Hit>
137
139 std::vector<float> times = layerClusterTimeHandle(*track_particle);
140
142 std::vector<char> has_clusters = layerHasExtensionHandle(*track_particle);
143
144 std::vector<Hit> valid_hits;
145 valid_hits.reserve(4);
146
147for (size_t i = 0; i < has_clusters.size(); i++){
148 if (not has_clusters.at(i)) {
149 ATH_MSG_DEBUG("[TimeCompatibilityCheckAlg::getValidHits] NO clusters found");
150 continue;
151 }
152 Hit newhit;
153
154 newhit.m_time = times.at(i);
155
156 valid_hits.push_back(newhit);
157}
158return valid_hits;
159
160}
161
162bool TimeCompatibilityCheckAlg::passesDeltaT(const std::vector<Hit>& hits) const {
163 if (not(hits.size()==2)){
164 return false;
165 }
166// pass if the distance in units of the resolution passes the cut
167if (fabs(hits.at(0).m_time - hits.at(1).m_time) <
168 m_delta_cut * hypot(hits.at(0).m_resolution, hits.at(1).m_resolution)) {
169 return true;
170 }
171 return false;
172}
173
174std::vector<TimeCompatibilityCheckAlg::Hit> TimeCompatibilityCheckAlg::getTimeCompatibleHits(
175 const xAOD::TrackParticle* track_particle) const {
176// get all available hits (see the struct Hit) in a first step
177auto valid_hits = getValidHits(track_particle);
178
179size_t vts = valid_hits.size();
180
181// if there is only one hit, not time consistency check can be done
182if (vts <= 1) {
183 return valid_hits;
184}
185
186// in case of two hits, check for time consistencyf
187if (vts == 2) {
188 if (passesDeltaT(valid_hits)) {
189 return valid_hits;
190 } else {
191 // if times are too far away form each other, do not accept time
192 return {};
193 }
194}
195
196// if there are 3 or 4 hits, perfome chi2 outlier removal
197// calculate the chi2 value of the available hits in a first step
198float chi2 = calculateChi2(valid_hits);
199
200// if the chi2 value does not surpass the set threshold, the hits are accepted as compatible in time
201if (chi2 < m_chi2_threshold) {
202 return valid_hits;
203}
204
205std::vector<Hit> time_candidates_copy = valid_hits; // TODO do I need this copy?
206 bool searching = true;
207 while (searching) {
208 // calculate chi2 contribution of each value
209 std::vector<float> chi2_contributions(time_candidates_copy.size(), 0.0);
210 for (size_t i = 0; i < time_candidates_copy.size(); i++) {
211 std::vector<Hit> buff = time_candidates_copy;
212 buff.erase(buff.begin() + i);
213
214 // calculate the chi2 value we would get when removing the i-th hit
215 double local_chi2 = calculateChi2(buff);
216
217 chi2_contributions.at(i) = local_chi2;
218 }
219 // if removing one of the hits gives a much smaller chi2, it should be
220 // removed so find the position where the "local chi2" is the smallest, and
221 // this is the hit that should be removed (since it gave a big
222 // contribution)]
223
224 // find minimum local chi2
225 int position = std::distance(
226 chi2_contributions.begin(),
227 std::min_element(chi2_contributions.begin(), chi2_contributions.end()));
228
229 // and remove it from the hits
230 time_candidates_copy.erase(time_candidates_copy.begin() + position);
231
232 // recompute chi2 value
233 chi2 = calculateChi2(time_candidates_copy);
234
235 // check for accepted chi2
236 if (chi2 < m_chi2_threshold) {
237 // if the threshold is now fulfilled, break out of the while loop
238 searching = false;
239 }
240 // if everything except 2 values has been removed, stop algo
241 if (time_candidates_copy.size() == 2) {
242 if (passesDeltaT(time_candidates_copy)) {
243 return time_candidates_copy;
244 } else {
245 ATH_MSG_DEBUG("[TimeCompatibilityCheckAlg::getValidHits] times of hits are too far away");
246 // if times are too far away, don't accept any TODO maybe accept one,
247 // can the spatial chi2 be used?
248 return {};
249 }
250 }
251 }
252 return time_candidates_copy;
253}
254
255
258
260 track.trackStateOnSurfaces();
261 if (not tsos) {
262 ATH_MSG_ERROR("Failed to retrieve track state on surfaces");
263 return nullptr;
264 }
265 // loop over the associated hits in ITk in reverse order, since we want to
266 // select the one closest to HGTD to start the extrapolation
267 for (auto i = tsos->rbegin(); i != tsos->rend(); ++i) {
268 const auto* curr_last_tsos = *i;
269 if (not curr_last_tsos) {
270 continue;
271 }
272 if (curr_last_tsos->type(Trk::TrackStateOnSurface::Measurement) and
273 curr_last_tsos->trackParameters() and
274 curr_last_tsos->measurementOnTrack()) {
275 return curr_last_tsos->trackParameters();
276 }
277 }
278 return nullptr;
279}
280
282 const Trk::Track* track = track_particle.track();
283 const Trk::TrackParameters* last_hit_param = getLastHitOnTrack(*track);
284 double radius = hypot(last_hit_param->position().x(), last_hit_param->position().y());
285 double abs_z = fabs(last_hit_param->position().z());
286
287 if (abs_z > 2700) {
288 return true;
289 }
290 if (radius < 350 and abs_z > 2400) {
291 return true;
292 }
293 // region 2
294 if (radius > 205 and radius < 350 and abs_z > 2100) {
295 return true;
296 }
297 // region 3
298 if (radius < 220 and abs_z > 2200) {
299 return true;
300 }
301
302 if (radius < 140 and abs_z > 1890) {
303 return true;
304 }
305
306 return false;
307}
308
309} // namespace HGTD
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
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:795
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-2025 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".