ATLAS Offline Software
Loading...
Searching...
No Matches
HGTD_IterativeExtensionTool Class Reference

#include <HGTD_IterativeExtensionTool.h>

Inheritance diagram for HGTD_IterativeExtensionTool:
Collaboration diagram for HGTD_IterativeExtensionTool:

Public Member Functions

 HGTD_IterativeExtensionTool (const std::string &, const std::string &, const IInterface *)
virtual StatusCode initialize () override final
virtual HGTD::ExtensionObject extendTrackToHGTD (const EventContext &ctx, const xAOD::TrackParticle &track_ptkl, const HGTD_ClusterContainer *container, const HepMC::GenEvent *hs_event=nullptr, const InDetSimDataCollection *sim_data=nullptr) const override final
 Finds the (up to) four measurements in HGTD that can be associated to the track.
virtual std::vector< std::unique_ptr< Trk::TrackParameters > > getHolesITk (const EventContext &ctx, const xAOD::TrackParticle &track_ptkl) const override final

Private Member Functions

const Trk::TrackStateOnSurfacegetLastHitOnTrack (const Trk::Track &track) const
 Retrieve the last hit on track stored in the Trk::Track.
std::vector< std::unique_ptr< const Trk::TrackParameters > > extrapolateToSurfaces (const EventContext &ctx, const Trk::TrackParameters &param, const std::vector< const Trk::Surface * > &surfaces) const
 After the compatible surfaces have been selected, the extrapolation is repeated to each of them.
std::unique_ptr< const Trk::TrackStateOnSurfaceupdateStateWithBestFittingCluster (const Trk::Track *track, const std::vector< std::unique_ptr< const Trk::TrackParameters > > &params, const HGTD_ClusterContainer *container, bool &on_surface) const
 Finds the overall best fitting cluster by keeping the one that gave the lowest chi2 after testing each surface and returning it.
std::unique_ptr< const Trk::TrackStateOnSurfacefindBestCompatibleCluster (const Trk::Track *track, const Trk::TrackParameters *param, const HGTD_ClusterContainer *container) const
 Find the cluster on a given surface that has the best chi2 passing the cut.
std::unique_ptr< const Trk::TrackStateOnSurfaceupdateState (const Trk::Track *track, const Trk::TrackParameters *param, const HGTD_Cluster *cluster) const
 Calls the TOF correction tool to build an HGTD_ClusterOnTrack with a calibrated time and resolution and then calls the Kalman updator tools to update the track state.
std::pair< const HGTD_Cluster *, HGTD::ClusterTruthInfogetTruthMatchedCluster (const std::vector< const Trk::Surface * > &surfaces, const HGTD_ClusterContainer *container, const xAOD::TruthParticle *truth_ptkl, const HepMC::GenEvent *hs_event, const InDetSimDataCollection *sim_data) const
const Trk::SurfacegetFirstHGTDlayer (const xAOD::TrackParticle &track_ptkl) const
bool isOnHGTDSurface (const std::unique_ptr< const Trk::TrackParameters > &last_param) const

Static Private Member Functions

static std::vector< const Trk::Surface * > getCompatibleSurfaces (const Trk::TrackParameters &param, const Trk::Layer *layer)
 Select all within the vincinity of the point of extrapolation.

Private Attributes

ToolHandle< Trk::IExtrapolatorm_extrapolator
ToolHandle< Trk::IUpdatorm_updator
ToolHandle< IHGTD_TOFcorrectionToolm_tof_corr_tool
ToolHandle< IHGTD_ClusterTruthToolm_truth_tool
const HGTD_DetectorManagerm_hgtd_det_mgr {nullptr}
const HGTD_IDm_hgtd_id_helper {nullptr}
FloatProperty m_chi2_cut
 Track extensions are only kept if the chi2/ndof is lower than the defined cut.
IntegerProperty m_particle_hypot
 Particle hypothesis used for the extrapolation.
IntegerProperty m_phitol_ITk
IntegerProperty m_etatol_ITk

Detailed Description

Definition at line 44 of file HGTD_IterativeExtensionTool.h.

Constructor & Destructor Documentation

◆ HGTD_IterativeExtensionTool()

HGTD_IterativeExtensionTool::HGTD_IterativeExtensionTool ( const std::string & t,
const std::string & n,
const IInterface * p )

Definition at line 31 of file HGTD_IterativeExtensionTool.cxx.

34 : base_class(t, n, p) {}

Member Function Documentation

◆ extendTrackToHGTD()

HGTD::ExtensionObject HGTD_IterativeExtensionTool::extendTrackToHGTD ( const EventContext & ctx,
const xAOD::TrackParticle & track_ptkl,
const HGTD_ClusterContainer * container,
const HepMC::GenEvent * hs_event = nullptr,
const InDetSimDataCollection * sim_data = nullptr ) const
finaloverridevirtual

Finds the (up to) four measurements in HGTD that can be associated to the track.

The Track itself is not altered during this process. Since HGTD contains four active layers per endcap, four hits is the maximum. An extension can be of hole-type

Parameters
[in]trackTrack reconstructed in ITk.
Returns
Array of compatible HGTD hits in the form of HGTD_ClusterOnTrack.

