ATLAS Offline Software
ReFitTrack.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // ReFitTrack.cxx
7 // Implementation file for class ReFitTrack
9 // version 1.0 13/05/04 Maria Jose Costa
11 
12 //SiTBLineFitter includes
13 #include "TrkRefitAlg/ReFitTrack.h"
14 
15 // Gaudi includes
16 #include "GaudiKernel/ListItem.h"
17 
28 #include "VxVertex/VxContainer.h"
29 #include "VxVertex/RecVertex.h"
30 
31 #include <memory>
32 
33 #include <vector>
34 
35 // Constructor with parameters:
36 Trk::ReFitTrack::ReFitTrack(const std::string &name, ISvcLocator *pSvcLocator) :
37  AthAlgorithm(name,pSvcLocator),
38  m_trackName("Tracks"),
39  m_newTrackName("ReFitted_Tracks"),
40  m_runOutlier(false),
41  m_matEffects(3),
42  m_ParticleHypothesis(Trk::pion),
43  m_tracks(nullptr),
44  m_ITrackFitter("TrkKalmanFitter/KalmanFitter"),
45  m_ITrackFitterTRT(""),
46  m_trkSummaryTool(""),
47  m_trkSelectorTool(""),
48  m_constrainFitMode(0),
49  m_vxContainerName("VxPrimaryCandidate"),
50  m_extrapolator("Trk::Extrapolator/InDetExtrapolator"),
51  m_usetrackhypo(false)
52 {
53 
54  // Get parameter values from jobOptions file
55  declareProperty("TrackName", m_trackName, "collection name for tracks to be refitted");
56  declareProperty("NewTrackName", m_newTrackName, "collection name for output tracks");
57  declareProperty("FitterTool", m_ITrackFitter, "ToolHandle for track fitter implementation");
58  declareProperty("FitterToolTRT", m_ITrackFitterTRT, "ToolHandle for TRT track fitter implementation");
59  declareProperty("SummaryTool" , m_trkSummaryTool, "ToolHandle for track summary tool");
60  declareProperty("TrackSelectionTool", m_trkSelectorTool, "ToolHandle for track selection tool");
61  declareProperty("runOutlier", m_runOutlier, "switch to control outlier finding in track fit");
62  declareProperty("matEffects", m_matEffects, "type of material interaction in extrapolation");
63  declareProperty("useParticleHypothesisFromTrack", m_usetrackhypo,"fit with particle hypothesis from original track");
64 
65  // constrained fitting
66  declareProperty("ConstrainFit", m_constrainFitMode,"mode switch if/how the track is constrained to the BS/Vx");
67  declareProperty("VertexCollection", m_vxContainerName,"Source for vertex to use for constraining tracks");
68  declareProperty("Extrapolator", m_extrapolator, "Extrapolator needed for coherent measurement frame.");
69 
70 
71 }
72 
73 // Initialize method:
75 {
76  ATH_MSG_INFO("ReFitTrack::initialize()");
77 
78  if (m_ITrackFitter.retrieve().isFailure()) {
79  msg(MSG::FATAL) << "Failed to retrieve tool "<<m_ITrackFitter.typeAndName()<<endmsg;
80  return StatusCode::FAILURE;
81  } else
82  msg(MSG::INFO) << "Retrieved general fitter " << m_ITrackFitter.typeAndName() << endmsg;
83 
84  if (!m_ITrackFitterTRT.name().empty()){
85  if (m_ITrackFitterTRT.retrieve().isFailure()) {
86  msg(MSG::FATAL) << "Failed to retrieve tool " << m_ITrackFitterTRT.typeAndName()<<endmsg;
87  return StatusCode::FAILURE;
88  } else
89  msg(MSG::INFO) << "Retrieved fitter for TRT-only tracks " << m_ITrackFitterTRT.typeAndName() << endmsg;
90  }
91 
92  if (!m_trkSummaryTool.name().empty()){
93  if (m_trkSummaryTool.retrieve().isFailure()) {
94  msg(MSG::FATAL) << "Failed to retrieve tool " << m_trkSummaryTool << endmsg;
95  return StatusCode::FAILURE;
96  } else
97  msg(MSG::INFO) << "Retrieved tool " << m_trkSummaryTool.typeAndName() << endmsg;
98  }
99  if ( m_assoTool.retrieve().isFailure() ) {
100  msg(MSG::FATAL) << "Failed to retrieve tool " << m_assoTool << endmsg;
101  return StatusCode::FAILURE;
102  } else ATH_MSG_INFO("Retrieved tool " << m_assoTool);
103 
104  if (!m_trkSelectorTool.empty()){
105  if (m_trkSelectorTool.retrieve().isFailure()) {
106  msg(MSG::FATAL) << "Failed to retrieve tool " << m_trkSelectorTool << ". No Track Selection will be done." << endmsg;
107  return StatusCode::FAILURE;
108  } else
109  msg(MSG::INFO) << "Retrieved tool " << m_trkSelectorTool.typeAndName() << endmsg;
110  }
111 
112  // beam conditions service
113  if (m_constrainFitMode) {
114  ATH_CHECK(m_beamSpotKey.initialize());
115  }
116 
117  // extrapolator
118  if (m_constrainFitMode && m_extrapolator.retrieve().isFailure()){
119  ATH_MSG_FATAL( "Failed to retrieve " << m_extrapolator );
120  return StatusCode::FAILURE;
121  }
122 
123  // Configuration of the material effects
124  m_ParticleHypothesis = Trk::ParticleSwitcher::particle[m_matEffects];
125 
126  ATH_CHECK( m_trackName.initialize() );
127  ATH_CHECK( m_vxContainerName.initialize() );
128  ATH_CHECK( m_newTrackName.initialize() );
129  ATH_CHECK( m_pixelDetEleCollKey.initialize() );
130  ATH_CHECK( m_SCTDetEleCollKey.initialize() );
131 
132  return StatusCode::SUCCESS;
133 }
134 
135 // Execute method:
137 {
138  ATH_MSG_DEBUG ("ReFitTrack::execute()");
139  std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map(m_assoTool->createPRDtoTrackMap());
140  const EventContext& ctx = Gaudi::Hive::currentContext();
141  SG::ReadHandle<TrackCollection> tracks (m_trackName, ctx);
142 
143  if (!tracks.isValid()){
144  msg(MSG::ERROR) <<"Track collection named " << m_trackName.key()
145  << " not found, exit ReFitTrack." << endmsg;
146  return StatusCode::SUCCESS;
147  } else {
148  ATH_MSG_DEBUG ("Tracks collection '" << m_trackName.key() << "' retrieved from EventStore.");
149  }
150 
151  ATH_MSG_DEBUG("Track fit configured with constrain option : " << m_constrainFitMode );
152 
153  // Handle the various possible constraints.
154  std::unique_ptr<const Trk::PerigeeSurface> constrainSf;
155  std::unique_ptr<const Trk::RecVertex> constrainVx;
156 
157  if (m_constrainFitMode > 0){
158  constrainVx.reset( setupConstrainedFit() );
159  }
160 
161  // constrain surface (either BS of VTX)
162  if (constrainVx) {
163  constrainSf = std::make_unique<Trk::PerigeeSurface>( constrainVx->position());
164  }
165 
166  ParticleHypothesis hypo=m_ParticleHypothesis;
167 
168  // create new collection of tracks to write in storegate
169  // auto newtracks = std::make_unique<TrackCollection>();
170  std::vector<std::unique_ptr<Trk::Track> > new_tracks;
171 
172  // loop over tracks
173  for (TrackCollection::const_iterator itr = (*tracks).begin(); itr < (*tracks).end(); ++itr){
174 
175  ATH_MSG_VERBOSE ("input track:" << **itr);
176 
177  if (m_usetrackhypo) hypo=(**itr).info().particleHypothesis();
178  std::unique_ptr<Trk::Track> newtrack;
179  bool trtonly=false;
180 
181  bool passedSelection = true;
182  // check whether the track passes the selection
183  if (*itr && !m_trkSelectorTool.empty()){
184  passedSelection = m_trkSelectorTool->decision(**itr);
185  }
186 
187 
188  if (!m_ITrackFitterTRT.name().empty() && !m_trkSummaryTool.name().empty()){
189  ATH_MSG_VERBOSE ("Creating summary");
190  // @TODO does not need PRDtoTrackMap
191  unsigned int n_trt_hits;
192  if ((*itr)->trackSummary()) {
193  n_trt_hits = (*itr)->trackSummary()->get(numberOfTRTHits);
194  }
195  else {
196  std::unique_ptr<const Trk::TrackSummary> summary( m_trkSummaryTool->summaryNoHoleSearch(**itr));
197  n_trt_hits = summary->get(numberOfTRTHits);
198  }
199  if ( (**itr).measurementsOnTrack()->size() - n_trt_hits<3 )
200  trtonly=true;
201  }
202 
203  if (passedSelection) {
204  ATH_MSG_VERBOSE ("Passed selection");
205 
206  const Trk::Perigee* origPerigee = (*itr)->perigeeParameters();
207  if (origPerigee){
208  double od0 = origPerigee->parameters()[Trk::d0];
209  double oz0 = origPerigee->parameters()[Trk::z0];
210  double ophi0 = origPerigee->parameters()[Trk::phi0];
211  double otheta = origPerigee->parameters()[Trk::theta];
212  double oqOverP = origPerigee->parameters()[Trk::qOverP];
213  ATH_MSG_DEBUG ("Original parameters " << od0 << " " << oz0 << " " << ophi0 << " " << otheta << " " << oqOverP);
214  }
215 
216  // create a measurement for the beamspot
217  if (constrainVx && origPerigee){
218 
219  ATH_MSG_VERBOSE ("Creating measurement for beamspot.");
220  // extrapolate the track to the vertex -- for consistent Measurement frame
221  std::unique_ptr<const Trk::TrackParameters> tp( m_extrapolator->extrapolateTrack(ctx,
222  **itr,
223  *constrainSf,
225  const Trk::Perigee* tpConstrainedSf = dynamic_cast<const Trk::Perigee*>(tp.get());
226  // create the vertex/beamsptOnTrack
227  std::unique_ptr<Trk::VertexOnTrack> bsvxOnTrack( tpConstrainedSf ? new Trk::VertexOnTrack(*constrainVx,*tpConstrainedSf) : nullptr );
228  std::vector<const MeasurementBase*> vec;
229  if (tpConstrainedSf) vec.push_back(bsvxOnTrack.get() );
230  // get the measurmentsOnTrack
231  const DataVector<const MeasurementBase>* measurementsOnTracks = (**itr).measurementsOnTrack();
232  // get the outliersOnTrack, needs sorting
234  // clone measurements and outliers into the track
235  DataVector<const MeasurementBase>::const_iterator measIter = measurementsOnTracks->begin();
236  DataVector<const MeasurementBase>::const_iterator measIterEnd = measurementsOnTracks->end();
237  for ( ; measIter != measIterEnd; ++measIter)
238  vec.push_back((*measIter));
239  // if - protect the outliers ...
240  // const DataVector<const MeasurementBase>* outliersOnTracks = (**itr).outliersOnTrack();
241  // measIter = outliersOnTracks->begin();
242  // measIterEnd = outliersOnTracks->end();
243  // for ( ; measIter != measIterEnd; ++measIter)
244  // vec.push_back((*measIter));
245  // refit with the beamspot / vertex
246  newtrack = ((trtonly ? m_ITrackFitterTRT : m_ITrackFitter)
247  ->fit(Gaudi::Hive::currentContext(),
248  vec,
249  *origPerigee,
250  m_runOutlier,
251  hypo));
252  // now delete the vsvx
253  } else {
254  newtrack =
255  ((trtonly ? m_ITrackFitterTRT : m_ITrackFitter)
256  ->fit(Gaudi::Hive::currentContext(), **itr, m_runOutlier, hypo));
257  }
258  } // passed selection
259 
260  if (msgLvl(MSG::DEBUG)) {
261  if (!newtrack) ATH_MSG_DEBUG ("Refit Failed");
262  else {
263 
264  // ATH_MSG_VERBOSE ("re-fitted track:" << *newtrack);
265  const Trk::Perigee *aMeasPer=
266  dynamic_cast<const Trk::Perigee*>(newtrack->perigeeParameters () );
267  if (aMeasPer==nullptr){
268  msg(MSG::ERROR) << "Could not get Trk::MeasuredPerigee" << endmsg;
269  continue;
270  }
271  double d0 = aMeasPer->parameters()[Trk::d0];
272  double z0 = aMeasPer->parameters()[Trk::z0];
273  double phi0 = aMeasPer->parameters()[Trk::phi0];
274  double theta = aMeasPer->parameters()[Trk::theta];
275  double qOverP = aMeasPer->parameters()[Trk::qOverP];
276  ATH_MSG_DEBUG ("Refitted parameters " << d0 << " " << z0 << " " << phi0 << " " << theta << " " << qOverP);
277  }
278  }
279 
280  if (newtrack) {
281  new_tracks.push_back(std::move(newtrack));
282  }
283 
284  }
285 
286  ATH_MSG_VERBOSE ("Add PRDs to assoc tool.");
287 
288  // recreate the summaries on the final track collection with correct PRD tool
289  for(const std::unique_ptr<Trk::Track> &new_track : new_tracks ) {
290  if((m_assoTool->addPRDs(*prd_to_track_map, *new_track)).isFailure()) {ATH_MSG_WARNING("Failed to add PRDs to map");}
291  }
292 
293  ATH_MSG_VERBOSE ("Recalculate the summary");
294  // and copy tracks from vector of non-const tracks to collection of const tracks
295  std::unique_ptr<TrackCollection> new_track_collection = std::make_unique<TrackCollection>();
296  new_track_collection->reserve(new_tracks.size());
297  for(std::unique_ptr<Trk::Track> &new_track : new_tracks ) {
298  m_trkSummaryTool->computeAndReplaceTrackSummary(*new_track, false /* DO NOT suppress hole search*/);
299  new_track_collection->push_back(std::move(new_track));
300  }
301 
302  ATH_MSG_VERBOSE ("Save tracks");
303  ATH_CHECK(SG::WriteHandle<TrackCollection>(m_newTrackName).record(std::move(new_track_collection)));
304 
305  return StatusCode::SUCCESS;
306 }
307 
308 // Finalize method:
310 {
311  msg(MSG::INFO) << "ReFitTrack::finalize()" << endmsg;
312  return StatusCode::SUCCESS;
313 }
314 
316 {
317  // constrainVx
318  const Trk::RecVertex* constrainVx = nullptr;
319  if ( m_constrainFitMode == 2 ){
320  // Beamspot mode
321  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
322  // get vertex position and uncertainties from BeamCondSvc
323  constrainVx = new Trk::RecVertex(beamSpotHandle->beamVtx());
324  ATH_MSG_DEBUG("Track fit with BeamSpot constraint (x/y/z) = "
325  << constrainVx->position().x() << ", "
326  << constrainVx->position().y() << ", "
327  << constrainVx->position().z());
328  } else if (m_constrainFitMode ==1){
329  // Vertex mode
330  SG::ReadHandle<VxContainer> vxContainer (m_vxContainerName);
331  ATH_MSG_DEBUG("Track fit with vertex from collection '" << m_vxContainerName.key() << "'.");
332  if (!vxContainer.isValid())
333  ATH_MSG_WARNING("Track fit configured to use vertex constraint, but '" << m_vxContainerName.key() << "' could not be retrieved.");
334  else if (vxContainer->size() == 1 ) {
335  ATH_MSG_WARNING("Track fit configured to use vertex constraint, but '" << m_vxContainerName.key() << "' contains only dummy vertex.");
336  } else {
337  // only refit to the 'signal' vertex
338  constrainVx = new Trk::RecVertex( (*vxContainer)[0]->recVertex() ); // Just copy it to simplify ownership.
339  ATH_MSG_DEBUG("Track fit with Vertex constraint (x/y/z) = "
340  << constrainVx->position().x() << ", "
341  << constrainVx->position().y() << ", "
342  << constrainVx->position().z());
343  }
344  } else {
345  ATH_MSG_WARNING("Unknown constraint mode: "<< m_constrainFitMode);
346  }
347  return constrainVx;
348 }
DataVector::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
Trk::ReFitTrack::m_runOutlier
Trk::RunOutlierRemoval m_runOutlier
switch whether to run outlier logics or not
Definition: ReFitTrack.h:71
Trk::ReFitTrack::m_extrapolator
ToolHandle< Trk::IExtrapolator > m_extrapolator
the extrapolator for the consistent measurement frame
Definition: ReFitTrack.h:93
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
RecVertex.h
Trk::ReFitTrack::ReFitTrack
ReFitTrack()
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
TrackParameters.h
ReFitTrack.h
MeasurementBase.h
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:19
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PerigeeSurface.h
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
ParticleTest.tp
tp
Definition: ParticleTest.py:25
xAOD::pion
@ pion
Definition: TrackingPrimitives.h:196
Trk::z0
@ z0
Definition: ParamDefs.h:70
IExtrapolator.h
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
Trk::ReFitTrack::setupConstrainedFit
const Trk::RecVertex * setupConstrainedFit()
Definition: ReFitTrack.cxx:315
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
ParamDefs.h
Trk::ReFitTrack::m_vxContainerName
SG::ReadHandleKey< VxContainer > m_vxContainerName
Definition: ReFitTrack.h:88
Trk::RecVertex
Trk::RecVertex inherits from Trk::Vertex.
Definition: RecVertex.h:44
Trk::ParticleHypothesis
ParticleHypothesis
Definition: ParticleHypothesis.h:25
CxxUtils::vec
typename vecDetail::vec_typedef< T, N >::type vec
Define a nice alias for the vectorized type.
Definition: vec.h:207
Trk::ReFitTrack::finalize
virtual StatusCode finalize()
Definition: ReFitTrack.cxx:309
Trk::theta
@ theta
Definition: ParamDefs.h:72
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Trk::ReFitTrack::m_ITrackFitterTRT
ToolHandle< Trk::ITrackFitter > m_ITrackFitterTRT
the TRT refit tool
Definition: ReFitTrack.h:79
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Trk::ReFitTrack::initialize
virtual StatusCode initialize()
Definition: ReFitTrack.cxx:74
VertexOnTrack.h
Trk::ReFitTrack::m_ITrackFitter
ToolHandle< Trk::ITrackFitter > m_ITrackFitter
the refit tool
Definition: ReFitTrack.h:78
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
VxContainer.h
TrackSummary.h
Trk::Vertex::position
const Amg::Vector3D & position() const
return position of vertex
Definition: Vertex.cxx:72
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
Trk::ReFitTrack::m_matEffects
int m_matEffects
type of material interaction in extrapolation
Definition: ReFitTrack.h:72
AthAlgorithm
Definition: AthAlgorithm.h:47
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Trk::VertexOnTrack
Definition: VertexOnTrack.h:45
MuonValidation_CreateResolutionProfiles.fit
def fit(h, emin, emax)
Definition: MuonValidation_CreateResolutionProfiles.py:69
Trk::ReFitTrack::m_newTrackName
SG::WriteHandleKey< TrackCollection > m_newTrackName
Definition: ReFitTrack.h:68
Trk::Track::perigeeParameters
const Perigee * perigeeParameters() const
return Perigee.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:163
Trk::numberOfTRTHits
@ numberOfTRTHits
number of TRT outliers
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:79
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Trk::d0
@ d0
Definition: ParamDefs.h:69
Trk::ReFitTrack::m_trkSummaryTool
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trkSummaryTool
the track summary tool
Definition: ReFitTrack.h:80
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
Trk::ReFitTrack::m_trkSelectorTool
ToolHandle< Trk::ITrackSelectorTool > m_trkSelectorTool
the track selector tool
Definition: ReFitTrack.h:85
LocalParameters.h
Trk::ReFitTrack::m_constrainFitMode
unsigned int m_constrainFitMode
0 - not constrained, 1 - vertex, 2 - beamspot
Definition: ReFitTrack.h:87
Trk::ReFitTrack::m_trackName
SG::ReadHandleKey< TrackCollection > m_trackName
Definition: ReFitTrack.h:67
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::ReFitTrack::execute
virtual StatusCode execute()
Definition: ReFitTrack.cxx:136
DEBUG
#define DEBUG
Definition: page_access.h:11
Trk::ReFitTrack::m_usetrackhypo
bool m_usetrackhypo
Fit using particle hypothesis from input track
Definition: ReFitTrack.h:95
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:73
ITrackSelectorTool.h
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
ITrackFitter.h
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
Trk::phi0
@ phi0
Definition: ParamDefs.h:71
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
SCT_Monitoring::summary
@ summary
Definition: SCT_MonitoringNumbers.h:65