ATLAS Offline Software
OutwardsCombinedMuonTrackBuilder.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 // OutwardsCombinedMuonTrackBuilder
7 // AlgTool gathering material effects along a combined muon track, in
8 // particular the TSOS'es representing the calorimeter energy deposit and
9 // Coulomb scattering.
10 // The resulting track is fitted at the IP using the ITrackFitter interface.
11 //
14 
15 #include <cmath>
16 #include <iomanip>
17 
18 #include "AthenaKernel/Units.h"
25 #include "TrkTrack/Track.h"
28 #include "VxVertex/RecVertex.h"
30 namespace Rec {
31  inline double nDoF(const Trk::Track& track) {
32  if (track.fitQuality()) return track.fitQuality()->doubleNumberDoF();
33  return 0.;
34  }
35  inline double normalizedChi2(const Trk::Track& track) {
36  if (nDoF(track)) {
37  return track.fitQuality()->chiSquared() / nDoF(track);
38  }
39  return FLT_MAX;
40  }
42  const IInterface* parent) :
44 
46  ATH_MSG_INFO("Initializing OutwardsCombinedMuonTrackBuilder.");
47 
48  msg(MSG::INFO) << " with options: ";
49  if (m_allowCleanerVeto) msg(MSG::INFO) << " AllowCleanerVeto";
50  if (m_cleanCombined) msg(MSG::INFO) << " CleanCombined";
51  msg(MSG::INFO) << endmsg;
52 
53  if (!m_cleaner.empty()) {
54  ATH_CHECK(m_cleaner.retrieve());
55  ATH_MSG_INFO("Retrieved tool " << m_cleaner);
56  }
57 
58  if (!m_muonHoleRecovery.empty()) {
59  ATH_CHECK(m_muonHoleRecovery.retrieve());
60  ATH_MSG_INFO("Retrieved tool " << m_muonHoleRecovery);
61  }
62 
63  if (!m_muonErrorOptimizer.empty()) {
64  ATH_CHECK(m_muonErrorOptimizer.retrieve());
65  ATH_MSG_INFO("Retrieved tool " << m_muonErrorOptimizer);
66  }
67 
68  if (!m_fitter.empty()) {
69  ATH_CHECK(m_fitter.retrieve());
70  ATH_MSG_INFO("Retrieved tool " << m_fitter);
71  }
72 
73  if (!m_trackSummary.empty()) {
74  ATH_CHECK(m_trackSummary.retrieve());
75  ATH_MSG_INFO("Retrieved tool " << m_trackSummary);
76  }
77 
78  ATH_CHECK(m_trackingVolumesSvc.retrieve());
79  ATH_MSG_DEBUG("Retrieved Svc " << m_trackingVolumesSvc);
81  std::make_unique<Trk::Volume>(m_trackingVolumesSvc->volume(Trk::ITrackingVolumesSvc::MuonSpectrometerEntryLayer));
83  return StatusCode::SUCCESS;
84  }
85 
88  std::unique_ptr<Trk::Track> OutwardsCombinedMuonTrackBuilder::combinedFit(const EventContext& ctx,
89  const Trk::Track& indetTrack,
90  const Trk::Track& /*extrapolatedTrack*/,
91  const Trk::Track& spectrometerTrack) const {
92  ATH_MSG_VERBOSE("combinedFit:: ");
93 
94  std::unique_ptr<Trk::Track> combinedTrack = fit(ctx, indetTrack, spectrometerTrack, m_cleanCombined, Trk::muon);
95 
96  // add the track summary
97 
98  if (combinedTrack) m_trackSummary->updateTrack(*combinedTrack);
99 
100  return combinedTrack;
101  }
102 
103  std::unique_ptr<Trk::Track> OutwardsCombinedMuonTrackBuilder::indetExtension(const EventContext& ctx,
104  const Trk::Track& indetTrack,
105  const Trk::MeasurementSet& spectrometerMeas,
106  std::unique_ptr<Trk::TrackParameters> /*innerParameters*/,
107  std::unique_ptr<Trk::TrackParameters> /*middleParameters*/,
108  std::unique_ptr<Trk::TrackParameters> /*outerParameters*/) const {
109  ATH_MSG_VERBOSE("indetExtension fit::");
110 
111  auto trajectory = std::make_unique<Trk::TrackStates>();
112 
113  for ( const Trk::MeasurementBase* tsos : spectrometerMeas) {
114  trajectory->push_back(Muon::MuonTSOSHelper::createMeasTSOS(tsos->uniqueClone(), nullptr, Trk::TrackStateOnSurface::Measurement));
115  }
116 
118  Trk::Track inputtrack2(trackInfo, std::move(trajectory), nullptr);
119  std::unique_ptr<Trk::Track> track{fit(ctx, indetTrack, inputtrack2, m_cleanCombined, Trk::muon)};
120 
121  return track;
122  }
123 
124  std::unique_ptr<Trk::Track> OutwardsCombinedMuonTrackBuilder::standaloneFit( const EventContext&, const Trk::Track& /*spectrometerTrack*/,
125  const Amg::Vector3D&, const Trk::Vertex* /*vertex*/ ) const {
126  ATH_MSG_FATAL("This method should actually never be called");
127  return nullptr;
128  }
129 
130  std::unique_ptr<Trk::Track> OutwardsCombinedMuonTrackBuilder::standaloneRefit(const EventContext& ctx, const Trk::Track& combinedTrack,
131  const Amg::Vector3D& origin) const {
132  ATH_MSG_DEBUG(" start OutwardsCombinedMuonTrackBuilder standaloneRefit");
133 
134  ATH_MSG_DEBUG(" beam position bs " << origin);
135 
136  double vertex3DSigmaRPhi = 6.0;
137  double vertex3DSigmaZ = 60.0;
138 
139  auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
140 
141  bool addVertexRegion = true;
142  AmgSymMatrix(3) vertexRegionCovariance;
143  vertexRegionCovariance.setZero();
144  vertexRegionCovariance(0, 0) = vertex3DSigmaRPhi * vertex3DSigmaRPhi;
145  vertexRegionCovariance(1, 1) = vertex3DSigmaRPhi * vertex3DSigmaRPhi;
146  vertexRegionCovariance(2, 2) = vertex3DSigmaZ * vertex3DSigmaZ;
147 
148  Trk::RecVertex vertex(origin, vertexRegionCovariance);
149 
150  int itsos = 0;
151  Trk::TrackStates::const_iterator t = combinedTrack.trackStateOnSurfaces()->begin();
152 
153  // create perigee TSOS
154  for (; t != combinedTrack.trackStateOnSurfaces()->end(); ++t) {
155  itsos++;
156 
157  if ((**t).alignmentEffectsOnTrack()) continue;
158 
159  if ((**t).type(Trk::TrackStateOnSurface::Perigee)) {
160  const Trk::TrackParameters* pars = (**t).trackParameters();
161 
162  if (pars) {
163  const Trk::TrackStateOnSurface* TSOS = (**t).clone();
164  trackStateOnSurfaces->push_back(TSOS);
165 
166  // including vertex region pseudoMeas
167  if (addVertexRegion) {
168  auto vertexInFit = vertexOnTrack(pars, vertex);
169 
170  if (vertexInFit) {
171  std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> type;
173  trackStateOnSurfaces->push_back(
174  std::make_unique<Trk::TrackStateOnSurface>(std::move(vertexInFit), nullptr, nullptr, type));
175  ATH_MSG_DEBUG(" found Perigee and added vertex " << itsos);
176  }
177  }
178  break;
179  }
180  }
181  }
182 
183  //
184  // add ID Eloss
185  //
186  double Eloss = 0.;
187  for (; t != combinedTrack.trackStateOnSurfaces()->end(); ++t) {
188  itsos++;
189  if ((**t).alignmentEffectsOnTrack()) continue;
190  if (!(**t).trackParameters()) continue;
191 
192  if ((**t).materialEffectsOnTrack()) {
193  if (!m_indetVolume->inside((**t).trackParameters()->position())) break;
194 
195  double X0 = (**t).materialEffectsOnTrack()->thicknessInX0();
196 
197  const Trk::MaterialEffectsOnTrack* meot = dynamic_cast<const Trk::MaterialEffectsOnTrack*>((**t).materialEffectsOnTrack());
198 
199  if (meot) {
200  const Trk::EnergyLoss* energyLoss = meot->energyLoss();
201  if (energyLoss) {
202  Eloss += std::abs(energyLoss->deltaE());
203 
204  ATH_MSG_DEBUG("OutwardsCombinedMuonFit ID Eloss found r " << ((**t).trackParameters())->position().perp() << " z "
205  << ((**t).trackParameters())->position().z() << " value "
206  << energyLoss->deltaE() << " Eloss " << Eloss);
207 
208  const Trk::ScatteringAngles* scat = meot->scatteringAngles();
209 
210  if (scat) {
211  double sigmaDeltaPhi = scat->sigmaDeltaPhi();
212  double sigmaDeltaTheta = scat->sigmaDeltaTheta();
213 
214  auto energyLossNew = std::make_unique<Trk::EnergyLoss>(
215  energyLoss->deltaE(), energyLoss->sigmaDeltaE(), energyLoss->sigmaDeltaE(), energyLoss->sigmaDeltaE());
216 
217  Trk::ScatteringAngles scatNew{0., 0., sigmaDeltaPhi, sigmaDeltaTheta};
218 
219  const Trk::Surface& surfNew = (**t).trackParameters()->associatedSurface();
220 
221  std::bitset<Trk::MaterialEffectsBase::NumberOfMaterialEffectsTypes> meotPattern(0);
224 
225  auto meotNew =
226  std::make_unique<Trk::MaterialEffectsOnTrack>(X0,
227  scatNew,
228  std::move(energyLossNew),
229  surfNew,
230  meotPattern);
231 
232 
233  auto parsNew = ((**t).trackParameters())->uniqueClone();
234 
235  std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePatternScat(0);
236  typePatternScat.set(Trk::TrackStateOnSurface::Scatterer);
237 
238  std::unique_ptr<Trk::TrackStateOnSurface> newTSOS =
239  std::make_unique<Trk::TrackStateOnSurface>(nullptr, std::move(parsNew), std::move(meotNew), typePatternScat);
240 
241  trackStateOnSurfaces->push_back(std::move(newTSOS));
242  }
243  }
244  }
245  }
246  }
247 
248  ATH_MSG_DEBUG("OutwardsCombinedMuonFit Total ID Eloss " << Eloss << " nr of states " << itsos);
249 
250  // add Calo and MS TSOSs
251 
252  for (; t != combinedTrack.trackStateOnSurfaces()->end(); ++t) {
253  itsos++;
254 
255  if ((**t).alignmentEffectsOnTrack()) continue;
256 
257  trackStateOnSurfaces->push_back((**t).clone());
258  }
259 
260  ATH_MSG_DEBUG(" trackStateOnSurfaces found " << trackStateOnSurfaces->size() << " from total " << itsos);
261 
262  std::unique_ptr<Trk::Track> standaloneTrack =
263  std::make_unique<Trk::Track>(combinedTrack.info(), std::move(trackStateOnSurfaces), nullptr);
265 
266  std::unique_ptr<Trk::Track> refittedTrack = fit(ctx, *standaloneTrack, false, Trk::muon);
267 
268  if (!refittedTrack) {
269  ATH_MSG_DEBUG(" OutwardsCombinedMuonTrackBuilder standaloneRefit FAILED ");
270  return nullptr;
271  }
272 
273  ATH_MSG_DEBUG(" OutwardsCombinedMuonTrackBuilder standaloneRefit OK ");
274 
275  m_trackSummary->updateTrack(*refittedTrack);
276  return refittedTrack;
277  }
278 
280  std::unique_ptr<Trk::Track> OutwardsCombinedMuonTrackBuilder::fit(const EventContext& ctx, const Trk::Track& track,
281  const Trk::RunOutlierRemoval runOutlier,
282  const Trk::ParticleHypothesis particleHypothesis) const {
283  // check valid particleHypothesis
284  if (particleHypothesis != Trk::muon && particleHypothesis != Trk::nonInteracting) {
285  ATH_MSG_WARNING(" invalid particle hypothesis " << particleHypothesis
286  << " requested. Must be 0 or 2 (nonInteracting or muon) ");
287  return nullptr;
288  }
289 
290  // fit
291  std::unique_ptr<Trk::Track> fittedTrack{m_fitter->fit(ctx, track, false, particleHypothesis)};
292  if (!fittedTrack) return nullptr;
293 
294  // track cleaning
295  if (runOutlier) {
296  // fit with optimized spectrometer errors
297  if (!m_muonErrorOptimizer.empty() && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack)) {
298  ATH_MSG_VERBOSE(" perform spectrometer error optimization before cleaning ");
299 
300  std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*fittedTrack, ctx);
301  if (optimizedTrack) { fittedTrack.swap(optimizedTrack); }
302  }
303 
304  // muon cleaner
305  ATH_MSG_VERBOSE(" perform track cleaning... ");
306 
307  std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrack, ctx);
308  if (!cleanTrack) {
309  ATH_MSG_DEBUG(" cleaner veto ");
310  if (m_allowCleanerVeto && normalizedChi2(*fittedTrack)> m_badFitChi2) { fittedTrack.reset(); }
311  } else if (!(*cleanTrack->perigeeParameters() == *fittedTrack->perigeeParameters())) {
312  ATH_MSG_VERBOSE(" found and removed spectrometer outlier(s) ");
313  // this will probably never be fixed as the outwards combined
314  // builder is deprecated
315  fittedTrack.swap(cleanTrack);
316  }
317 
318  // FIXME: provide indet cleaner
319  ATH_MSG_VERBOSE(" finished cleaning");
320  }
321 
322  return fittedTrack;
323  }
324 
325  std::unique_ptr<Trk::Track> OutwardsCombinedMuonTrackBuilder::fit(const EventContext& ctx, const Trk::Track& indetTrack, const Trk::Track& extrapolatedTrack,
326  const Trk::RunOutlierRemoval runOutlier,
327  const Trk::ParticleHypothesis particleHypothesis) const {
328  // check valid particleHypothesis
329  if (particleHypothesis != Trk::muon && particleHypothesis != Trk::nonInteracting) {
330  ATH_MSG_WARNING(" invalid particle hypothesis " << particleHypothesis
331  << " requested. Must be 0 or 2 (nonInteracting or muon) ");
332  return nullptr;
333  }
334 
335  // fit
336  std::unique_ptr<Trk::Track> fittedTrack{m_fitter->fit(ctx, indetTrack, extrapolatedTrack, false, particleHypothesis)};
337 
338  if (!fittedTrack) { return nullptr; }
339 
340  if (!fittedTrack->perigeeParameters()) {
341  ATH_MSG_WARNING(" Fitter returned a track without perigee, failing fit");
342  return nullptr;
343  }
344 
345  // track cleaning
346  if (runOutlier) {
347  // fit with optimized spectrometer errors
348  if (!m_muonErrorOptimizer.empty() && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack)) {
349  ATH_MSG_VERBOSE(" perform spectrometer error optimization before cleaning ");
350  std::unique_ptr<Trk::Track> optimizedTrack{m_muonErrorOptimizer->optimiseErrors(*fittedTrack, ctx)};
351  if (optimizedTrack) {
352  // until code is updated to use unique_ptr or removed
353  fittedTrack.swap(optimizedTrack);
354  }
355  }
356  // muon cleaner
357  ATH_MSG_VERBOSE(" perform track cleaning... ");
358  std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrack, ctx);
359  if (!cleanTrack) {
360  ATH_MSG_DEBUG(" cleaner veto ");
361  if (m_allowCleanerVeto && normalizedChi2(*fittedTrack)> m_badFitChi2) { fittedTrack.reset(); }
362  } else if (!(*cleanTrack->perigeeParameters() == *fittedTrack->perigeeParameters())) {
363  ATH_MSG_VERBOSE(" found and removed spectrometer outlier(s) ");
364  // this will probably never be fixed as the outwards builder is
365  // deprecated
366  fittedTrack.swap(cleanTrack);
367  }
368 
369  ATH_MSG_VERBOSE(" finished cleaning");
370  }
371 
372  if (fittedTrack) {
373  std::unique_ptr<Trk::Track> newTrack{addIDMSerrors(*fittedTrack)};
374  if (newTrack) {
375  std::unique_ptr<Trk::Track> refittedTrack{fit(ctx, *newTrack, false, Trk::muon)};
377  if (refittedTrack) {
378  if (refittedTrack->fitQuality()) { fittedTrack.swap(refittedTrack); }
379  }
380  }
381  }
382 
383  if (m_recoverCombined && fittedTrack) {
384  std::unique_ptr<Trk::Track> recoveredTrack{m_muonHoleRecovery->recover(*fittedTrack, ctx)};
385  double oldfitqual = fittedTrack->fitQuality()->chiSquared() / fittedTrack->fitQuality()->numberDoF();
386 
387  if (recoveredTrack && recoveredTrack != fittedTrack) {
388  double newfitqual = recoveredTrack->fitQuality()->chiSquared() / recoveredTrack->fitQuality()->numberDoF();
389  if (newfitqual < oldfitqual || newfitqual < 1.5 || (newfitqual < 2 && newfitqual < oldfitqual + .5)) {
390  fittedTrack.swap(recoveredTrack);
391  }
392  }
393  /*
394  * DO NOT REMOVE THE CODE BELOW BECAUSE IT WILL BE NEEDED IN A FUTURE MR
395  using MSTrackRecovery = Muon::IMuonHoleRecoveryTool::MSTrackRecovery;
396  MSTrackRecovery recoverResult{};
397  do {
398  recoverResult = m_muonHoleRecovery->recover(ctx,*fittedTrack);
399  if (!recoverResult.track) {
400  ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" track got lost during hole recovery. That should not happen");
401  break;
402  }
404  if (recoverResult.new_meas) {
405  recoverResult.track = fit(ctx, *recoverResult.track, false, Trk::muon);
406  if (!recoverResult.track) {
407  ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" track got lost during refit of recovery.");
408  break;
409  }
410  const double oldFitQual = normalizedChi2(*fittedTrack);
411  const double newFitQual = normalizedChi2(*recoverResult.track);
413  if (newFitQual < oldFitQual) fittedTrack.swap(recoverResult.track);
414  else break;
415  } else std::swap(recoverResult.track, fittedTrack);
416 
417  } while (recoverResult.new_meas);
418  */
419  }
420  if (fittedTrack && !fittedTrack->perigeeParameters()) {
421  ATH_MSG_WARNING(" Fitter returned a track without perigee, failing fit");
422  return nullptr;
423  }
424 
425  if (runOutlier && fittedTrack) {
426  double fitqual = fittedTrack->fitQuality()->chiSquared() / fittedTrack->fitQuality()->numberDoF();
427 
428  if (fitqual > 5 || (fittedTrack->perigeeParameters()->pT() < 20000 && fitqual > 2.5)) {
429  fittedTrack.reset();
430  } else {
431  Trk::TrackStates::const_iterator itStates = fittedTrack->trackStateOnSurfaces()->begin();
432 
433  Trk::TrackStates::const_iterator endStates = fittedTrack->trackStateOnSurfaces()->end();
434 
435  for (; itStates != endStates; ++itStates) {
436  if ((*itStates)->materialEffectsOnTrack()) {
437  const Trk::MaterialEffectsOnTrack* meot =
438  dynamic_cast<const Trk::MaterialEffectsOnTrack*>((*itStates)->materialEffectsOnTrack());
439 
440  if (!meot) continue;
441 
442  if (meot->scatteringAngles() && !meot->energyLoss()) {
443  double pullphi = std::abs(meot->scatteringAngles()->deltaPhi() / meot->scatteringAngles()->sigmaDeltaPhi());
444 
445  double pulltheta =
446  std::abs(meot->scatteringAngles()->deltaTheta() / meot->scatteringAngles()->sigmaDeltaTheta());
447 
448  if (pullphi > 7 || pulltheta > 7) {
449  fittedTrack.reset();
450  break;
451  }
452  }
453  }
454  }
455  }
456  }
457 
458  // final fit with optimized spectrometer errors
459  if (!m_muonErrorOptimizer.empty() && fittedTrack && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack)) {
460  ATH_MSG_VERBOSE(" perform spectrometer error optimization... ");
461 
462  std::unique_ptr<Trk::Track> optimizedTrack{m_muonErrorOptimizer->optimiseErrors(*fittedTrack, ctx)};
463  if (optimizedTrack) {
464  // until the code uses unique ptrs (or is removed since it's deprecated)
465  fittedTrack.swap(optimizedTrack);
466  }
467  }
468  return fittedTrack;
469  }
470 
471  std::unique_ptr<Trk::Track> OutwardsCombinedMuonTrackBuilder::addIDMSerrors(const Trk::Track& track) const {
472  //
473  // take track and correct the two scattering planes in the Calorimeter
474  // to take into account m_IDMS_rzSigma and m_IDMS_xySigma
475  //
476  // returns a new Track
477  //
478  if (!m_addIDMSerrors) return nullptr;
479 
480  ATH_MSG_VERBOSE(" OutwardsCombinedMuonTrackBuilder addIDMSerrors to track ");
481 
482  Amg::Vector3D positionMS(0, 0, 0);
483  Amg::Vector3D positionCaloFirst(0, 0, 0);
484  Amg::Vector3D positionCaloLast(0, 0, 0);
485 
486  int itsos = 0;
487  int itsosCaloFirst = -1;
488  int itsosCaloLast = -1;
489  double p = -1.;
490 
491  Trk::TrackStates::const_iterator t = track.trackStateOnSurfaces()->begin();
492  for (; t != track.trackStateOnSurfaces()->end(); ++t) {
493  itsos++;
494 
495  if ((**t).trackParameters()) {
496  if (p == -1.) { p = (**t).trackParameters()->momentum().mag() / Gaudi::Units::GeV; }
497  if (m_indetVolume->inside((**t).trackParameters()->position())) { continue; }
498 
499  if ((**t).trackParameters()->position().mag() < 1000) { continue; }
500 
501  if (m_calorimeterVolume->inside((**t).trackParameters()->position())) {
502  // first scattering plane in Calorimeter
503  if ((**t).type(Trk::TrackStateOnSurface::Scatterer) && (**t).materialEffectsOnTrack()) {
504  double X0 = (**t).materialEffectsOnTrack()->thicknessInX0();
505 
506  if (X0 < 10) continue;
507 
508  if (itsosCaloFirst != -1) {
509  itsosCaloLast = itsos;
510  positionCaloLast = (**t).trackParameters()->position();
511  }
512 
513  if (itsosCaloFirst == -1) {
514  itsosCaloFirst = itsos;
515  positionCaloFirst = (**t).trackParameters()->position();
516  }
517  }
518  }
519  if (!m_calorimeterVolume->inside((**t).trackParameters()->position())) {
520  if ((**t).measurementOnTrack()) {
521  // inside muon system
522  positionMS = (**t).trackParameters()->position();
523  break;
524  }
525  }
526  }
527  }
528 
529  // it can happen that no Calorimeter Scatterers are found.
530 
531  ATH_MSG_DEBUG(" OutwardsCombinedMuonTrackBuilder addIDMSerrors p muon GeV "
532  << p << " First Calorimeter Scatterer radius " << positionCaloFirst.perp() << " z " << positionCaloFirst.z()
533  << " Second Scatterer r " << positionCaloLast.perp() << " z " << positionCaloLast.z() << " First Muon hit r "
534  << positionMS.perp() << " z " << positionMS.z());
535 
536  if (itsosCaloFirst < 0 || itsosCaloLast < 0) {
537  ATH_MSG_DEBUG(" addIDMSerrors keep original track ");
538  return nullptr;
539  }
540 
541  // If no Calorimeter no IDMS uncertainties have to be propagated
542  positionCaloFirst = positionCaloFirst - positionMS;
543  positionCaloLast = positionCaloLast - positionMS;
544 
545  double sigmaDeltaPhiIDMS2 = m_IDMS_xySigma / (positionCaloFirst.perp() + positionCaloLast.perp());
546  double sigmaDeltaThetaIDMS2 = m_IDMS_rzSigma / (positionCaloFirst.mag() + positionCaloLast.mag());
547 
548  sigmaDeltaPhiIDMS2 *= sigmaDeltaPhiIDMS2;
549  sigmaDeltaThetaIDMS2 *= sigmaDeltaThetaIDMS2;
550 
551  auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
552  trackStateOnSurfaces->reserve(track.trackStateOnSurfaces()->size());
553 
554  t = track.trackStateOnSurfaces()->begin();
555  itsos = 0;
556 
557  for (; t != track.trackStateOnSurfaces()->end(); ++t) {
558  itsos++;
559 
560  if ((**t).alignmentEffectsOnTrack()) { continue; }
561 
562  if (itsos == itsosCaloFirst || itsos == itsosCaloLast) {
563  if ((**t).materialEffectsOnTrack()) {
564  double X0 = (**t).materialEffectsOnTrack()->thicknessInX0();
565 
566  const Trk::MaterialEffectsOnTrack* meot =
567  dynamic_cast<const Trk::MaterialEffectsOnTrack*>((**t).materialEffectsOnTrack());
568 
569  if (meot) {
570  const Trk::ScatteringAngles* scat = meot->scatteringAngles();
571 
572  if (scat) {
573  double sigmaDeltaPhi = std::sqrt((scat->sigmaDeltaPhi()) * (scat->sigmaDeltaPhi()) + sigmaDeltaPhiIDMS2);
574 
575  double sigmaDeltaTheta =
576  std::sqrt((scat->sigmaDeltaTheta()) * (scat->sigmaDeltaTheta()) + sigmaDeltaThetaIDMS2);
577 
578  auto energyLossNew = std::make_unique<Trk::EnergyLoss>(0., 0., 0., 0.);
579 
580  auto scatNew = Trk::ScatteringAngles(0., 0., sigmaDeltaPhi, sigmaDeltaTheta);
581 
582  const Trk::Surface& surfNew = (**t).trackParameters()->associatedSurface();
583 
584  std::bitset<Trk::MaterialEffectsBase::NumberOfMaterialEffectsTypes> meotPattern(0);
587 
588  auto meotNew =
589  std::make_unique<Trk::MaterialEffectsOnTrack>(X0,
590  scatNew,
591  std::move(energyLossNew),
592  surfNew,
593  meotPattern);
594 
595  auto parsNew = ((**t).trackParameters())->uniqueClone();
596 
597  std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePatternScat(0);
598  typePatternScat.set(Trk::TrackStateOnSurface::Scatterer);
599 
600  const Trk::TrackStateOnSurface* newTSOS =
601  new Trk::TrackStateOnSurface(nullptr, std::move(parsNew), std::move(meotNew), typePatternScat);
602 
603  trackStateOnSurfaces->push_back(newTSOS);
604 
605  ATH_MSG_DEBUG(" old Calo scatterer had sigmaDeltaPhi mrad "
606  << scat->sigmaDeltaPhi() * 1000 << " sigmaDeltaTheta mrad " << scat->sigmaDeltaTheta() * 1000
607  << " X0 " << X0);
608 
609  ATH_MSG_DEBUG(" new Calo scatterer made with sigmaDeltaPhi mrad "
610  << sigmaDeltaPhi * 1000 << " sigmaDeltaTheta mrad " << sigmaDeltaTheta * 1000);
611  } else {
613  " This should not happen: no Scattering Angles for "
614  "scatterer ");
615  }
616  } else {
618  " This should not happen: no MaterialEffectsOnTrack "
619  "for "
620  "scatterer ");
621  }
622  }
623  } else {
624  const Trk::TrackStateOnSurface* TSOS = (**t).clone();
625  trackStateOnSurfaces->push_back(TSOS);
626  }
627  }
628  ATH_MSG_DEBUG(" trackStateOnSurfaces on input track " << track.trackStateOnSurfaces()->size() << " trackStateOnSurfaces found "
629  << trackStateOnSurfaces->size());
630 
631  return std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces), nullptr);
632  }
633 
634  std::unique_ptr<Trk::PseudoMeasurementOnTrack>
636  const Trk::RecVertex& vertex) {
637  // create the corresponding PerigeeSurface, localParameters and
638  // covarianceMatrix
639  const Trk::PerigeeSurface surface(vertex.position());
640 
641  Trk::LocalParameters localParameters;
642 
643  Amg::MatrixX covarianceMatrix;
644  covarianceMatrix.setZero();
645 
646  // transform Cartesian (x,y,z) to beam axis or perigee
647  Amg::Vector2D localPosition(0, 0);
648 
649  double ptInv = 1. / parameters->momentum().perp();
650 
651  localParameters = Trk::LocalParameters(localPosition);
652 
653  Amg::MatrixX jacobian(2, 3);
654  jacobian.setZero();
655  jacobian(0, 0) = -ptInv * parameters->momentum().y();
656  jacobian(0, 1) = ptInv * parameters->momentum().x();
657  jacobian(1, 2) = 1.0;
658 
659  const Amg::MatrixX& cov = vertex.covariancePosition();
660  covarianceMatrix = cov.similarity(jacobian);
661 
662  return std::make_unique<Trk::PseudoMeasurementOnTrack>(std::move(localParameters),
663  std::move(covarianceMatrix),
664  surface);
665  }
667  double chi2 = 999999.;
668  if (track.fitQuality()) {
669  if (track.fitQuality()->numberDoF()) {
670  chi2 = track.fitQuality()->chiSquared() / track.fitQuality()->doubleNumberDoF();
671  } else {
672  chi2 = m_badFitChi2;
673  }
674  }
675 
676  return chi2;
677  }
678 } // namespace Rec
Trk::ScatteringAngles::deltaPhi
double deltaPhi() const
returns the
Definition: ScatteringAngles.h:82
Rec::OutwardsCombinedMuonTrackBuilder::m_addIDMSerrors
Gaudi::Property< bool > m_addIDMSerrors
Definition: OutwardsCombinedMuonTrackBuilder.h:134
RecVertex.h
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
Rec::OutwardsCombinedMuonTrackBuilder::fit
std::unique_ptr< Trk::Track > fit(const EventContext &ctx, const Trk::Track &track, const Trk::RunOutlierRemoval runOutlier, const Trk::ParticleHypothesis particleHypothesis) const
refit a track
Definition: OutwardsCombinedMuonTrackBuilder.cxx:280
Rec::OutwardsCombinedMuonTrackBuilder::m_fitter
ToolHandle< Trk::ITrackFitter > m_fitter
Definition: OutwardsCombinedMuonTrackBuilder.h:94
Trk::LocalParameters
Definition: LocalParameters.h:98
Trk::Vertex
Definition: Tracking/TrkEvent/VxVertex/VxVertex/Vertex.h:26
EnergyLoss.h
Trk::TrackInfo
Contains information about the 'fitter' of this track.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/TrackInfo.h:32
Trk::TrackStateOnSurface::Perigee
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
Definition: TrackStateOnSurface.h:117
ScatteringAngles.h
Rec::OutwardsCombinedMuonTrackBuilder::standaloneRefit
virtual std::unique_ptr< Trk::Track > standaloneRefit(const EventContext &ctx, const Trk::Track &combinedTrack, const Amg::Vector3D &bs) const override
ICombinedMuonTrackBuilder interface: refit a track removing any indet measurements with optional addi...
Definition: OutwardsCombinedMuonTrackBuilder.cxx:130
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
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:29
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
TrackParameters.h
MeasurementBase.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
OutwardsCombinedMuonTrackBuilder.h
Rec::OutwardsCombinedMuonTrackBuilder::vertexOnTrack
static std::unique_ptr< Trk::PseudoMeasurementOnTrack > vertexOnTrack(const Trk::TrackParameters *parameters, const Trk::RecVertex &vertex)
Definition: OutwardsCombinedMuonTrackBuilder.cxx:635
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
Trk::TrackStateOnSurface::clone
virtual TrackStateOnSurface * clone() const
Pseudo-constructor: needed to avoid excessive RTTI.
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
Trk::Track::info
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
Trk::TrackInfo::MuidStandaloneRefit
@ MuidStandaloneRefit
Standalone muon that was obtained by refitting a combined muon using the calorimeter information of t...
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/TrackInfo.h:233
Trk::ITrackingVolumesSvc::MuonSpectrometerEntryLayer
@ MuonSpectrometerEntryLayer
Tracking Volume which defines the entrance surfaces of the MS.
Definition: ITrackingVolumesSvc.h:41
Trk::EnergyLoss::sigmaDeltaE
double sigmaDeltaE() const
returns the symmatric error
Rec::OutwardsCombinedMuonTrackBuilder::addIDMSerrors
std::unique_ptr< Trk::Track > addIDMSerrors(const Trk::Track &track) const
Definition: OutwardsCombinedMuonTrackBuilder.cxx:471
Rec::OutwardsCombinedMuonTrackBuilder::combinedFit
virtual std::unique_ptr< Trk::Track > combinedFit(const EventContext &ctx, const Trk::Track &indetTrack, const Trk::Track &extrapolatedTrack, const Trk::Track &spectrometerTrack) const override
ICombinedMuonTrackBuilder interface: build and fit combined ID/Calo/MS track.
Definition: OutwardsCombinedMuonTrackBuilder.cxx:88
Rec::OutwardsCombinedMuonTrackBuilder::m_trackingVolumesSvc
ServiceHandle< Trk::ITrackingVolumesSvc > m_trackingVolumesSvc
Definition: OutwardsCombinedMuonTrackBuilder.h:122
uniqueClone
std::unique_ptr< T_Obj > uniqueClone(const T_Obj *obj)
Definition: ObjContainer.h:49
Trk::ScatteringAngles
represents a deflection of the track caused through multiple scattering in material.
Definition: ScatteringAngles.h:26
Rec::OutwardsCombinedMuonTrackBuilder::m_muonHoleRecovery
ToolHandle< Muon::IMuonHoleRecoveryTool > m_muonHoleRecovery
Definition: OutwardsCombinedMuonTrackBuilder.h:108
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::combinedTrack
void combinedTrack(long int ICH, double *pv0, double *covi, double BMAG, double *par, double *covo)
Definition: XYZtrp.cxx:113
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
Trk::RecVertex
Trk::RecVertex inherits from Trk::Vertex.
Definition: RecVertex.h:44
Trk::RunOutlierRemoval
bool RunOutlierRemoval
switch to toggle quality processing after fit
Definition: FitterTypes.h:22
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
Track.h
Rec::nDoF
double nDoF(const Trk::Track &track)
Definition: OutwardsCombinedMuonTrackBuilder.cxx:31
Rec::OutwardsCombinedMuonTrackBuilder::OutwardsCombinedMuonTrackBuilder
OutwardsCombinedMuonTrackBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Definition: OutwardsCombinedMuonTrackBuilder.cxx:41
MaterialEffectsOnTrack.h
Trk::TrackInfo::StraightTrack
@ StraightTrack
A straight track.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/TrackInfo.h:84
pdg_comparison.X0
X0
Definition: pdg_comparison.py:314
Trk::ParticleHypothesis
ParticleHypothesis
Definition: ParticleHypothesis.h:25
Trk::MaterialEffectsOnTrack
represents the full description of deflection and e-loss of a track in material.
Definition: MaterialEffectsOnTrack.h:40
MuonTSOSHelper.h
Trk::ScatteringAngles::sigmaDeltaTheta
double sigmaDeltaTheta() const
returns the
Definition: ScatteringAngles.h:100
Rec::OutwardsCombinedMuonTrackBuilder::initialize
virtual StatusCode initialize() override
Definition: OutwardsCombinedMuonTrackBuilder.cxx:45
Rec
Name: MuonSpContainer.h Package : offline/Reconstruction/MuonIdentification/muonEvent.
Definition: FakeTrackBuilder.h:10
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
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Muon::MuonTSOSHelper::createMeasTSOS
static std::unique_ptr< Trk::TrackStateOnSurface > createMeasTSOS(std::unique_ptr< Trk::MeasurementBase > meas, std::unique_ptr< Trk::TrackParameters > pars, Trk::TrackStateOnSurface::TrackStateOnSurfaceType type)
create a TSOS with a measurement, takes ownership of the pointers
Definition: MuonTSOSHelper.h:62
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:522
Trk::EnergyLoss::deltaE
double deltaE() const
returns the
PseudoMeasurementOnTrack.h
Trk::MaterialEffectsBase::ScatteringEffects
@ ScatteringEffects
contains material effects due to multiple scattering
Definition: MaterialEffectsBase.h:45
test_pyathena.parent
parent
Definition: test_pyathena.py:15
Rec::OutwardsCombinedMuonTrackBuilder::m_calorimeterVolume
std::unique_ptr< Trk::Volume > m_calorimeterVolume
Definition: OutwardsCombinedMuonTrackBuilder.h:124
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TrackSummary.h
Trk::ParametersBase
Definition: ParametersBase.h:55
Rec::OutwardsCombinedMuonTrackBuilder::normalizedChi2
double normalizedChi2(const Trk::Track &track) const
Definition: OutwardsCombinedMuonTrackBuilder.cxx:666
Trk::muon
@ muon
Definition: ParticleHypothesis.h:28
Rec::OutwardsCombinedMuonTrackBuilder::m_badFitChi2
Gaudi::Property< double > m_badFitChi2
Definition: OutwardsCombinedMuonTrackBuilder.h:136
trackInfo
Definition: TrigInDetUtils.h:13
Trk::ITrackingVolumesSvc::CalorimeterEntryLayer
@ CalorimeterEntryLayer
Tracking Volume which defines the entrance srufaces of the calorimeter.
Definition: ITrackingVolumesSvc.h:40
Trk::MeasurementSet
std::vector< const MeasurementBase * > MeasurementSet
vector of fittable measurements
Definition: FitterTypes.h:30
Trk::MeasurementBase
Definition: MeasurementBase.h:58
Trk::Track::perigeeParameters
const Perigee * perigeeParameters() const
return Perigee.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:163
Rec::OutwardsCombinedMuonTrackBuilder::m_IDMS_xySigma
Gaudi::Property< double > m_IDMS_xySigma
Definition: OutwardsCombinedMuonTrackBuilder.h:132
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
Trk::nonInteracting
@ nonInteracting
Definition: ParticleHypothesis.h:25
Trk::EnergyLoss
This class describes energy loss material effects in the ATLAS tracking EDM.
Definition: EnergyLoss.h:34
Rec::normalizedChi2
double normalizedChi2(const Trk::Track &track)
Definition: OutwardsCombinedMuonTrackBuilder.cxx:35
Units.h
Wrapper to avoid constant divisions when using units.
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::MaterialEffectsBase::EnergyLossEffects
@ EnergyLossEffects
contains energy loss corrections
Definition: MaterialEffectsBase.h:48
Rec::OutwardsCombinedMuonTrackBuilder::standaloneFit
virtual std::unique_ptr< Trk::Track > standaloneFit(const EventContext &ctx, const Trk::Track &spectrometerTrack, const Amg::Vector3D &bs, const Trk::Vertex *vertex) const override
ICombinedMuonTrackBuilder interface: propagate to perigee adding calo energy-loss and material to MS ...
Definition: OutwardsCombinedMuonTrackBuilder.cxx:124
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
Trk::MaterialEffectsOnTrack::energyLoss
const EnergyLoss * energyLoss() const
returns the energy loss object.
Rec::OutwardsCombinedMuonTrackBuilder::m_recoverCombined
Gaudi::Property< bool > m_recoverCombined
Definition: OutwardsCombinedMuonTrackBuilder.h:131
Rec::OutwardsCombinedMuonTrackBuilder::m_cleanCombined
Gaudi::Property< bool > m_cleanCombined
Definition: OutwardsCombinedMuonTrackBuilder.h:130
Rec::OutwardsCombinedMuonTrackBuilder::indetExtension
virtual std::unique_ptr< Trk::Track > indetExtension(const EventContext &ctx, const Trk::Track &indetTrack, const Trk::MeasurementSet &spectrometerMeas, std::unique_ptr< Trk::TrackParameters > innerParameters, std::unique_ptr< Trk::TrackParameters > middleParameters, std::unique_ptr< Trk::TrackParameters > outerParameters) const override
ICombinedMuonTrackBuilder interface: build and fit indet track extended to include MS Measurement set...
Definition: OutwardsCombinedMuonTrackBuilder.cxx:103
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Rec::OutwardsCombinedMuonTrackBuilder::m_IDMS_rzSigma
Gaudi::Property< double > m_IDMS_rzSigma
Definition: OutwardsCombinedMuonTrackBuilder.h:133
Trk::MaterialEffectsOnTrack::scatteringAngles
const ScatteringAngles * scatteringAngles() const
returns the MCS-angles object.
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
Rec::OutwardsCombinedMuonTrackBuilder::m_indetVolume
std::unique_ptr< Trk::Volume > m_indetVolume
Definition: OutwardsCombinedMuonTrackBuilder.h:125
Trk::ScatteringAngles::sigmaDeltaPhi
double sigmaDeltaPhi() const
returns the
Definition: ScatteringAngles.h:94
Rec::OutwardsCombinedMuonTrackBuilder::m_trackSummary
ToolHandle< Trk::ITrackSummaryTool > m_trackSummary
Definition: OutwardsCombinedMuonTrackBuilder.h:101
Trk::TrackStateOnSurface::Scatterer
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
Definition: TrackStateOnSurface.h:113
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
Rec::OutwardsCombinedMuonTrackBuilder::m_allowCleanerVeto
Gaudi::Property< bool > m_allowCleanerVeto
Definition: OutwardsCombinedMuonTrackBuilder.h:129
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
Trk::TrackInfo::setPatternRecognitionInfo
void setPatternRecognitionInfo(const TrackPatternRecoInfo &patternReco)
Method setting the pattern recognition algorithm.
Trk::ScatteringAngles::deltaTheta
double deltaTheta() const
returns the
Definition: ScatteringAngles.h:88
AthAlgTool
Definition: AthAlgTool.h:26
Rec::OutwardsCombinedMuonTrackBuilder::m_muonErrorOptimizer
ToolHandle< Muon::IMuonErrorOptimisationTool > m_muonErrorOptimizer
Definition: OutwardsCombinedMuonTrackBuilder.h:115
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
Rec::OutwardsCombinedMuonTrackBuilder::m_cleaner
ToolHandle< Muon::IMuonTrackCleaner > m_cleaner
Definition: OutwardsCombinedMuonTrackBuilder.h:87
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
Trk::TrackStateOnSurface::Measurement
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
Definition: TrackStateOnSurface.h:101
TrackStateOnSurface.h
Trk::TrackInfo::Unknown
@ Unknown
Track fitter not defined.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/TrackInfo.h:41