Definition at line 54 of file HGTD_IterativeExtensionTool.cxx.

57 {
58
59 ATH_MSG_DEBUG("Start extending");
60
61 const Trk::Track* track = track_ptkl.track();
62
63 HGTD::ExtensionObject result;
64
65 // get last hit on track in ITk as a starting point for the extrapolation
66 const Trk::TrackStateOnSurface* last_hit = getLastHitOnTrack(*track);
67 const Trk::TrackParameters* last_param = last_hit->trackParameters();
68
69 ATH_MSG_DEBUG("last param x: " << last_param->position().x()
70 << ", y: " << last_param->position().y()
71 << ", z: " << last_param->position().z());
72 ATH_MSG_DEBUG("last param px: " << last_param->momentum().x()
73 << ", py: " << last_param->momentum().y()
74 << ", pz: " << last_param->momentum().z());
75
76 const xAOD::TruthParticle* truth_ptkl =
78
79 // get the tracking geometry
80 const Trk::TrackingGeometry* trk_geom = m_extrapolator->trackingGeometry();
81 if (not trk_geom) {
82 ATH_MSG_DEBUG("trackingGeometry returns null");
83 return result;
84 }
85
86 bool is_pos_endcap = last_param->eta() > 0;
87
88 // get the target volume
89 const Trk::TrackingVolume* hgtd_trk_volume = trk_geom->trackingVolume(
90 is_pos_endcap ? "HGTD::PositiveEndcap" : "HGTD::NegativeEndcap");
91
92 if (not hgtd_trk_volume) {
93 ATH_MSG_DEBUG("trackingVolume returns null");
94 return result;
95 }
96
97 const Trk::BinnedArray<Trk::Layer>* confined_layers =
98 hgtd_trk_volume->confinedLayers();
99 // careful, this array is not ordered from inside out (only in pos endcap)
100 if (not confined_layers) {
101 ATH_MSG_DEBUG("confinedLayers returns null");
102 return result;
103 }
104
105 // get the layers, traverse depending on endcap used
106 // since they are not in ascending z order!!
107 std::span<Trk::Layer const * const> layers = confined_layers->arrayObjects();
108 size_t layer_size = layers.size();
109
110 short position = is_pos_endcap ? 0 : layer_size - 1;
111 short step = is_pos_endcap ? 1 : -1;
112 short hgtd_layer_i = -1; // start at -1 since the ++ happens at the beginning
113 for (size_t i = 0; i < layer_size - 1; i++, position = position + step) {
114
115 const Trk::Layer* layer = layers[position];
116 // only use it, if it is an active one
117 if (layer->layerType() != 1) {
118 continue;
119 }
120 hgtd_layer_i++;
121
122 const Trk::Surface& surf_obj = layer->surfaceRepresentation();
123 ATH_MSG_DEBUG("extrapolation surface z: " << surf_obj.center().z());
124
125 // if it is a good surface, extrapolate to this surface
126 // uses same particle hypothesis used for the track itself
127 // TODO: BoundaryCheck set to false as in 20.20 -> what does this do?
128 std::unique_ptr<const Trk::TrackParameters> extrap_result = nullptr;
129
130 Trk::ParticleHypothesis part = track->info().particleHypothesis();
131 if (part == Trk::undefined) {
132 part = static_cast<Trk::ParticleHypothesis>(m_particle_hypot.value());
133 }
134 extrap_result = m_extrapolator->extrapolate(
135 ctx, *last_param, surf_obj, Trk::PropDirection::alongMomentum, false,
136 part);
137
138
139 if (not extrap_result) {
140 ATH_MSG_WARNING("Extrapolator returned null");
141 result.m_hits.at(hgtd_layer_i) = nullptr;
142 result.m_truth_primary_hits.at(hgtd_layer_i) = nullptr;
143 result.m_truth_primary_info.at(hgtd_layer_i) = HGTD::ClusterTruthInfo();
144 continue;
145 }
146
147 // get the extrapolation position info only on the first layer
148 if (hgtd_layer_i == 0) {
149 result.m_extrap_x = extrap_result->position().x();
150 result.m_extrap_y = extrap_result->position().y();
151 }
152
153 ATH_MSG_DEBUG("extrap. params x: "
154 << extrap_result->position().x()
155 << ", y: " << extrap_result->position().y()
156 << ", z: " << extrap_result->position().z());
157 ATH_MSG_DEBUG("extrap. params px: "
158 << extrap_result->momentum().x()
159 << ", py: " << extrap_result->momentum().y()
160 << ", pz: " << extrap_result->momentum().z());
161
162 // find active surfaces in the vincinity
163 auto compatible_surfaces = getCompatibleSurfaces(*extrap_result, layer);
164
165 if (compatible_surfaces.empty()) {
166 ATH_MSG_WARNING("No compatible surfaces for position");
167 result.m_hits.at(hgtd_layer_i) = nullptr;
168 result.m_truth_primary_hits.at(hgtd_layer_i) = nullptr;
169 result.m_truth_primary_info.at(hgtd_layer_i) = HGTD::ClusterTruthInfo();
170 continue;
171 }
172
173 auto extrapolated_params =
174 extrapolateToSurfaces(ctx, *last_param, compatible_surfaces);
175
176 bool on_surface = false;
177 std::unique_ptr<const Trk::TrackStateOnSurface> updated_state =
178 updateStateWithBestFittingCluster(track, extrapolated_params,
179 container, on_surface);
180
181 if (not updated_state) {
182 result.m_hits.at(hgtd_layer_i) = nullptr;
183 result.m_truth_primary_hits.at(hgtd_layer_i) = nullptr;
184 result.m_truth_primary_info.at(hgtd_layer_i) = HGTD::ClusterTruthInfo();
185 result.m_holes_hgtd.at(hgtd_layer_i) = on_surface;
186 continue;
187 }
188 // if the state was updated with a measurement, the it becomes the new last
189 // parameter
190 last_param = updated_state->trackParameters();
191 // store the last track state to be returned
192
193 std::pair<const HGTD_Cluster*, HGTD::ClusterTruthInfo> truth_info =
194 getTruthMatchedCluster(compatible_surfaces, container, truth_ptkl,
195 hs_event, sim_data);
196
197 result.m_hits.at(hgtd_layer_i) = std::move(updated_state);
198 result.m_truth_primary_hits.at(hgtd_layer_i) = truth_info.first;
199 result.m_truth_primary_info.at(hgtd_layer_i) = truth_info.second;
200
201 }
202
203 return result;
204}
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
ToolHandle< Trk::IExtrapolator > m_extrapolator
static std::vector< const Trk::Surface * > getCompatibleSurfaces(const Trk::TrackParameters &param, const Trk::Layer *layer)
Select all within the vincinity of the point of extrapolation.
const Trk::TrackStateOnSurface * getLastHitOnTrack(const Trk::Track &track) const
Retrieve the last hit on track stored in the Trk::Track.
std::vector< std::unique_ptr< const Trk::TrackParameters > > extrapolateToSurfaces(const EventContext &ctx, const Trk::TrackParameters &param, const std::vector< const Trk::Surface * > &surfaces) const
After the compatible surfaces have been selected, the extrapolation is repeated to each of them.
std::pair< const HGTD_Cluster *, HGTD::ClusterTruthInfo > getTruthMatchedCluster(const std::vector< const Trk::Surface * > &surfaces, const HGTD_ClusterContainer *container, const xAOD::TruthParticle *truth_ptkl, const HepMC::GenEvent *hs_event, const InDetSimDataCollection *sim_data) const
IntegerProperty m_particle_hypot
Particle hypothesis used for the extrapolation.
std::unique_ptr< const Trk::TrackStateOnSurface > updateStateWithBestFittingCluster(const Trk::Track *track, const std::vector< std::unique_ptr< const Trk::TrackParameters > > &params, const HGTD_ClusterContainer *container, bool &on_surface) const
Finds the overall best fitting cluster by keeping the one that gave the lowest chi2 after testing eac...
double eta() const
Access method for pseudorapidity - from momentum.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
layers(flags, cells_name, *args, **kw)
Here we define wrapper functions to set up all of the standard corrections.
@ layer
Definition HitInfo.h:79
@ alongMomentum
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.
ParametersBase< TrackParametersDim, Charged > TrackParameters
const xAOD::TruthParticle * getTruthParticle(const xAOD::IParticle &p)
Return the truthParticle associated to the given IParticle (if any).
TruthParticle_v1 TruthParticle
Typedef to implementation.

◆ extrapolateToSurfaces()

std::vector< std::unique_ptr< const Trk::TrackParameters > > HGTD_IterativeExtensionTool::extrapolateToSurfaces ( const EventContext & ctx,
const Trk::TrackParameters & param,
const std::vector< const Trk::Surface * > & surfaces ) const
private

After the compatible surfaces have been selected, the extrapolation is repeated to each of them.

Parameters
[in]paramThe last track parameter before extrapolation.
[in]surfacesTarget layer of the extrapolation.
Returns
Vector of the updated track parameters.

FIXME Is this really necessary to call the extrapolation on each target surface?

Definition at line 275 of file HGTD_IterativeExtensionTool.cxx.

277 {
278
279 std::vector<std::unique_ptr<const Trk::TrackParameters>> params;
280 params.reserve(surfaces.size());
281
282 for (const auto* surface : surfaces) {
283 std::unique_ptr<const Trk::TrackParameters> extrapolated_params = nullptr;
284
285 extrapolated_params = m_extrapolator->extrapolate(
286 ctx, param, *surface, Trk::alongMomentum, false,
287 static_cast<Trk::ParticleHypothesis>(m_particle_hypot.value()));
288 if (not extrapolated_params) {
289 continue;
290 }
291 params.push_back(std::move(extrapolated_params));
292 }
293
294 return params;
295}

◆ findBestCompatibleCluster()

std::unique_ptr< const Trk::TrackStateOnSurface > HGTD_IterativeExtensionTool::findBestCompatibleCluster ( const Trk::Track * track,
const Trk::TrackParameters * param,
const HGTD_ClusterContainer * container ) const
private

Find the cluster on a given surface that has the best chi2 passing the cut.

Is called within updateStateWithBestFittingCluster.

Definition at line 340 of file HGTD_IterativeExtensionTool.cxx.

342 {
343
344 ATH_MSG_DEBUG("[findBestCompatibleCluster] start");
345
346 std::unique_ptr<const Trk::TrackStateOnSurface> tsos = nullptr;
347
348 double lowest_chi2 = -1;
349 for (const auto* collection : *container) {
350 // find the one collection that can be associated to the surface
351 if (collection->identify() !=
353 continue;
354 }
356 "[findBestCompatibleCluster] found collection of given surface");
357 // test the clusters on this surface for compatibility, keep the best
358 for (const auto* cluster : *collection) {
359 // update the track parameters with the found cluster
360 std::unique_ptr<const Trk::TrackStateOnSurface> candidate =
361 updateState(track, param, cluster);
362
363 if (not candidate) {
364 continue;
365 }
366 if (not candidate->measurementOnTrack() and
367 not candidate->fitQualityOnSurface()) {
368 continue;
369 }
370 double chi2 = candidate->fitQualityOnSurface().chiSquared() /
371 candidate->fitQualityOnSurface().doubleNumberDoF();
372 ATH_MSG_DEBUG("found cluster with chi2 of " << chi2);
373 // apply cut on the chi2
374 if (chi2 > m_chi2_cut) {
375 continue;
376 }
377 // make sure only one TSOS is kept
378 if (not tsos or chi2 < lowest_chi2) {
379 tsos.swap(candidate);
380 lowest_chi2 = chi2;
381 }
382 }
383 // per trackparameter, there is only one fitting surface
384 // break after having found it
385 break;
386 }
387
388 return tsos; // no need to std::move thanks to Return Value Optimization (RVO)
389}
FloatProperty m_chi2_cut
Track extensions are only kept if the chi2/ndof is lower than the defined cut.
std::unique_ptr< const Trk::TrackStateOnSurface > updateState(const Trk::Track *track, const Trk::TrackParameters *param, const HGTD_Cluster *cluster) const
Calls the TOF correction tool to build an HGTD_ClusterOnTrack with a calibrated time and resolution a...
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
Identifier associatedDetectorElementIdentifier() const
return Identifier of the associated Detector Element
double chi2(TH1 *h0, TH1 *h1)

◆ getCompatibleSurfaces()

std::vector< const Trk::Surface * > HGTD_IterativeExtensionTool::getCompatibleSurfaces ( const Trk::TrackParameters & param,
const Trk::Layer * layer )
staticprivate

Select all within the vincinity of the point of extrapolation.

Parameters
[in]paramThe already extrapolated track parameter.
[in]layerTarget layer of the extrapolation.
Returns
Vector of compatible surfaces that represent modules.

FIXME exchange the loop with the neighbour functionality (wherever that is)

Definition at line 232 of file HGTD_IterativeExtensionTool.cxx.

233 {
234
235 std::vector<const Trk::Surface*> surfaces;
236
237 // point of extrapolation as global position
238 const Amg::Vector3D& position = param.position();
239 // get the surface at the point of extrapolation
240 const auto* surface_arr = layer->surfaceArray(); // these are the modules
241 if (!surface_arr) {
242 return surfaces;
243 }
244 const Trk::Surface* module_surface = surface_arr->object(
245 position); // from this binned object, get the module closeby
246 if (!module_surface) {
247 return surfaces;
248 }
249 surfaces.push_back(module_surface);
250
251 // pick up additional surfaces in a 4cm radius
252 // TODO REPLACE THIS BY NEIGHBOUR FUNCTIONALITY IN FUTURE!!
253 short steps = 16;
254 float delta_angle = 6.2831853 / (float)steps;
255 float angle = 0.;
256 float radius = 20.0;
257 for (short i = 0; i < steps; i++, angle = angle + delta_angle) {
258 Amg::Vector3D delta(radius * std::cos(angle), radius * std::sin(angle), 0);
259 Amg::Vector3D result = position + delta;
260 const Trk::Surface* additional_surface = surface_arr->object(result);
261 if (!additional_surface) {
262 continue;
263 }
264 // check if surface was added to avoid duplicates
265 if (std::find(surfaces.begin(), surfaces.end(), additional_surface) ==
266 surfaces.end()) {
267 surfaces.push_back(additional_surface);
268 }
269 }
270
271 return surfaces;
272}
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Eigen::Matrix< double, 3, 1 > Vector3D

◆ getFirstHGTDlayer()

const Trk::Surface * HGTD_IterativeExtensionTool::getFirstHGTDlayer ( const xAOD::TrackParticle & track_ptkl) const
private

Definition at line 475 of file HGTD_IterativeExtensionTool.cxx.

475 {
476
477 const Trk::Track* track = track_ptkl.track();
478 const Trk::TrackStateOnSurface* last_hit = getLastHitOnTrack(*track);
479 const Trk::TrackParameters* startParameters = last_hit->trackParameters();
480 const Trk::Surface* surf = nullptr;
481
482 const Trk::TrackingGeometry* trk_geom = m_extrapolator->trackingGeometry();
483 if (not trk_geom){
484 ATH_MSG_DEBUG("trackingGeometry returns null");
485 return surf;
486 }
487
488 bool is_pos_endcap = startParameters->eta() > 0;
489
490 // get the target volume
491 const Trk::TrackingVolume* hgtd_trk_volume = trk_geom->trackingVolume(
492 is_pos_endcap ? "HGTD::PositiveEndcap" : "HGTD::NegativeEndcap");
493
494 if (not hgtd_trk_volume) {
495 ATH_MSG_DEBUG("trackingVolume returns null");
496 return surf;
497 }
498
499 const Trk::BinnedArray<Trk::Layer>* confined_layer =
500 hgtd_trk_volume->confinedLayers();
501 //careful, this array is not ordered from inside out (only in pos endcap)
502 if (not confined_layer) {
503 ATH_MSG_DEBUG("confinedLayer returns null");
504 return surf;
505 }
506
507 // get the layers, traverse depending in endcap used
508 // since they are not in ascending z order !!
509 std::span<Trk::Layer const * const> layers =
510 confined_layer->arrayObjects();
511 const Trk::Layer* layer = layers[0];
512 surf = &(layer->surfaceRepresentation());
513 return surf;
514
515}

◆ getHolesITk()

std::vector< std::unique_ptr< Trk::TrackParameters > > HGTD_IterativeExtensionTool::getHolesITk ( const EventContext & ctx,
const xAOD::TrackParticle & track_ptkl ) const
finaloverridevirtual

checking active material

Definition at line 518 of file HGTD_IterativeExtensionTool.cxx.

518 {
519 const Trk::Track* track = track_ptkl.track();
520 const Trk::TrackStateOnSurface* last_hit = getLastHitOnTrack(*track);
521 const Trk::TrackParameters* startParameters = last_hit->trackParameters();
522 const Trk::Surface* surf_obj = getFirstHGTDlayer(track_ptkl);
523
524 std::vector<std::unique_ptr<Trk::TrackParameters> > paramList = m_extrapolator->extrapolateStepwise(
525 ctx, *startParameters, *surf_obj, Trk::alongMomentum,
526 false, static_cast<Trk::ParticleHypothesis>(m_particle_hypot.value()));
527
528 int nOfExtrapolations = paramList.size();
529 if (paramList.empty()) {
530 return paramList;
531 }
532
533 std::vector<std::unique_ptr<Trk::TrackParameters> > listOfHoles;
534 listOfHoles.reserve(nOfExtrapolations);
535
536 for (std::unique_ptr<Trk::TrackParameters>& thisParameters : paramList) {
537 ATH_MSG_DEBUG("extrapolated pos: " << thisParameters->position() << " r: " <<
538 sqrt(pow(thisParameters->position().x(),2)+pow(thisParameters->position().y(),2)));
539
540 // check if surface has identifier !
541 Identifier id;
542 if ((thisParameters->associatedSurface()).associatedDetectorElement() != nullptr and
543 (thisParameters->associatedSurface()).associatedDetectorElement()->identify() != 0) {
544 id = (thisParameters->associatedSurface()).associatedDetectorElement()->identify();
545 ATH_MSG_DEBUG("ID: "<<id);
546 } else {
547 ATH_MSG_VERBOSE("Surface has no detector element ID, skip it");
548 continue;
549 }
550
551 const InDetDD::SiDetectorElement* siElement =
552 dynamic_cast<const InDetDD::SiDetectorElement*>(
553 thisParameters->associatedSurface().associatedDetectorElement());
554 if (siElement == nullptr) {
555 ATH_MSG_DEBUG("TrackParameters do not belong to a Si Element");
557 continue;
558 }
559 double phitol = 2.5;
560 double etatol = 5.;
561 if (thisParameters->covariance()) {
562 phitol = m_phitol_ITk * sqrt((*thisParameters->covariance())(Trk::locX, Trk::locX));
563 etatol = m_etatol_ITk * sqrt((*thisParameters->covariance())(Trk::locY, Trk::locY));
564 }
565 if (siElement->nearBondGap(thisParameters->localPosition(), etatol)) {
566 continue;
567 }
568 InDetDD::SiIntersect siIn =
569 siElement->inDetector(thisParameters->localPosition(), phitol, etatol);
570
571 if (not siIn.in()){
572 ATH_MSG_DEBUG("Extrapolation does not belong to ITk");
573 continue;
574 }
575
576 if(thisParameters->position().z() > 3200){
577 ATH_MSG_DEBUG("Extrapolated pos. z is probably at HGTD: " << thisParameters->position().z());
578 continue;
579 }
580
581 // check if this surface is not already in the list to avoid repetitions
582 auto searchRepeatition = std::find_if(
583 listOfHoles.begin(), listOfHoles.end(), [id](std::unique_ptr<Trk::TrackParameters> &tp_test)
584 {return tp_test->associatedSurface().associatedDetectorElement()->identify() == id ; });
585 if (searchRepeatition == listOfHoles.end()) {
586 listOfHoles.push_back(std::move(thisParameters));
587 } else {
588 continue;
589 }
590
591}
592
593 ATH_MSG_DEBUG("[HGTD_IterativeExtensionTool::getHolesITk] difference in 2 lists: "<< nOfExtrapolations-listOfHoles.size());
594 return listOfHoles;
595 }
#define ATH_MSG_VERBOSE(x)
const Trk::Surface * getFirstHGTDlayer(const xAOD::TrackParticle &track_ptkl) const
bool nearBondGap(const Amg::Vector2D &localPosition, double etaTol) const
Test if near bond gap within tolerances.
SiIntersect inDetector(const Amg::Vector2D &localPosition, double phiTol, double etaTol) const
Test that it is in the active region.
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
constexpr int pow(int x)
Definition conifer.h:27

◆ getLastHitOnTrack()

const Trk::TrackStateOnSurface * HGTD_IterativeExtensionTool::getLastHitOnTrack ( const Trk::Track & track) const
private

Retrieve the last hit on track stored in the Trk::Track.

Parameters
[in]trackTrack reconstructed in ITk.
Returns
The last hit on track, i.e. the closest one to HGTD.

FIXME: returns a const*, but the Track manages this TSOS. Could I return rather const&? But: I want to check if type is OK... should I return an "empty" TSOS if nothing passes the requirements?

Definition at line 207 of file HGTD_IterativeExtensionTool.cxx.

207 {
208
209 const Trk::TrackStates* tsos =
210 track.trackStateOnSurfaces();
211 if (not tsos) {
212 ATH_MSG_ERROR("Failed to retrieve track state on surfaces");
213 return nullptr;
214 }
215 // loop over the associated hits in ITk in reverse order, since we want to
216 // select the one closest to HGTD to start the extrapolation
217 for (auto i = tsos->rbegin(); i != tsos->rend(); ++i) {
218 const auto* curr_last_tsos = *i;
219 if (not curr_last_tsos) {
220 continue;
221 }
222 if (curr_last_tsos->type(Trk::TrackStateOnSurface::Measurement) and
223 curr_last_tsos->trackParameters() and
224 curr_last_tsos->measurementOnTrack()) {
225 return curr_last_tsos;
226 }
227 }
228 return nullptr;
229}
#define ATH_MSG_ERROR(x)
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
DataVector< const Trk::TrackStateOnSurface > TrackStates

◆ getTruthMatchedCluster()

std::pair< const HGTD_Cluster *, HGTD::ClusterTruthInfo > HGTD_IterativeExtensionTool::getTruthMatchedCluster ( const std::vector< const Trk::Surface * > & surfaces,
const HGTD_ClusterContainer * container,
const xAOD::TruthParticle * truth_ptkl,
const HepMC::GenEvent * hs_event,
const InDetSimDataCollection * sim_data ) const
private

Definition at line 430 of file HGTD_IterativeExtensionTool.cxx.

434 {
435
436 if (not truth_ptkl or not sim_data) {
437 if (not truth_ptkl)
438 ATH_MSG_DEBUG("truth_ptkl is null");
439 if (not sim_data)
440 ATH_MSG_DEBUG("sim_data is null");
441
442 return {nullptr, HGTD::ClusterTruthInfo()};
443 }
444
445 std::vector<Identifier> ids;
446 std::for_each(surfaces.begin(), surfaces.end(),
447 [&](const Trk::Surface* surf) {
448 ids.push_back(surf->associatedDetectorElementIdentifier());
449 });
450
451 for (const auto *const collection : *container) {
452 // if the ID corresponding to this collection is not in the list, skip
453
454 if (std::find(ids.begin(), ids.end(), collection->identify()) ==
455 ids.end()) {
456 continue;
457 }
458 for (const auto* cluster : *collection) {
459
460 HGTD::ClusterTruthInfo truth_info = m_truth_tool->classifyCluster(
461 cluster, truth_ptkl, sim_data, hs_event);
462 // return cluster and truth info if the hit is matched to the truth
463 // particle
465 return {cluster, truth_info};
466 }
467 }
468 }
469 // no matched cluster found
470 return {nullptr, HGTD::ClusterTruthInfo()};
471}
ToolHandle< IHGTD_ClusterTruthTool > m_truth_tool

◆ initialize()

StatusCode HGTD_IterativeExtensionTool::initialize ( )
finaloverridevirtual

Definition at line 36 of file HGTD_IterativeExtensionTool.cxx.

36 {
37 StatusCode sc = AthAlgTool::initialize();
38
39 ATH_CHECK(m_extrapolator.retrieve());
40
41 ATH_CHECK(m_updator.retrieve());
42
43 ATH_CHECK(m_tof_corr_tool.retrieve());
44
45 ATH_CHECK(m_truth_tool.retrieve());
46
47 // get HGTD Detector Description Manager and HGTD Helper
48 ATH_CHECK(detStore()->retrieve(m_hgtd_det_mgr, "HGTD"));
49 ATH_CHECK(detStore()->retrieve(m_hgtd_id_helper, "HGTD_ID"));
50
51 return sc;
52}
#define ATH_CHECK
Evaluate an expression and check for errors.
static Double_t sc
ToolHandle< IHGTD_TOFcorrectionTool > m_tof_corr_tool
const HGTD_DetectorManager * m_hgtd_det_mgr
ToolHandle< Trk::IUpdator > m_updator
::StatusCode StatusCode
StatusCode definition for legacy code.

◆ isOnHGTDSurface()

bool HGTD_IterativeExtensionTool::isOnHGTDSurface ( const std::unique_ptr< const Trk::TrackParameters > & last_param) const
private

Definition at line 597 of file HGTD_IterativeExtensionTool.cxx.

598 {
599 //Here I will check if the extrapolation is on the sensor within the
600 //tolerance level
601 double phitol = 2.5;
602 double etatol = 5.;
603 if (last_param->covariance()) {
604 phitol = (-3) * sqrt((*last_param->covariance())(Trk::locX, Trk::locX));
605 etatol = (-3) * sqrt((*last_param->covariance())(Trk::locY, Trk::locY));
606 }
607
608 const Trk::SurfaceBounds &bounds_HGTD =
609 dynamic_cast<const Trk::SurfaceBounds &>(last_param->associatedSurface().bounds());
610 ATH_MSG_DEBUG("Distance from the surface: " << last_param->associatedSurface().bounds().minDistance(
611 last_param->localPosition()));
612 ATH_MSG_DEBUG("Phitol: " << phitol << " , etatol: "<<etatol);
613 ATH_MSG_DEBUG("Is on surface: "<< bounds_HGTD.inside(last_param->localPosition(), phitol, etatol));
614
615 return bounds_HGTD.inside(last_param->localPosition(), phitol, etatol);
616}
virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const =0
Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds.

◆ updateState()

std::unique_ptr< const Trk::TrackStateOnSurface > HGTD_IterativeExtensionTool::updateState ( const Trk::Track * track,
const Trk::TrackParameters * param,
const HGTD_Cluster * cluster ) const
private

Calls the TOF correction tool to build an HGTD_ClusterOnTrack with a calibrated time and resolution and then calls the Kalman updator tools to update the track state.

Definition at line 392 of file HGTD_IterativeExtensionTool.cxx.

393 {
394 ATH_MSG_DEBUG("[updateState] calling the updator");
395
396 // FIXME: the HGTD_Cluster should know its detector element here. needs
397 // to be set up in the converter at some point!!
398 const auto* det_el = m_hgtd_det_mgr->getDetectorElement(cluster->identify());
399
400 // apply the time of flight correction before setting the time and resolution
401 // in the HGTD_ClusterOnTrack
402 std::pair<float, float> corr_time_and_res =
403 m_tof_corr_tool->correctTimeAndResolution(
404 *track, *cluster, cluster->time(), cluster->timeResolution());
405
406 std::unique_ptr<HGTD_ClusterOnTrack> cot =
407 std::make_unique<HGTD_ClusterOnTrack>(
408 cluster, Trk::LocalParameters(cluster->localPosition()),
409 Amg::MatrixX(cluster->localCovariance()), corr_time_and_res.first,
410 corr_time_and_res.second, det_el->identifyHash());
411
412 Trk::FitQualityOnSurface* quality = nullptr;
413
414 std::unique_ptr<Trk::TrackParameters> pars = m_updator->addToState(
415 *param, cot->localParameters(), cot->localCovariance(), quality);
416 if (not pars) {
417 ATH_MSG_DEBUG("[updateState] pars is null");
418 return nullptr;
419 }
420
421 //Here one could fix the addToState intefaces to
422 //avoid them allocating memory for Fit Quality On Surface
423 auto uniqueQuality= std::unique_ptr<Trk::FitQualityOnSurface>(quality);
424 auto QoS = uniqueQuality? *uniqueQuality : Trk::FitQualityOnSurface{};
425 return std::make_unique<const Trk::TrackStateOnSurface>(QoS, std::move(cot),
426 std::move(pars));
427}
float time() const
float timeResolution() const
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.

◆ updateStateWithBestFittingCluster()

std::unique_ptr< const Trk::TrackStateOnSurface > HGTD_IterativeExtensionTool::updateStateWithBestFittingCluster ( const Trk::Track * track,
const std::vector< std::unique_ptr< const Trk::TrackParameters > > & params,
const HGTD_ClusterContainer * container,
bool & on_surface ) const
private

Finds the overall best fitting cluster by keeping the one that gave the lowest chi2 after testing each surface and returning it.

Definition at line 298 of file HGTD_IterativeExtensionTool.cxx.

301 {
302 ATH_MSG_DEBUG("[updateStateWithBestFittingCluster] start updating");
303
304 std::unique_ptr<const Trk::TrackStateOnSurface> updated_state = nullptr;
305
306 double lowest_chi2 = -1.;
307 // all compatible surfaces are tested for the best fitting cluster
308 for (const auto& param : params) {
309
310 if (!on_surface)
311 {
312 on_surface = isOnHGTDSurface(param);
313 }
314
315 std::unique_ptr<const Trk::TrackStateOnSurface> best_tsos =
316 findBestCompatibleCluster(track, param.get(), container);
317 if (not best_tsos) {
318 ATH_MSG_DEBUG("[updateStateWithBestFittingCluster] tsos is null");
319 continue;
320 }
321 ATH_MSG_DEBUG("[updateStateWithBestFittingCluster] tsos found");
322
323 double chi2 = best_tsos->fitQualityOnSurface().chiSquared() /
324 best_tsos->fitQualityOnSurface().doubleNumberDoF();
326 "[updateStateWithBestFittingCluster] found state with chi2 of "
327 << chi2);
328 // make sure only one TSOS is kept
329 if (!updated_state or chi2 < lowest_chi2) {
330 updated_state.swap(best_tsos);
331 lowest_chi2 = chi2;
332 }
333 }
334
335 return updated_state; // no need to std::move thanks to Return Value
336 // Optimization (RVO)
337}
bool isOnHGTDSurface(const std::unique_ptr< const Trk::TrackParameters > &last_param) const
std::unique_ptr< const Trk::TrackStateOnSurface > findBestCompatibleCluster(const Trk::Track *track, const Trk::TrackParameters *param, const HGTD_ClusterContainer *container) const
Find the cluster on a given surface that has the best chi2 passing the cut.

Member Data Documentation

◆ m_chi2_cut

FloatProperty HGTD_IterativeExtensionTool::m_chi2_cut
private
Initial value:
{this, "Chi2Cut", 5.0,
"Quality cut for decision to keep track extension"}

Track extensions are only kept if the chi2/ndof is lower than the defined cut.

Definition at line 181 of file HGTD_IterativeExtensionTool.h.

181 {this, "Chi2Cut", 5.0,
182 "Quality cut for decision to keep track extension"};

◆ m_etatol_ITk

IntegerProperty HGTD_IterativeExtensionTool::m_etatol_ITk
private
Initial value:
{
this, "ToleranceLevelITk", 3,
"The tolerance level in eta for an extrapolation to be a hole on track in ITk"}

Definition at line 194 of file HGTD_IterativeExtensionTool.h.

194 {
195 this, "ToleranceLevelITk", 3,
196 "The tolerance level in eta for an extrapolation to be a hole on track in ITk"};

◆ m_extrapolator

ToolHandle<Trk::IExtrapolator> HGTD_IterativeExtensionTool::m_extrapolator
private
Initial value:
{
this, "ExtrapolatorTool", "Trk::Extrapolator/AtlasExtrapolator",
"Tool for extrapolating the track to the HGTD surfaces"}

Definition at line 158 of file HGTD_IterativeExtensionTool.h.

158 {
159 this, "ExtrapolatorTool", "Trk::Extrapolator/AtlasExtrapolator",
160 "Tool for extrapolating the track to the HGTD surfaces"};

◆ m_hgtd_det_mgr

const HGTD_DetectorManager* HGTD_IterativeExtensionTool::m_hgtd_det_mgr {nullptr}
private

Definition at line 174 of file HGTD_IterativeExtensionTool.h.

174{nullptr};

◆ m_hgtd_id_helper

const HGTD_ID* HGTD_IterativeExtensionTool::m_hgtd_id_helper {nullptr}
private

Definition at line 175 of file HGTD_IterativeExtensionTool.h.

175{nullptr};

◆ m_particle_hypot

IntegerProperty HGTD_IterativeExtensionTool::m_particle_hypot
private
Initial value:
{
this, "ParticleHypothesis", Trk::ParticleHypothesis::pion,
"The hypothesis of the track's particle type"}

Particle hypothesis used for the extrapolation.

Definition at line 187 of file HGTD_IterativeExtensionTool.h.

187 {
188 this, "ParticleHypothesis", Trk::ParticleHypothesis::pion,
189 "The hypothesis of the track's particle type"};

◆ m_phitol_ITk

IntegerProperty HGTD_IterativeExtensionTool::m_phitol_ITk
private
Initial value:
{
this, "ToleranceLevelITk", 3,
"The tolerance level in phi for an extrapolation to be a hole on track in ITk"}

Definition at line 191 of file HGTD_IterativeExtensionTool.h.

191 {
192 this, "ToleranceLevelITk", 3,
193 "The tolerance level in phi for an extrapolation to be a hole on track in ITk"};

◆ m_tof_corr_tool

ToolHandle<IHGTD_TOFcorrectionTool> HGTD_IterativeExtensionTool::m_tof_corr_tool
private
Initial value:
{
this, "TOFCorrTool", "StraightLineTOFcorrectionTool",
"Tool for correcting for time of flight"}

Definition at line 166 of file HGTD_IterativeExtensionTool.h.

166 {
167 this, "TOFCorrTool", "StraightLineTOFcorrectionTool",
168 "Tool for correcting for time of flight"};

◆ m_truth_tool

ToolHandle<IHGTD_ClusterTruthTool> HGTD_IterativeExtensionTool::m_truth_tool
private
Initial value:
{
this, "ClusterTruthTool", "HGTD::ClusterTruthTool/ClusterTruthTool",
"Tool for classifying HGTD clusters with truth information"}

Definition at line 170 of file HGTD_IterativeExtensionTool.h.

170 {
171 this, "ClusterTruthTool", "HGTD::ClusterTruthTool/ClusterTruthTool",
172 "Tool for classifying HGTD clusters with truth information"};

◆ m_updator

ToolHandle<Trk::IUpdator> HGTD_IterativeExtensionTool::m_updator
private
Initial value:
{
this, "UpdatorTool", "Trk::KalmanUpdator/KalmanUpdator",
"Tool for updating the track parameters accounting for new measurements"}

Definition at line 162 of file HGTD_IterativeExtensionTool.h.

162 {
163 this, "UpdatorTool", "Trk::KalmanUpdator/KalmanUpdator",
164 "Tool for updating the track parameters accounting for new measurements"};

The documentation for this class was generated from the following files: