ATLAS Offline Software
Loading...
Searching...
No Matches
MuonRefitTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "MuonRefitTool.h"
6
21#include "TrkSurfaces/Surface.h"
23#include "TrkTrack/Track.h"
27
28namespace Muon {
29 using namespace MuonStationIndex;
44
46 ATH_MSG_INFO("Initializing MuonRefitTool " << name());
47
48 ATH_CHECK(m_printer.retrieve());
49 ATH_CHECK(m_edmHelperSvc.retrieve());
50 ATH_CHECK(m_idHelperSvc.retrieve());
51 m_BME_station = m_idHelperSvc->mdtIdHelper().stationNameIndex("BME");
52
54 if (!m_alignErrorTool.empty()) ATH_CHECK(m_alignErrorTool.retrieve());
55 } else {
56 m_alignErrorTool.disable();
57 }
58 ATH_CHECK(m_muonExtrapolator.retrieve());
59 ATH_CHECK(m_trackFitter.retrieve());
60
61 ATH_MSG_INFO("Retrieved " << m_trackFitter);
62
63 ATH_CHECK(m_mdtRotCreator.retrieve());
64 if (!m_compClusterCreator.empty()) ATH_CHECK(m_compClusterCreator.retrieve());
65
66 if (!m_t0Fitter.empty()) {
67 ATH_CHECK(m_t0Fitter.retrieve());
68 ATH_MSG_INFO("Retrieved " << m_t0Fitter);
69 }
70
72
74 MuonDriftCircleErrorStrategy strategy(bits);
75 strategy.setParameter(MuonDriftCircleErrorStrategy::BroadError, false);
76 strategy.setParameter(MuonDriftCircleErrorStrategy::ScaledError, false);
77 strategy.setParameter(MuonDriftCircleErrorStrategy::FixedError, false);
78 strategy.setParameter(MuonDriftCircleErrorStrategy::ParameterisedErrors, false);
79 strategy.setParameter(MuonDriftCircleErrorStrategy::StationError, false);
81 strategy.setParameter(MuonDriftCircleErrorStrategy::T0Refit, false);
82 strategy.setParameter(MuonDriftCircleErrorStrategy::TofCorrection, false);
83 strategy.setParameter(MuonDriftCircleErrorStrategy::PropCorrection, false);
84 strategy.setParameter(MuonDriftCircleErrorStrategy::TempCorrection, false);
85 strategy.setParameter(MuonDriftCircleErrorStrategy::MagFieldCorrection, false);
86 strategy.setParameter(MuonDriftCircleErrorStrategy::SlewCorrection, false);
87 strategy.setParameter(MuonDriftCircleErrorStrategy::BackgroundCorrection, false);
88 strategy.setParameter(MuonDriftCircleErrorStrategy::Segment, false);
89
90 m_errorStrategyBEE = strategy;
92
95
96 m_errorStrategyEE = strategy;
98
99 m_errorStrategyBIS78 = strategy;
101
102 m_errorStrategyBXE = strategy;
104
105 m_errorStrategyEEL1C05 = strategy;
107
108 m_errorStrategySL = strategy;
111
112 m_errorStrategyBarEnd = strategy;
115
116 m_errorStrategy = strategy;
119
123
124 ATH_MSG_INFO("Options:");
125 if (m_deweightBEE) ATH_MSG_INFO(" Deweight BEE");
126 if (m_deweightEE) ATH_MSG_INFO(" Deweight EE");
127 if (m_deweightBIS78) ATH_MSG_INFO(" Deweight BIS78");
128 if (m_deweightBME) ATH_MSG_INFO(" Deweight BME");
129 if (m_deweightBOE) ATH_MSG_INFO(" Deweight BOE");
130 if (m_deweightEEL1C05) ATH_MSG_INFO(" Deweight EEL1C05");
131 if (m_deweightTwoStationTracks) ATH_MSG_INFO(" Deweight Two stations");
132 return StatusCode::SUCCESS;
133 }
134
136 double scaleRefit = m_nrefits != 0 ? 1. / (double)m_nrefits : 1.;
137 ATH_MSG_INFO("Number of refits "
138 << m_nrefits << std::endl
139 << "Good " << scaleRefit * m_ngoodRefits << std::endl
140 << "Failed Outlier removal " << scaleRefit * m_failedOutlierRemoval << std::endl
141 << "Failed Error Update " << scaleRefit * m_failedErrorUpdate << std::endl
142 << "Failed Refit " << scaleRefit * m_failedRefit << std::endl
143 << "Failed Extrapolation to Muon Entry " << scaleRefit * m_failedExtrapolationMuonEntry);
144 return StatusCode::SUCCESS;
145 }
146 std::unique_ptr<Trk::Track> MuonRefitTool::refit(const Trk::Track& track, const EventContext& ctx,
147 const IMuonRefitTool::Settings* set) const {
148 const IMuonRefitTool::Settings& settings = set ? *set : m_defaultSettings;
149
150 // to keep track of the latest track
151 std::unique_ptr<Trk::Track> newTrack;
152 ++m_nrefits;
153 if (settings.removeOutliers) {
154 std::unique_ptr<Trk::Track> cleanedTrack = removeOutliers(track, settings);
155 if (!cleanedTrack) {
156 ATH_MSG_DEBUG("Track lost during outlier removal");
158 return std::make_unique<Trk::Track>(track);
159 }
160 if (cleanedTrack->perigeeParameters() != track.perigeeParameters()) {
161 ATH_MSG_DEBUG("Outlier removal removed hits from track");
162 }
163 newTrack.swap(cleanedTrack);
164 } else
165 newTrack = std::make_unique<Trk::Track>(track);
166
167 if (settings.updateErrors) {
168 ATH_MSG_DEBUG("track hits before error updating: " << m_printer->printMeasurements(*newTrack));
169 std::unique_ptr<Trk::Track> updateErrorTrack =
170 m_alignmentErrors ? updateAlignmentErrors(*newTrack, ctx, settings) : updateErrors(*newTrack, ctx, settings);
171 if (!updateErrorTrack) {
172 ATH_MSG_WARNING("Failed to update errors");
174 return newTrack;
175 }
176 newTrack.swap(updateErrorTrack);
177 }
178
179 if (settings.refit) {
180 ATH_MSG_DEBUG("Original track" << m_printer->print(track));
181
182 // do not put AEOTs on extremely bad chi2 tracks and do not refit them
183
184 std::unique_ptr<Trk::Track> refittedTrack;
185 if (track.fitQuality() && track.fitQuality()->chiSquared() < 10000 * track.fitQuality()->numberDoF())
186 refittedTrack = std::unique_ptr<Trk::Track>(m_trackFitter->fit(ctx, *newTrack, false, Trk::muon));
187 if (!refittedTrack) {
188 ATH_MSG_DEBUG("Failed to refit track");
190 // BUG fix Peter
191 return std::make_unique<Trk::Track>(track);
192 }
193 ATH_MSG_DEBUG("Refitted track" << m_printer->print(*refittedTrack));
194 ATH_MSG_DEBUG("Refitted track" << m_printer->printMeasurements(*refittedTrack));
195 newTrack.swap(refittedTrack);
196 }
197
198 if (settings.extrapolateToMuonEntry) {
199 std::unique_ptr<Trk::Track> extrapolatedTrack(m_muonEntryTrackExtrapolator->extrapolate(*newTrack, ctx));
200 if (!extrapolatedTrack) {
201 ATH_MSG_WARNING("Failed to back-extrapolate track");
203 return newTrack;
204 }
205 ATH_MSG_DEBUG("Entry track " << m_printer->print(*extrapolatedTrack));
206 newTrack.swap(extrapolatedTrack);
207 }
209
210 return newTrack;
211 }
212 std::vector<std::unique_ptr<Trk::Track>> MuonRefitTool::refit(const std::vector<Trk::Track*>& tracks, const EventContext& ctx,
213 const IMuonRefitTool::Settings* set) const {
214 std::vector<std::unique_ptr<Trk::Track>> refittedTracks;
215 refittedTracks.reserve(tracks.size());
216 for (const Trk::Track* it : tracks) { refittedTracks.emplace_back(refit(*it, ctx, set)); }
217
218 return refittedTracks;
219 }
220
221 std::unique_ptr<Trk::Track> MuonRefitTool::updateAlignmentErrors(const Trk::Track& track, const EventContext& ctx,
222 const IMuonRefitTool::Settings& settings) const {
223 // first scale the Mdt errors
224
225 std::unique_ptr<Trk::Track> updatedTrack = updateMdtErrors(track, ctx, settings);
226
227 std::unique_ptr<Trk::Track> updatedAEOTsTrack = m_simpleAEOTs ? makeSimpleAEOTs(*updatedTrack) : makeAEOTs(*updatedTrack);
228
229 return updatedAEOTsTrack;
230 }
231
232 std::unique_ptr<Trk::Track> MuonRefitTool::makeAEOTs(const Trk::Track& track) const {
233 //
234 // use the new AlignmentEffectsOnTrack class and alignmentErrorTool
235 //
236 if (m_alignErrorTool.empty()) { return std::make_unique<Trk::Track>(track); }
237 //
238 // Use the alignmentErrorTool and store a list of hits with error on position and angle
239 //
240 std::map<std::vector<Identifier>, std::pair<double, double>> alignerrmap;
241
242 std::vector<Trk::AlignmentDeviation*> align_deviations;
243 m_alignErrorTool->makeAlignmentDeviations(track, align_deviations);
244
245 int iok = 0;
246 bool isSmallChamber = false;
247 bool isLargeChamber = false;
248 bool isEndcap = false;
249 bool isBarrel = false;
250 std::vector<int> usedRotations;
251
252 // loop on deviations
253 for (Trk::AlignmentDeviation* it : align_deviations) {
254 double angleError = 0.;
255 double translationError = 0.;
256 bool differentChambers = false;
257 int jdifferent = -1;
258 isSmallChamber = false;
259 isLargeChamber = false;
260 isEndcap = false;
261 isBarrel = false;
262
263 if (dynamic_cast<MuonAlign::AlignmentTranslationDeviation*>(it)) {
264 translationError = std::sqrt(it->getCovariance(0, 0));
265 // vector to store hit id
266 std::vector<Identifier> hitids;
267 const auto& vec_riowithdev = it->getListOfHits();
268 // bool to decide if deviation should be skipped (if it's for more than 1 station)
269 for (const Trk::RIO_OnTrack* riowithdev : vec_riowithdev) {
270 const Identifier id_riowithdev = riowithdev->identify();
271 if (m_idHelperSvc->isEndcap(id_riowithdev)) {
272 isEndcap = true;
273 } else {
274 isBarrel = true;
275 }
276 if (m_idHelperSvc->isSmallChamber(id_riowithdev)) {
277 isSmallChamber = true;
278 } else {
279 isLargeChamber = true;
280 }
281 hitids.push_back(id_riowithdev);
282 if (hitids.size() > 1 && m_idHelperSvc->chamberId(id_riowithdev) != m_idHelperSvc->chamberId(hitids[0])) {
283 differentChambers = true;
284 jdifferent = hitids.size() - 1;
285 }
286 }
287 bool matchFound = false;
288 if (!hitids.empty()) {
289 int iRot = -1;
290 for (Trk::AlignmentDeviation* itRot : align_deviations) {
291 ++iRot;
292 if (dynamic_cast<MuonAlign::AlignmentRotationDeviation*>(itRot)) {
293 if (itRot->hasValidHashOfHits() && it->hasValidHashOfHits()) {
294 if (itRot->getHashOfHits() == it->getHashOfHits()) {
295 angleError = std::sqrt(itRot->getCovariance(0, 0));
296 matchFound = true;
297 usedRotations.push_back(iRot);
298 }
299 } else {
300 ATH_MSG_ERROR("One of the alignment deviations has an invalid hash created from the hits.");
301 }
302 }
303 if (matchFound) break;
304 }
305 }
306 // if deviation is accepted (i.e. only on one station) store the hit IDs associated with the deviation and the error
307
308 // store (all) translationError with or without a matched angleError
309 iok++;
310 alignerrmap.insert(std::pair<std::vector<Identifier>, std::pair<double, double>>(
311 hitids, std::pair<double, double>(translationError, angleError)));
312
313 if (matchFound)
314 ATH_MSG_DEBUG(" AlignmentMap entry " << iok << " filled with nr hitids " << hitids.size() << " "
315 << m_idHelperSvc->toString(hitids[0]) << " translationError " << translationError
316 << " angleError " << angleError);
317 if (!matchFound)
318 ATH_MSG_DEBUG(" AlignmentMap entry No angleError" << iok << " filled with nr hitids " << hitids.size() << " "
319 << m_idHelperSvc->toString(hitids[0]) << " translationError "
320 << translationError << " angleError " << angleError);
321 if (isEndcap) ATH_MSG_DEBUG(" AlignmentMap Endcap Chamber ");
322 if (isBarrel) ATH_MSG_DEBUG(" AlignmentMap Barrel Chamber ");
323 if (isSmallChamber) ATH_MSG_DEBUG(" AlignmentMap Small Chamber ");
324 if (isLargeChamber) ATH_MSG_DEBUG(" AlignmentMap Large Chamber ");
325 if (differentChambers)
326 ATH_MSG_DEBUG(" AlignmentMap entry " << iok << " for different Chamber "
327 << m_idHelperSvc->toString(hitids[jdifferent]));
328 }
329 }
330
331 // now add the angleErrors that were NOT matched to a translationError
332
333 int iRot = -1;
334 for (Trk::AlignmentDeviation* itRot : align_deviations) {
335 ++iRot;
336 isSmallChamber = false;
337 isLargeChamber = false;
338 isEndcap = false;
339 isBarrel = false;
340 if (dynamic_cast<MuonAlign::AlignmentRotationDeviation*>(itRot)) {
341 bool used = std::find(usedRotations.begin(), usedRotations.end(), iRot) != usedRotations.end();
342 if (used) continue;
343 ATH_MSG_ERROR("This following code should not be reached anymore!");
344 const auto& vec_riowithdev = itRot->getListOfHits();
345
346 std::vector<Identifier> hitids;
347 // bool to decide if deviation should be skipped (if it's for more than 1 station)
348 for (const Trk::RIO_OnTrack* riowithdev : vec_riowithdev) {
349 Identifier id_riowithdev = riowithdev->identify();
350 if (m_idHelperSvc->isEndcap(id_riowithdev)) {
351 isEndcap = true;
352 } else {
353 isBarrel = true;
354 }
355 if (m_idHelperSvc->isSmallChamber(id_riowithdev)) {
356 isSmallChamber = true;
357 } else {
358 isLargeChamber = true;
359 }
360 hitids.push_back(id_riowithdev);
361 }
362
363 double translationError = 0.;
364 double angleError = std::sqrt(itRot->getCovariance(0, 0));
365
366 iok++;
367 alignerrmap.insert(std::pair<std::vector<Identifier>, std::pair<double, double>>(
368 hitids, std::pair<double, double>(translationError, angleError)));
369 ATH_MSG_DEBUG(" AlignmentMap entry No Translation Error " << iok << " filled with nr hitids " << hitids.size() << " "
370 << m_idHelperSvc->toString(hitids[0]) << " translationError "
371 << translationError << " angleError " << angleError);
372 if (isEndcap) ATH_MSG_DEBUG(" AlignmentMap Endcap Chamber");
373 if (isBarrel) ATH_MSG_DEBUG(" AlignmentMap Barrel Chamber");
374 if (isSmallChamber) ATH_MSG_DEBUG(" AlignmentMap Small Chamber ");
375 if (isLargeChamber) ATH_MSG_DEBUG(" AlignmentMap Large Chamber ");
376 }
377 }
378
379 // clean-up of alignment deviations
380 for (auto* it : align_deviations) delete it;
381 align_deviations.clear();
382
383 const Trk::TrackStates* states = track.trackStateOnSurfaces();
384 if (!states) {
385 ATH_MSG_WARNING(" track without states, discarding track ");
386 return nullptr;
387 }
388
389 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
391
392 std::vector<int> indexAEOTs;
393 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> tsosAEOTs;
394
395 ATH_MSG_DEBUG(" AlignmentMap size " << alignerrmap.size());
396
397 std::set<ChIndex> stationIds;
398
399 for (const auto& itAli : alignerrmap) {
400 unsigned int imiddle = (itAli.first.size()) / 2;
401 Identifier idMiddle = itAli.first[imiddle];
402 int index = -1;
403 bool found = false;
404 for (const Trk::TrackStateOnSurface* tsit : *states) {
405 index++;
406 const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
407 if (!meas) { continue; }
408 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
409 if (!id.is_valid()) continue;
410
411 if (m_idHelperSvc->isMdt(id)) stationIds.insert(m_idHelperSvc->chamberIndex(id));
412
413 // make Alignment Effect using the surface of the TSOS
414
415 if (idMiddle == id) {
417 const double deltaError = std::max(itAli.second.first, 0.01);
418 const double angleError = std::max(itAli.second.second, 0.000001);
419 auto aEOT = std::make_unique<Trk::AlignmentEffectsOnTrack>(
420 0.,
421 deltaError,
422 0.,
423 angleError,
424 itAli.first,
425 tsit->measurementOnTrack()->associatedSurface());
426 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOT =
427 std::make_unique<Trk::TrackStateOnSurface>(
428 nullptr,
429 tsit->trackParameters()->uniqueClone(),
430 nullptr,
431 typePattern,
432 std::move(aEOT));
433 indexAEOTs.push_back(index);
434 tsosAEOTs.emplace_back(std::move(tsosAEOT));
435 found = true;
436 break;
437 }
438 }
439 if (!found) ATH_MSG_WARNING(" This should not happen Identifier from AlignmentErrorTool is not found");
440 }
441
442 //
443 // clone the TSOSs and add the tsosAEOTs
444 //
445 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
446 trackStateOnSurfaces->reserve(states->size() + indexAEOTs.size());
447 int index = -1;
448 for (const Trk::TrackStateOnSurface* tsit : *states) {
449 index++;
450 for (unsigned int i = 0; i < indexAEOTs.size(); i++) {
451 if (index == indexAEOTs[i]) {
452 if (tsosAEOTs[i])
453 trackStateOnSurfaces->push_back(std::move(tsosAEOTs[i]));
454 else {
455 ATH_MSG_WARNING("There's a trial to push back the same AEOT twice to the track...");
456 }
457 }
458 }
459
460 // Skip AEOTs that are already present, as they will be added above already
461 if (tsit->alignmentEffectsOnTrack()) {
462 ATH_MSG_DEBUG("makeAEOTs: Skipping insertion of old AEOT!");
463 continue;
464 }
465 trackStateOnSurfaces->push_back(tsit->clone());
466 }
467
468 if (indexAEOTs.empty() && stationIds.size() > 1) ATH_MSG_WARNING(" Track without AEOT ");
469
470 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces),
471 track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
472
473 ATH_MSG_DEBUG(m_printer->print(*newTrack));
474 ATH_MSG_DEBUG(m_printer->printMeasurements(*newTrack));
475
476 return newTrack;
477 }
478
479 std::unique_ptr<Trk::Track> MuonRefitTool::makeSimpleAEOTs(const Trk::Track& track) const {
480 // use the new AlignmentEffectsOnTrack class
481
482 const Trk::TrackStates* states = track.trackStateOnSurfaces();
483 if (!states) {
484 ATH_MSG_WARNING(" track without states, discarding track ");
485 return nullptr;
486 }
487
488 //
489 // first clone the TSOSs
490 //
491 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
492 trackStateOnSurfaces->reserve(states->size() + 1);
493 for (const Trk::TrackStateOnSurface* tsit : *states) { trackStateOnSurfaces->push_back(tsit->clone()); }
494
495 // loop over TSOSs and look for EM or BM chambers
496 std::vector<const Trk::TrackStateOnSurface*> indicesOfAffectedTSOS;
497 std::vector<const Trk::TrackStateOnSurface*> indicesOfAffectedTSOSInner;
498 std::vector<Identifier> indicesOfAffectedIds;
499 std::vector<Identifier> indicesOfAffectedIdsInner;
500 int index {-1}, indexFirst {-1}, indexFirstInner {-1};
501 for (const Trk::TrackStateOnSurface* tsit : *trackStateOnSurfaces) {
502 ++index;
503 if (!tsit) continue; // sanity check
504
505 const Trk::TrackParameters* pars = tsit->trackParameters();
506 if (!pars) continue;
507
508 // check whether state is a measurement
509 const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
510 if (!meas) { continue; }
511
512 // skip outliers
513 if (tsit->type(Trk::TrackStateOnSurface::Outlier)) continue;
514 if (tsit->alignmentEffectsOnTrack()) {
515 ATH_MSG_WARNING(" AlignmentEffectOnTrack is already on track skip it");
516 continue;
517 }
518 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
519 // Not a ROT, else it would have had an identifier. Keep the TSOS.
520 if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) continue;
521 StIndex stIndex = m_idHelperSvc->stationIndex(id);
522 // skip phi measurements
523 if ((m_idHelperSvc->isTrigger(id) && m_idHelperSvc->measuresPhi(id)) ||
524 (m_idHelperSvc->isCsc(id) && m_idHelperSvc->measuresPhi(id)))
525 continue;
526 if (m_addAll) {
527 // skip RPC and TGC eta (to avoid code crashes)
528 if (m_idHelperSvc->isTrigger(id)) continue;
529 if (indexFirst == -1) indexFirst = index;
530 indicesOfAffectedTSOS.push_back(tsit);
531 indicesOfAffectedIds.push_back(id);
532 } else {
533 // skip trigger hits and CSC phi measurements and select precision hits
534 if (m_idHelperSvc->isTrigger(id)) continue;
535 if (stIndex == StIndex::BM || stIndex == StIndex::EM) {
536 if (indexFirst == -1) indexFirst = index;
537 indicesOfAffectedTSOS.push_back(tsit);
538 indicesOfAffectedIds.push_back(id);
539 // two alignment discontinuities
540 if (m_addTwo) {
541 if (indexFirstInner == -1) indexFirstInner = index;
542 indicesOfAffectedTSOSInner.push_back(tsit);
543 indicesOfAffectedIdsInner.push_back(id);
544 }
545 }else if (stIndex == StIndex::BI || stIndex == StIndex::EI) {
546 if (indexFirstInner == -1) indexFirstInner = index;
547 indicesOfAffectedTSOSInner.push_back(tsit);
548 indicesOfAffectedIdsInner.push_back(id);
549 }
550 }
551 }
552
553 if (indicesOfAffectedTSOS.empty() && indicesOfAffectedTSOSInner.empty()) {
554 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces),
555 track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
556 return newTrack;
557 }
558
559 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
561
562 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOT;
563 if (!indicesOfAffectedTSOS.empty() && (m_addMiddle || m_addAll)) {
564 int middle = indicesOfAffectedTSOS.size() / 2;
565 const Trk::TrackStateOnSurface* tsos = indicesOfAffectedTSOS[middle];
566 auto aEOT = std::make_unique<Trk::AlignmentEffectsOnTrack>(
571 indicesOfAffectedIds,
573 ATH_MSG_DEBUG(" AlignmentEffectsOnTrack on surface "
574 << aEOT->associatedSurface()
575 << " nr of tsos affected "
576 << indicesOfAffectedTSOS.size());
577 tsosAEOT = std::make_unique<Trk::TrackStateOnSurface>(
578 nullptr,
579 tsos->trackParameters()->uniqueClone(),
580 nullptr,
581 typePattern,
582 std::move(aEOT));
583 }
584
585 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOTInner;
586 if (!indicesOfAffectedTSOSInner.empty() && (m_addInner || m_addTwo)) {
587 int middle = indicesOfAffectedTSOSInner.size() / 2;
588 const Trk::TrackStateOnSurface* tsosInner = indicesOfAffectedTSOSInner[middle];
589 auto aEOTInner = std::make_unique<Trk::AlignmentEffectsOnTrack>(
594 indicesOfAffectedIdsInner,
595 tsosInner->measurementOnTrack()->associatedSurface());
596 tsosAEOTInner = std::make_unique<Trk::TrackStateOnSurface>(
597 nullptr,
598 tsosInner->trackParameters()->uniqueClone(),
599 nullptr,
600 typePattern,
601 std::move(aEOTInner));
602 }
603
604 auto trackStateOnSurfacesAEOT = std::make_unique<Trk::TrackStates>();
605 trackStateOnSurfacesAEOT->reserve(states->size() + 2);
606 index = -1;
607 for (const Trk::TrackStateOnSurface* tsit : *trackStateOnSurfaces) {
608 index++;
609 if (index == indexFirst && tsosAEOT) {
610 trackStateOnSurfacesAEOT->push_back(std::move(tsosAEOT));
611 if (!m_addAll) ATH_MSG_DEBUG(" AlignmentEffectsOnTrack for Middle added to trackStateOnSurfacesAEOT ");
612 if (m_addAll) ATH_MSG_DEBUG(" AlignmentEffectsOnTrack for All stations added to trackStateOnSurfacesAEOT ");
613 }
614 if (index == indexFirstInner && tsosAEOTInner) {
615 trackStateOnSurfacesAEOT->push_back(std::move(tsosAEOTInner));
616 ATH_MSG_DEBUG(" AlignmentEffectsOnTrack for Inner added to trackStateOnSurfacesAEOT ");
617 if (m_addTwo) ATH_MSG_DEBUG(" also AlignmentEffectsOnTrack for Middle added to trackStateOnSurfacesAEOT ");
618 }
619 trackStateOnSurfacesAEOT->push_back(tsit);
620 }
621 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfacesAEOT),
622 track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
623 ATH_MSG_DEBUG(m_printer->print(*newTrack));
624 ATH_MSG_DEBUG(m_printer->printMeasurements(*newTrack));
625
626 return newTrack;
627 }
628
629 std::unique_ptr<Trk::Track> MuonRefitTool::updateErrors(const Trk::Track& track, const EventContext& ctx,
630 const IMuonRefitTool::Settings& settings) const {
631 // loop over track and calculate residuals
632 const Trk::TrackStates* states = track.trackStateOnSurfaces();
633 if (!states) {
634 ATH_MSG_WARNING(" track without states, discarding track ");
635 return nullptr;
636 }
637
638 // vector to store states, the boolean indicated whether the state was create in this routine (true) or belongs to the track (false)
639 // If any new state is created, all states will be cloned and a new track will beformed from them.
640 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> newStates;
641 newStates.reserve(states->size() + 5);
642
643 const Trk::TrackParameters* startPars = nullptr;
644 std::map<int, std::set<StIndex>> stationsPerSector;
645
646 // loop over TSOSs and find start parameters
647 for (const Trk::TrackStateOnSurface* tsit : *states) {
648
649 if (!tsit) continue; // sanity check
650
651 const Trk::TrackParameters* pars = tsit->trackParameters();
652 if (!pars) continue;
653
654 if (tsit->type(Trk::TrackStateOnSurface::Perigee)) {
655 if (!dynamic_cast<const Trk::Perigee*>(pars)) {
656 if (!startPars) {
657 startPars = pars;
658 } else {
659 ATH_MSG_WARNING("Track with two fit starting parameters!!!");
660 }
661 }
662 }
663
664 // check whether state is a measurement
665 const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
666 if (!meas) { continue; }
667
668 // skip outliers
669 if (tsit->type(Trk::TrackStateOnSurface::Outlier)) continue;
670
671 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
672 // Not a ROT, else it would have had an identifier. Keep the TSOS.
673 if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) continue;
674 if (m_idHelperSvc->isTrigger(id) || (m_idHelperSvc->isCsc(id) && m_idHelperSvc->measuresPhi(id))) continue;
675 StIndex stIndex = m_idHelperSvc->stationIndex(id);
676 int sector = m_idHelperSvc->sector(id);
677 stationsPerSector[sector].insert(stIndex);
678 }
679
680 if (!startPars) {
681 if (!track.trackParameters() || track.trackParameters()->empty()) {
682 ATH_MSG_WARNING("Track without parameters, cannot update errors");
683 return nullptr;
684 }
685 startPars = track.trackParameters()->front();
686 ATH_MSG_VERBOSE("Did not find fit starting parameters, using first parameters " << m_printer->print(*startPars));
687 }
688
689 // loop over sectors and select the one with most layers
690 std::vector<int> sectorsWithMostStations;
691 unsigned int nmaxStations = 0;
692 std::map<int, std::set<StIndex>>::iterator stit = stationsPerSector.begin();
693 std::map<int, std::set<StIndex>>::iterator stit_end = stationsPerSector.end();
694 for (; stit != stit_end; ++stit) {
695 if (msgLvl(MSG::VERBOSE)) {
696 ATH_MSG_VERBOSE(" sector " << stit->first);
697 for (std::set<StIndex>::iterator ssit = stit->second.begin(); ssit != stit->second.end(); ++ssit) {
698 ATH_MSG_VERBOSE(" " << stName(*ssit));
699 }
700 }
701 if (stit->second.size() > nmaxStations) {
702 nmaxStations = stit->second.size();
703 sectorsWithMostStations.clear();
704 sectorsWithMostStations.push_back(stit->first);
705 } else if (stit->second.size() == nmaxStations) {
706 sectorsWithMostStations.push_back(stit->first);
707 }
708 }
709 int selectedSector = -1;
710 if (sectorsWithMostStations.empty()) {
711 ATH_MSG_WARNING("No sector selected");
712 } else if (sectorsWithMostStations.size() == 1) {
713 selectedSector = sectorsWithMostStations.front();
714 } else {
715 ATH_MSG_DEBUG("Found track with special sector configuration " << sectorsWithMostStations.size() << " ch per sector "
716 << nmaxStations << " using first sector");
717 selectedSector = sectorsWithMostStations.front();
718 if (selectedSector % 2 == 1 && sectorsWithMostStations.back() % 2 != 1) {
719 ATH_MSG_DEBUG("Revising sector choice, picking small sector ");
720 selectedSector = sectorsWithMostStations.back();
721 }
722 }
723
724 // no check whether we have a barrel/endcap overlap
725
726 static constexpr std::array<StIndex, 3> barel_stations{StIndex::BI, StIndex::BM, StIndex::BO};
727 static constexpr std::array<StIndex, 5> endcap_stations{StIndex::EI,StIndex::EM, StIndex::EO, StIndex::EE, StIndex::BE};
728 const std::set<StIndex>& selected_set = stationsPerSector[selectedSector];
729 const int nbarrel = std::accumulate(barel_stations.begin(),barel_stations.end(),0, [&selected_set](int n, const StIndex& idx){
730 return (selected_set.count(idx) > 0) + n;
731 });
732 const int nendcap = std::accumulate(endcap_stations.begin(),endcap_stations.end(),0, [&selected_set](int n, const StIndex& idx){
733 return (selected_set.count(idx) > 0) + n;
734 });
735 bool barrelEndcap {false}, deweightBarrel{false}, deweightEndcap{false};
736 if (nbarrel > 0 && nendcap > 0) {
737 if (nbarrel < nendcap)
738 deweightBarrel = true;
739 else
740 deweightEndcap = true;
741 barrelEndcap = true;
742 }
743 if (msgLvl(MSG::DEBUG)) {
744 ATH_MSG_DEBUG(" Selected sector " << selectedSector << " nstations " << nmaxStations << " barrel " << nbarrel << " endcap "
745 << nendcap);
746 if (barrelEndcap) {
747 ATH_MSG_DEBUG(" barrel/endcap overlap ");
748 if (deweightEndcap) ATH_MSG_DEBUG(" deweight endcap ");
749 if (deweightBarrel) ATH_MSG_DEBUG(" deweight barrel ");
750 }
751 }
752
753 unsigned int deweightHits = 0;
754 unsigned int removedSectorHits = 0;
755 bool addedPerigee = false;
756 // loop over TSOSs
757 for (const Trk::TrackStateOnSurface* tsos : * states) {
758 if (!tsos) continue; // sanity check
759
760 // check whether state is a measurement, if not add it, except if we haven't added the perigee surface yet
761 const Trk::TrackParameters* pars = tsos->trackParameters();
762 if (settings.prepareForFit && !pars) {
763 if (addedPerigee) {
764 newStates.emplace_back(tsos->clone());
765 } else {
766 ATH_MSG_DEBUG("Dropping TSOS before perigee surface");
767 }
768 continue;
769 }
770
771 // if preparing for fit and not recreating the starting parameters, add the original perigee before back extrapolation to MS
772 // entry
773 if (settings.prepareForFit && !settings.recreateStartingParameters && tsos->type(Trk::TrackStateOnSurface::Perigee)) {
774 if (pars == startPars) {
775 ATH_MSG_DEBUG("Found fit starting parameters " << m_printer->print(*pars));
776 std::unique_ptr<Trk::Perigee> perigee = createPerigee(*pars, ctx);
777 newStates.emplace_back(MuonTSOSHelper::createPerigeeTSOS(std::move(perigee)));
778 addedPerigee = true;
779 continue;
780 } else {
781 ATH_MSG_DEBUG("Removing perigee");
782 }
783 }
784
785 // check whether state is a measurement
786 const Trk::MeasurementBase* meas = tsos->measurementOnTrack();
787 if (!meas) {
788 newStates.emplace_back(tsos->clone());
789 continue;
790 }
791
792 if (settings.prepareForFit && settings.recreateStartingParameters && !addedPerigee) {
793 // small shift towards the ip
794 double sign = pars->position().dot(pars->momentum()) > 0 ? 1. : -1.;
795 Amg::Vector3D perpos = pars->position() - 100. * sign * pars->momentum().unit();
796
797 // create perigee
798 double phi = pars->momentum().phi();
799 double theta = pars->momentum().theta();
800 double qoverp = pars->charge() / pars->momentum().mag();
801 Trk::PerigeeSurface persurf(perpos);
802 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0, phi, theta, qoverp, persurf);
803 newStates.emplace_back(MuonTSOSHelper::createPerigeeTSOS(std::move(perigee)));
804 addedPerigee = true;
805 ATH_MSG_DEBUG("Adding perigee in front of first measurement");
806 }
807
808 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
809
810 // Not a ROT, else it would have had an identifier. Keep the TSOS.
811 if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) {
812 newStates.emplace_back(tsos->clone());
813 continue;
814 }
815
816 if (!settings.updateErrors) {
817 newStates.emplace_back(tsos->clone());
818 } else {
819 Identifier chId = m_idHelperSvc->chamberId(id);
820 StIndex stIndex = m_idHelperSvc->stationIndex(id);
821 if (m_idHelperSvc->isMdt(id)) {
822 const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
823 if (!mdt) {
824 ATH_MSG_WARNING(" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
825 continue;
826 }
827
828 bool hasT0Fit = false;
830
831 std::unique_ptr<MdtDriftCircleOnTrack> rot{};
832 int sector = m_idHelperSvc->sector(id);
836
837 stIndex = m_idHelperSvc->stationIndex(id);
838
839 // error update for three stations with barrel-endcap and shared sectors
840 if (!m_deweightTwoStationTracks || nmaxStations > 2) {
841 if (m_deweightEEL1C05 && m_idHelperSvc->chamberIndex(id) == ChIndex::EEL && m_idHelperSvc->stationEta(id) < 0 &&
842 m_idHelperSvc->stationPhi(id) == 3) {
843 // for this chamber the errors are enormous (for a period of time)
844 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyEEL1C05));
845
846 } else if (deweightBarrel &&
847 std::find(barel_stations.begin(),barel_stations.end(),stIndex) != barel_stations.end()) {
848 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyBarEnd));
850
851 } else if (deweightEndcap &&
852 std::find(endcap_stations.begin(), endcap_stations.end(), stIndex) != endcap_stations.end()) { // BEE chambers enter the endcap alignment system!
853 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyBarEnd));
855
856 } else if (settings.deweightOtherSectors && sector != selectedSector) {
857 ++deweightHits;
858 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategySL));
859
860 } else if (m_deweightBEE && stIndex == StIndex::BE) {
861 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyBEE));
863
864 } else if (m_deweightEE && stIndex == StIndex::EE) {
865 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyEE));
866
867 } else if (m_deweightBIS78 && m_idHelperSvc->chamberIndex(id) == ChIndex::BIS &&
868 std::abs(m_idHelperSvc->stationEta(id)) > 6) {
869 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyBIS78));
870
871 } else if (m_deweightBME && stIndex == StIndex::BM && m_idHelperSvc->stationPhi(id) == 7 &&
872 (m_idHelperSvc->mdtIdHelper()).stationName(id) == m_BME_station) {
873 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyBXE));
874
875 } else if (m_deweightBOE && m_idHelperSvc->chamberIndex(id) == ChIndex::BOL &&
876 std::abs(m_idHelperSvc->stationEta(id)) == 7 &&
877 m_idHelperSvc->stationPhi(id) == 7) {
878 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyBXE));
879
880 } else {
883 if (hasT0Fit) strat.setParameter(MuonDriftCircleErrorStrategy::T0Refit, true);
885 rot.reset( m_mdtRotCreator->updateError(*mdt, pars, &strat));
886 }
887 } else {
888 rot.reset(m_mdtRotCreator->updateError(*mdt, pars, &m_errorStrategyTwoStations));
889 }
890
891
892
893 if (!rot) {
894 rot.reset(mdt->clone());
896 }
897 if (settings.removeOtherSectors) {
898 if (sector != selectedSector) {
899 ++removedSectorHits;
901 }
902 }
903 if (settings.chambersToBeremoved.count(chId) || settings.precisionLayersToBeremoved.count(stIndex)) {
905 }
906
907 if (msgLvl(MSG::DEBUG)) {
908 ATH_MSG_DEBUG(m_idHelperSvc->toString(rot->identify())
909 << " radius " << rot->driftRadius() << " new err "
910 << Amg::error(rot->localCovariance(), Trk::locR) << " old err "
912 if (hasT0Fit)
913 ATH_MSG_DEBUG(" HasT0");
914 else
915 ATH_MSG_DEBUG(" No T0");
917 if (std::abs(rot->driftRadius() - mdt->driftRadius()) > 0.1)
918 ATH_MSG_DEBUG(" Bad recalibration: old r " << mdt->driftRadius());
919 }
920 //the following is a cop-out until can sort out the unique_ptr magic for rot, mdt
921 std::unique_ptr<Trk::TrackStateOnSurface> new_tsos = MuonTSOSHelper::createMeasTSOSWithUpdate(*tsos, std::move(rot), pars->uniqueClone(), type);
922 newStates.emplace_back(std::move(new_tsos));
923 } else if (m_idHelperSvc->isCsc(id)) {
924 if (settings.chambersToBeremoved.count(chId) || settings.precisionLayersToBeremoved.count(stIndex)) {
925 std::unique_ptr<Trk::TrackStateOnSurface> new_tsos = MuonTSOSHelper::cloneTSOS(*tsos, Trk::TrackStateOnSurface::Outlier);
926 newStates.emplace_back(std::move(new_tsos));
927
928 } else {
929 newStates.emplace_back(tsos->clone());
930 }
931 } else if (m_idHelperSvc->isTrigger(id)) {
932 if (m_idHelperSvc->measuresPhi(id)) {
933 if (settings.chambersToBeremoved.count(chId) || settings.phiLayersToBeremoved.count(m_idHelperSvc->phiIndex(id))) {
934 std::unique_ptr<Trk::TrackStateOnSurface> new_tsos = MuonTSOSHelper::cloneTSOS(*tsos, Trk::TrackStateOnSurface::Outlier);
935 newStates.emplace_back(std::move(new_tsos));
936
937 } else {
938 newStates.emplace_back(tsos->clone());
939 }
940
941 } else {
942 if (settings.updateTriggerErrors) {
943 newStates.emplace_back(tsos->clone());
944
945 } else {
946 newStates.emplace_back(tsos->clone());
947 }
948 }
949 } else if (m_idHelperSvc->isMM(id) || m_idHelperSvc->issTgc(id)) {
950 newStates.emplace_back(tsos->clone());
951
952 } else {
953 ATH_MSG_WARNING(" unknown Identifier " << m_idHelperSvc->mdtIdHelper().print_to_string(id));
954 }
955 }
956 }
957
958 if (deweightHits > 0) ATH_MSG_DEBUG(" de-weighted " << deweightHits << " MDT hits from neighbouring sectors");
959 if (removedSectorHits > 0) ATH_MSG_DEBUG(" removed " << removedSectorHits << " MDT hits from neighbouring sectors");
960
961 ATH_MSG_VERBOSE(" original track had " << states->size() << " TSOS, adding " << newStates.size() - states->size() << " new TSOS ");
962
963 // states were added, create a new track
964 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
965 trackStateOnSurfaces->reserve(newStates.size());
966 for (std::unique_ptr<Trk::TrackStateOnSurface>& new_state : newStates) {
967 trackStateOnSurfaces->push_back(std::move(new_state));
968 }
969 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces),
970 track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
971 ATH_MSG_DEBUG("new track measurements: " << m_printer->printMeasurements(*newTrack));
972
973 return newTrack;
974 }
975
976 std::unique_ptr<Trk::Track> MuonRefitTool::updateMdtErrors(const Trk::Track& track, const EventContext& ctx,
977 const IMuonRefitTool::Settings& settings) const {
978 // uses the muonErrorStrategy
979
980 // loop over track and calculate residuals
981 const Trk::TrackStates* states = track.trackStateOnSurfaces();
982 if (!states) {
983 ATH_MSG_WARNING(" track without states, discarding track ");
984 return nullptr;
985 }
986
987 // vector to store states, the boolean indicated whether the state was create in this routine (true) or belongs to the track (false)
988 // If any new state is created, all states will be cloned and a new track will beformed from them.
989 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> newStates;
990 newStates.reserve(states->size() + 5);
991
992 const Trk::TrackParameters* startPars = nullptr;
993
994 // loop over TSOSs and find start parameters
995 for (const Trk::TrackStateOnSurface* tsos : *states) {
996 if (!tsos) continue; // sanity check
997
998 const Trk::TrackParameters* pars = tsos->trackParameters();
999 if (!pars) continue;
1000
1001 if (tsos->type(Trk::TrackStateOnSurface::Perigee)) {
1002 if (!dynamic_cast<const Trk::Perigee*>(pars)) {
1003 if (!startPars) {
1004 startPars = pars;
1005 } else {
1006 ATH_MSG_WARNING("Track with two fit starting parameters!!!");
1007 }
1008 }
1009 }
1010
1011 // check whether state is a measurement
1012 const Trk::MeasurementBase* meas = tsos->measurementOnTrack();
1013 if (!meas) { continue; }
1014
1015 // skip outliers
1016 if (tsos->type(Trk::TrackStateOnSurface::Outlier)) continue;
1017
1018 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1019 // Not a ROT, else it would have had an identifier. Keep the TSOS.
1020 if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) continue;
1021 if (m_idHelperSvc->isTrigger(id) || (m_idHelperSvc->isCsc(id) && m_idHelperSvc->measuresPhi(id))) continue;
1022 }
1023
1024 if (!startPars) {
1025 if (!track.trackParameters() || track.trackParameters()->empty()) {
1026 ATH_MSG_WARNING("Track without parameters, cannot update errors");
1027 return nullptr;
1028 }
1029 startPars = track.trackParameters()->front();
1030 ATH_MSG_VERBOSE("Did not find fit starting parameters, using first parameters " << m_printer->print(*startPars));
1031 }
1032
1033 bool addedPerigee = false;
1034 // loop over TSOSs
1035 for (const Trk::TrackStateOnSurface* tsos : *states) {
1036 if (!tsos) continue; // sanity check
1037
1038 // check whether state is a measurement, if not add it, except if we haven't added the perigee surface yet
1039 const Trk::TrackParameters* pars = tsos->trackParameters();
1040 if (settings.prepareForFit && !pars) {
1041 if (addedPerigee) {
1042 newStates.emplace_back(tsos->clone());
1043 continue;
1044 } else {
1045 ATH_MSG_DEBUG("Dropping TSOS before perigee surface");
1046 continue;
1047 }
1048 }
1049
1050 // if preparing for fit and not recreating the starting parameters, add the original perigee before back extrapolation to MS
1051 // entry
1052 if (settings.prepareForFit && !settings.recreateStartingParameters && tsos->type(Trk::TrackStateOnSurface::Perigee)) {
1053 if (pars == startPars) {
1054 ATH_MSG_DEBUG("Found fit starting parameters " << m_printer->print(*pars));
1055 std::unique_ptr<Trk::Perigee> perigee = createPerigee(*pars, ctx);
1056 newStates.emplace_back(MuonTSOSHelper::createPerigeeTSOS(std::move(perigee)));
1057 addedPerigee = true;
1058 continue;
1059 } else {
1060 ATH_MSG_DEBUG("Removing perigee");
1061 }
1062 }
1063
1064 // check whether state is a measurement
1065 const Trk::MeasurementBase* meas = tsos->measurementOnTrack();
1066 if (!meas) {
1067 newStates.emplace_back(tsos->clone());
1068 continue;
1069 }
1070
1071 if (settings.prepareForFit && settings.recreateStartingParameters && !addedPerigee) {
1072 // small shift towards the ip
1073 double sign = pars->position().dot(pars->momentum()) > 0 ? 1. : -1.;
1074 Amg::Vector3D perpos = pars->position() - 100. * sign * pars->momentum().unit();
1075
1076 // create perigee
1077 double phi = pars->momentum().phi();
1078 double theta = pars->momentum().theta();
1079 double qoverp = pars->charge() / pars->momentum().mag();
1080 Trk::PerigeeSurface persurf(perpos);
1081 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0, phi, theta, qoverp, persurf);
1082 newStates.emplace_back(MuonTSOSHelper::createPerigeeTSOS(std::move(perigee)));
1083 addedPerigee = true;
1084 ATH_MSG_DEBUG("Adding perigee in front of first measurement");
1085 }
1086
1087 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1088
1089 // Not a ROT, else it would have had an identifier. Keep the TSOS.
1090 if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) {
1091 newStates.emplace_back(tsos->clone());
1092 continue;
1093 }
1094
1095 if (!settings.updateErrors) {
1096 newStates.emplace_back(tsos->clone());
1097 } else {
1098 Identifier chId = m_idHelperSvc->chamberId(id);
1099 StIndex stIndex = m_idHelperSvc->stationIndex(id);
1100 if (m_idHelperSvc->isMdt(id)) {
1101 const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
1102 if (!mdt) {
1103 ATH_MSG_WARNING(" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
1104 continue;
1105 }
1106
1107 bool hasT0Fit = false;
1109
1110 Trk::RIO_OnTrack* rot = nullptr;
1114
1115 stIndex = m_idHelperSvc->stationIndex(id);
1116
1117 // use the muonErrorStrategy
1119 if (hasT0Fit) strat.setParameter(MuonDriftCircleErrorStrategy::T0Refit, true);
1121 rot = m_mdtRotCreator->updateError(*mdt, pars, &strat);
1122
1123 MdtDriftCircleOnTrack* newMdt = rot ? dynamic_cast<MdtDriftCircleOnTrack*>(rot) : nullptr;
1124 if (!newMdt) {
1125 newMdt = mdt->clone();
1127 }
1128 if (settings.chambersToBeremoved.count(chId) || settings.precisionLayersToBeremoved.count(stIndex)) {
1130 }
1131
1132 if (msgLvl(MSG::DEBUG)) {
1133 ATH_MSG_DEBUG(" updateMdtErrors " << m_idHelperSvc->toString(newMdt->identify()) << " radius "
1134 << newMdt->driftRadius() << " new err "
1135 << Amg::error(newMdt->localCovariance(), Trk::locR) << " old err "
1137 if (hasT0Fit)
1138 ATH_MSG_DEBUG(" HasT0");
1139 else
1140 ATH_MSG_DEBUG(" No T0");
1142 if (std::abs(newMdt->driftRadius() - mdt->driftRadius()) > 0.1)
1143 ATH_MSG_DEBUG(" Bad recalibration: old r " << mdt->driftRadius());
1144 }
1145 std::unique_ptr<MdtDriftCircleOnTrack> newUniqueMdt {newMdt};
1146 std::unique_ptr<Trk::TrackStateOnSurface> new_tsos = MuonTSOSHelper::createMeasTSOSWithUpdate(*tsos, std::move(newUniqueMdt), pars->uniqueClone(), type);
1147 newStates.emplace_back(std::move(new_tsos));
1148 } else if (m_idHelperSvc->isCsc(id)) {
1149 if (settings.chambersToBeremoved.count(chId) || settings.precisionLayersToBeremoved.count(stIndex)) {
1150 std::unique_ptr<Trk::TrackStateOnSurface> new_tsos = MuonTSOSHelper::cloneTSOS(*tsos, Trk::TrackStateOnSurface::Outlier);
1151 newStates.emplace_back(std::move(new_tsos));
1152
1153 } else {
1154 newStates.emplace_back(tsos->clone());
1155 }
1156 } else if (m_idHelperSvc->isTrigger(id)) {
1157 if (m_idHelperSvc->measuresPhi(id)) {
1158 if (settings.chambersToBeremoved.count(chId) || settings.phiLayersToBeremoved.count(m_idHelperSvc->phiIndex(id))) {
1159 std::unique_ptr<Trk::TrackStateOnSurface> new_tsos = MuonTSOSHelper::cloneTSOS(*tsos, Trk::TrackStateOnSurface::Outlier);
1160 newStates.emplace_back(std::move(new_tsos));
1161
1162 } else {
1163 newStates.emplace_back(tsos->clone());
1164 }
1165
1166 } else {
1167 if (settings.updateTriggerErrors) {
1168 newStates.emplace_back(tsos->clone());
1169
1170 } else {
1171 newStates.emplace_back(tsos->clone());
1172 }
1173 }
1174 } else if (m_idHelperSvc->isMM(id) || m_idHelperSvc->issTgc(id)) {
1175 newStates.emplace_back(tsos->clone());
1176
1177 } else {
1178 ATH_MSG_WARNING(" unknown Identifier " << m_idHelperSvc->mdtIdHelper().print_to_string(id));
1179 }
1180 }
1181 }
1182
1183 ATH_MSG_VERBOSE(" original track had " << states->size() << " TSOS, adding " << newStates.size() - states->size() << " new TSOS ");
1184
1185 // states were added, create a new track
1186 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1187 trackStateOnSurfaces->reserve(newStates.size());
1188 for ( std::unique_ptr<Trk::TrackStateOnSurface>& state : newStates) {
1189 // add states. If nit->first is true we have a new state. If it is false the state is from the old track and has to be cloned
1190 trackStateOnSurfaces->push_back(std::move(state));
1191 }
1192 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces),
1193 track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
1194 return newTrack;
1195 }
1196
1197 std::unique_ptr<Trk::Track> MuonRefitTool::removeOutliers(const Trk::Track& track, const IMuonRefitTool::Settings& settings) const {
1198 // loop over track and calculate residuals
1199 const Trk::TrackStates* states = track.trackStateOnSurfaces();
1200 if (!states) {
1201 ATH_MSG_WARNING(" track without states, discarding track ");
1202 return nullptr;
1203 }
1204
1205 Identifier currentMdtChId;
1206 std::set<Identifier> removedIdentifiers;
1207 std::vector<const MdtDriftCircleOnTrack*> mdts;
1208 const Trk::TrackParameters* chamberPars = nullptr;
1209
1210 // loop over TSOSs and find start parameters
1211 Trk::TrackStates::const_iterator tsit = states->begin();
1212 Trk::TrackStates::const_iterator tsit_end = states->end();
1213 for (; tsit != tsit_end; ++tsit) {
1214 if (!*tsit) continue; // sanity check
1215
1216 // check whether state is a measurement
1217 const Trk::TrackParameters* pars = (*tsit)->trackParameters();
1218 if (!pars) { continue; }
1219
1220 if (!(*tsit)->type(Trk::TrackStateOnSurface::Measurement)) { continue; }
1221
1222 // check whether state is a measurement
1223 const Trk::MeasurementBase* meas = (*tsit)->measurementOnTrack();
1224 if (!meas) { continue; }
1225
1226 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1227
1228 // Not a ROT, else it would have had an identifier. Keep the TSOS.
1229 if (!id.is_valid()) { continue; }
1230
1231 if (m_idHelperSvc->isMdt(id)) {
1232 const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
1233 if (!mdt) {
1234 ATH_MSG_WARNING(" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
1235 continue;
1236 }
1237 // get ch ID
1238 Identifier chId = m_idHelperSvc->chamberId(id);
1239
1240 // if we have a new chambers
1241 if (chId != currentMdtChId) {
1242 // check that there are pars (not the case for the first mdt), if so we collected all hits for this chamber so call
1243 // cleaning
1244 if (chamberPars) {
1245 if (!removeMdtOutliers(*chamberPars, mdts, removedIdentifiers, settings)) {
1246 if (mdts.size() > 4)
1247 ATH_MSG_WARNING("Problem removing outliers in chamber " << m_idHelperSvc->toStringChamber(currentMdtChId)
1248 << " hits " << mdts.size());
1249 if (settings.discardNotCleanedTracks) return nullptr;
1250 }
1251 }
1252 // update to new chamber
1253 chamberPars = pars;
1254 mdts.clear();
1255 currentMdtChId = chId;
1256 }
1257
1258 mdts.push_back(mdt);
1259 }
1260 }
1261
1262 // clean the last chamber on the track
1263 if (chamberPars) {
1264 if (!removeMdtOutliers(*chamberPars, mdts, removedIdentifiers, settings)) {
1265 if (mdts.size() > 4)
1266 ATH_MSG_WARNING("Problem removing outliers in chamber " << m_idHelperSvc->toStringChamber(currentMdtChId) << " hits "
1267 << mdts.size());
1268 if (settings.discardNotCleanedTracks) return nullptr;
1269 }
1270 }
1271
1272 if (removedIdentifiers.empty()) {
1273 ATH_MSG_DEBUG("No hits remove, returning original track");
1274 return std::make_unique<Trk::Track>(track);
1275 }
1276
1277 // states were added, create a new track
1278 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1279 trackStateOnSurfaces->reserve(states->size());
1280
1281 ATH_MSG_DEBUG("Removing nhits: " << removedIdentifiers.size());
1282
1283 for (const Trk::TrackStateOnSurface* tsos : *states) {
1284 if (!*tsit) continue; // sanity check
1285
1286 // check whether state is a measurement
1287 const Trk::MeasurementBase* meas = tsos->measurementOnTrack();
1288 if (meas) {
1289 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1290
1291 if (removedIdentifiers.count(id)) {
1292 std::unique_ptr<Trk::TrackStateOnSurface> new_tsos = MuonTSOSHelper::cloneTSOS(*tsos, Trk::TrackStateOnSurface::Outlier);
1293 trackStateOnSurfaces->push_back(std::move(new_tsos));
1294 continue;
1295 }
1296 }
1297 trackStateOnSurfaces->push_back(tsos->clone());
1298 }
1299
1300 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces),
1301 track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
1302 return newTrack;
1303 }
1304
1305 bool MuonRefitTool::removeMdtOutliers(const Trk::TrackParameters& pars, const std::vector<const MdtDriftCircleOnTrack*>& hits,
1306 std::set<Identifier>& removedIdentifiers, const IMuonRefitTool::Settings& settings) const {
1307 if (hits.size() < 3) {
1308 ATH_MSG_VERBOSE("Too few hits, cannot perform cleaning");
1309 return false;
1310 }
1311 ATH_MSG_VERBOSE("Performing cleaning, nhits " << hits.size());
1312
1315 /* ******** Mdt hits ******** */
1316
1317 const MuonGM::MdtReadoutElement* detEl = nullptr;
1318
1319 Amg::Transform3D gToStation;
1320
1322 TrkDriftCircleMath::SegmentFinder segFinder(5., 3., false);
1323 if (!m_t0Fitter.empty()) {
1324 std::shared_ptr<const TrkDriftCircleMath::DCSLFitter> fitter(m_t0Fitter->getFitter(), Muon::IDCSLFitProvider::Unowned{});
1325 segFinder.setFitter(fitter);
1326 }
1327 segFinder.debugLevel(m_finderDebugLevel);
1328 segFinder.setRecoverMDT(false);
1329
1330 for (const MdtDriftCircleOnTrack* mdt : hits) {
1331
1332 Identifier id = mdt->identify();
1333
1334 if (!detEl) {
1335 detEl = mdt->prepRawData()->detectorElement();
1336 if (!detEl) {
1337 ATH_MSG_WARNING(" error aborting not detEl found ");
1338 break;
1339 }
1340 gToStation = detEl->GlobalToAmdbLRSTransform();
1341 }
1342 // calculate local AMDB position
1343 Amg::Vector3D locPos = gToStation * mdt->prepRawData()->globalPosition();
1344 TrkDriftCircleMath::LocVec2D lpos(locPos.y(), locPos.z());
1345
1346 double r = std::abs(mdt->localParameters()[Trk::locR]);
1347 double dr = Amg::error(mdt->localCovariance(), Trk::locR);
1348 ATH_MSG_VERBOSE("New MDT " << m_idHelperSvc->toString(id) << " r " << mdt->localParameters()[Trk::locR] << " dr " << dr
1349 << " (original) " << Amg::error(mdt->localCovariance(), Trk::locR));
1350
1351 // create identifier
1352 TrkDriftCircleMath::MdtId mdtid(m_idHelperSvc->mdtIdHelper().isBarrel(id), m_idHelperSvc->mdtIdHelper().multilayer(id) - 1,
1353 m_idHelperSvc->mdtIdHelper().tubeLayer(id) - 1, m_idHelperSvc->mdtIdHelper().tube(id) - 1);
1354
1355 // create new DriftCircle
1357 dcsOnTrack.emplace_back(dc, 1., 1.);
1358 dcs.emplace_back(std::move(dc));
1359 }
1360
1361 if (!detEl) return false;
1362 // define axis of chamber in global coordinates
1363 Amg::Transform3D amdbToGlobal = detEl->AmdbLRSToGlobalTransform();
1364
1365 // create new surface
1366 Amg::Transform3D surfaceTransform(amdbToGlobal.rotation());
1367 surfaceTransform.pretranslate(pars.position());
1368 double surfDim = 500.;
1369 const std::unique_ptr<Trk::PlaneSurface> surf = std::make_unique<Trk::PlaneSurface>(surfaceTransform, surfDim, surfDim);
1370
1371 Amg::Vector3D dir = pars.momentum().unit();
1372 if (dir.y() * pars.position().y() < 0.) { dir *= -1.; }
1373 Trk::LocalDirection locDir;
1374 surf->globalToLocalDirection(dir, locDir);
1375
1376 Amg::Vector3D locDirTrack(gToStation.linear() * dir);
1377 double track_angleYZ = std::atan2(locDirTrack.z(), locDirTrack.y());
1378
1379 // transform nominal pointing chamber position into surface frame
1380 Amg::Vector3D dirCh(gToStation.linear() * detEl->center());
1381 double chamber_angleYZ = std::atan2(dirCh.z(), dirCh.y());
1382 double angleYZ = locDir.angleYZ();
1383
1384 const Amg::Vector3D lpos = gToStation * pars.position();
1385
1386 TrkDriftCircleMath::LocVec2D segPos(lpos.y(), lpos.z());
1387 TrkDriftCircleMath::Line segPars(segPos, angleYZ);
1388
1389 ATH_MSG_DEBUG("Seeding angles " << track_angleYZ << " from surf " << angleYZ << " ch angle " << chamber_angleYZ << " pos "
1390 << segPos);
1391 segFinder.setPhiRoad(track_angleYZ, chamber_angleYZ, 0.14);
1392
1393 if (msgLvl(MSG::VERBOSE)) {
1395 if (dcslFitter.fit(segment, segPars, dcsOnTrack)) {
1396 segment.hitsOnTrack(dcsOnTrack.size());
1397 ATH_MSG_DEBUG(" segment after fit " << segment.chi2() << " ndof " << segment.ndof() << " local parameters "
1398 << segment.line().x0() << " " << segment.line().y0() << " phi "
1399 << segment.line().phi());
1400 } else {
1401 ATH_MSG_DEBUG("Fit failed: hits" << dcsOnTrack.size());
1402 }
1403 }
1404
1405 TrkDriftCircleMath::SegVec segments = segFinder.findSegments(dcs);
1406 if (!segments.empty()) { ATH_MSG_DEBUG("Found segments " << segments.size()); }
1407
1408 if (segments.size() != 1) {
1409 if (hits.size() > 3)
1410 ATH_MSG_WARNING(" Found two solutions ");
1411 else
1412 ATH_MSG_DEBUG(" Found two solutions ");
1413 double dthetaBest = 10000.;
1414 int index = 0;
1415 int indexBest = -1;
1416 TrkDriftCircleMath::SegIt sit = segments.begin();
1417 TrkDriftCircleMath::SegIt sit_end = segments.end();
1418 for (; sit != sit_end; ++sit, ++index) {
1419 double dtheta = std::abs(sit->line().phi() - track_angleYZ);
1420 if (dtheta < dthetaBest) {
1421 dthetaBest = dtheta;
1422 indexBest = index;
1423 }
1424 if (sit->hitsOnTrack() > 4) { ATH_MSG_DEBUG("Recoverable segment " << *sit); }
1425 }
1426 if (indexBest != -1) {
1427 TrkDriftCircleMath::SegVec selectedSegments;
1428 selectedSegments.push_back(segments[indexBest]);
1429 segments = selectedSegments;
1430 ATH_MSG_DEBUG("Selected segment " << segments.front());
1431
1432 } else {
1433 return false;
1434 }
1435 }
1436
1437 TrkDriftCircleMath::Segment& segment = segments.front();
1438 if (settings.discardNotCleanedTracks && !segment.hasT0Shift()) return false;
1439
1440 if (segment.hasT0Shift() || segment.hitsOnTrack() > 5) { ATH_MSG_DEBUG("Segment with t0 shift " << segment.t0Shift()); }
1441
1442 if (dcs.size() == segment.hitsOnTrack()) {
1443 ATH_MSG_DEBUG(" No hits removed ");
1444 return true;
1445 } else if (dcs.size() > segment.hitsOnTrack() + 1) {
1446 ATH_MSG_DEBUG(" more than one hit removed ");
1447 if (segment.hitsOnTrack() < 4) return false;
1448 }
1449
1450 ATH_MSG_DEBUG(" removed hits: " << dcs.size() - segment.hitsOnTrack());
1451
1452 float tubeRadius = detEl->innerTubeRadius();
1453
1455 const TrkDriftCircleMath::DCOnTrackVec& matchedDCs = matchDC.match(segment.dcs());
1456
1457 for (TrkDriftCircleMath::DCOnTrackCit dcit = matchedDCs.begin(); dcit != matchedDCs.end(); ++dcit) {
1458 if (dcit->state() == TrkDriftCircleMath::DCOnTrack::OnTrack) {
1459 if (std::abs(dcit->r()) - std::abs(dcit->rot()->driftRadius()) > 0.1) {
1460 ATH_MSG_DEBUG("Large change in drift radius: r_old " << dcit->rot()->driftRadius() << " r_new " << dcit->r());
1461 }
1462 continue;
1463 }
1464 removedIdentifiers.insert(dcit->rot()->identify());
1465 ATH_MSG_VERBOSE(" removing hit " << m_idHelperSvc->toString(dcit->rot()->identify()));
1466 }
1467 return true;
1468 }
1469
1470 std::unique_ptr<Trk::Perigee>
1471 MuonRefitTool::createPerigee(const Trk::TrackParameters& pars, const EventContext& ctx) const {
1472 std::unique_ptr<Trk::Perigee> perigee;
1473 if (m_muonExtrapolator.empty()) { return perigee; }
1474 Trk::PerigeeSurface persurf(pars.position());
1475 std::unique_ptr<Trk::TrackParameters> exPars{m_muonExtrapolator->extrapolateDirectly(ctx, pars, persurf)};
1476 perigee.reset (dynamic_cast<Trk::Perigee*>(exPars.release()));
1477 if (!perigee) {
1478 ATH_MSG_WARNING(" Extrapolation to Perigee surface did not return a perigee!! ");
1479 return perigee;
1480 }
1481 return perigee;
1482 }
1483
1484} // namespace Muon
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
int sign(int a)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
virtual const Amg::Vector3D & center(const Identifier &) const override final
Return the center of the surface associated with this identifier In the case of silicon it returns th...
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
const MuonDriftCircleErrorStrategy & errorStrategy() const
Get information about the creation strategy used by Muon::MdtDriftCircleOnTrackCreator when making th...
double driftRadius() const
Returns the value of the drift radius.
virtual MdtDriftCircleOnTrack * clone() const override final
Pseudo-constructor, needed to avoid excessive RTTI.
bool creationParameter(CreationParameter) const
void setParameter(CreationParameter, bool value)
@ StationError
A term is added to account for misaligned.
@ T0Refit
A special error was applied to account for the T0 refit (user defined via jobProperties)
@ FixedError
A fixed error is given to this hit (user defined via jobProperties)
@ MagFieldCorrection
Magnetic field correction was applied in calibration.
@ SlewCorrection
Slewing correction was applied in calibration.
@ TofCorrection
Time of flight correction was applied in calibration.
@ BackgroundCorrection
Background correction was applied in calibration.
@ PropCorrection
Propagation correction was applied in calibration.
@ TempCorrection
Temperature correction was applied in calibration.
MuonDriftCircleErrorStrategy m_errorStrategyBarEnd
Gaudi::Property< bool > m_deweightBME
Gaudi::Property< float > m_alignmentDeltaError
Gaudi::Property< bool > m_deweightBEE
virtual StatusCode finalize() override
Gaudi::Property< bool > m_addInner
virtual StatusCode initialize() override
ToolHandle< IMuonCompetingClustersOnTrackCreator > m_compClusterCreator
ToolHandle< IMdtDriftCircleOnTrackCreator > m_mdtRotCreator
ToolHandle< Muon::IMuonTrackExtrapolationTool > m_muonEntryTrackExtrapolator
Gaudi::Property< bool > m_deweightEE
std::unique_ptr< Trk::Perigee > createPerigee(const Trk::TrackParameters &pars, const EventContext &ctx) const
Gaudi::Property< bool > m_addAll
ToolHandle< IDCSLFitProvider > m_t0Fitter
std::unique_ptr< Trk::Track > removeOutliers(const Trk::Track &track, const Settings &settings) const
std::unique_ptr< Trk::Track > updateErrors(const Trk::Track &track, const EventContext &ctx, const Settings &settings) const
update errors on a muon track
MuonDriftCircleErrorStrategy m_errorStrategySL
std::atomic< unsigned int > m_failedExtrapolationMuonEntry
MuonDriftCircleErrorStrategy m_errorStrategyEEL1C05
PublicToolHandle< MuonEDMPrinterTool > m_printer
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
bool removeMdtOutliers(const Trk::TrackParameters &pars, const std::vector< const MdtDriftCircleOnTrack * > &hits, std::set< Identifier > &removedIdentifiers, const Settings &settings) const
MuonDriftCircleErrorStrategy m_errorStrategyEE
MuonDriftCircleErrorStrategy m_errorStrategy
Gaudi::Property< float > m_alignmentDelta
Gaudi::Property< bool > m_deweightBOE
std::unique_ptr< Trk::Track > updateAlignmentErrors(const Trk::Track &track, const EventContext &ctx, const Settings &settings) const
Gaudi::Property< bool > m_deweightEEL1C05
std::unique_ptr< Trk::Track > makeAEOTs(const Trk::Track &track) const
std::atomic< unsigned int > m_failedOutlierRemoval
Gaudi::Property< bool > m_deweightTwoStationTracks
std::unique_ptr< Trk::Track > makeSimpleAEOTs(const Trk::Track &track) const
std::atomic< unsigned int > m_failedRefit
MuonDriftCircleErrorStrategy m_errorStrategyBXE
ToolHandle< Trk::ITrkAlignmentDeviationTool > m_alignErrorTool
Does not provide any method with EventContext yet.
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
Gaudi::Property< bool > m_addTwo
MuonDriftCircleErrorStrategy m_muonErrorStrategy
Gaudi::Property< bool > m_deweightBIS78
std::atomic< unsigned int > m_failedErrorUpdate
std::atomic< unsigned int > m_ngoodRefits
MuonDriftCircleErrorStrategy m_errorStrategyBEE
ToolHandle< Trk::ITrackFitter > m_trackFitter
Gaudi::Property< bool > m_simpleAEOTs
MuonDriftCircleErrorStrategy m_errorStrategyBIS78
Gaudi::Property< bool > m_alignmentErrors
std::unique_ptr< Trk::Track > updateMdtErrors(const Trk::Track &track, const EventContext &ctx, const Settings &settings) const
std::atomic< unsigned int > m_nrefits
Gaudi::Property< bool > m_addMiddle
Gaudi::Property< int > m_finderDebugLevel
std::unique_ptr< Trk::Track > refit(const Trk::Track &track, const EventContext &ctx, const Settings *settings) const override
refit a track
Gaudi::Property< float > m_alignmentAngle
MuonDriftCircleErrorStrategy m_errorStrategyTwoStations
ToolHandle< Trk::IExtrapolator > m_muonExtrapolator
MuonRefitTool(const std::string &ty, const std::string &na, const IInterface *pa)
Gaudi::Property< float > m_alignmentAngleError
static std::unique_ptr< Trk::TrackStateOnSurface > createPerigeeTSOS(std::unique_ptr< Trk::TrackParameters > perigee)
create a perigee TSOS, takes ownership of the Perigee
static std::unique_ptr< Trk::TrackStateOnSurface > createMeasTSOSWithUpdate(const Trk::TrackStateOnSurface &tsos, 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
static std::unique_ptr< Trk::TrackStateOnSurface > cloneTSOS(const Trk::TrackStateOnSurface &tsos, Trk::TrackStateOnSurface::TrackStateOnSurfaceType type)
clone input, update the type
virtual bool fit(Segment &result, const Line &line, const DCOnTrackVec &dcs, double t0Seed=-99999.) const
This class represents a drift time measurement.
Definition DriftCircle.h:22
@ InTime
drift time too small to be compatible with drift spectrum
Definition DriftCircle.h:27
double x0() const
Definition Line.h:63
double phi() const
Definition Line.h:62
double y0() const
Definition Line.h:64
Implementation of 2 dimensional vector class.
Definition LocVec2D.h:16
const DCOnTrackVec & match(const DCVec &dcs)
SegVec findSegments(const DCVec &dcs) const
void setPhiRoad(double phiRoad, double phiChamber, double sinPhiCut=0.2, bool useRoadPhi=true, bool useChamberPhi=true)
void debugLevel(int debugLevel)
void setFitter(std::shared_ptr< const DCSLFitter > fitter)
An object decorating a track and holding degrees of freedom reflecting alignment accuracy.
represents the three-dimensional global direction with respect to a planar surface frame.
This class is the pure abstract base class for all fittable tracking measurements.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
std::unique_ptr< ParametersBase< DIM, T > > uniqueClone() const
clone method for polymorphic deep copy returning unique_ptr; it is not overriden, but uses the existi...
Class describing the Line to which the Perigee refers to.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
represents the track state (measurement, material, fit parameters and quality) at a surface.
const MeasurementBase * measurementOnTrack() const
returns MeasurementBase const overload
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ Alignment
This TSOS contains a Trk::AlignmentEffectsOnTrack.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
STL class.
holding In fact this class is here in order to allow STL container for all features This class is sho...
int r
Definition globals.cxx:22
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
StIndex
enum to classify the different station layers in the muon spectrometer
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
const std::string & stName(StIndex index)
convert StIndex into a string
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
std::bitset< 23 > MuonDriftCircleErrorStrategyInput
DCOnTrackVec::const_iterator DCOnTrackCit
Definition DCOnTrack.h:61
std::vector< DriftCircle > DCVec
std::vector< DCOnTrack > DCOnTrackVec
Definition DCOnTrack.h:59
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ locR
Definition ParamDefs.h:44
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1
ElementLink_p1< typename GenerateELinkIndexType_p1< typename LINK::index_type >::type > type
Helper struct to overload the destructors of smart pointers.
bool prepareForFit
update the errors of the trigger hits
std::set< MuonStationIndex::PhiIndex > phiLayersToBeremoved
all precision hits in station layers that are in the list are turned into outliers
bool refit
use broad error settings
bool removeOutliers
toogle on/off refit of the track
std::set< MuonStationIndex::StIndex > precisionLayersToBeremoved
all hits in chambers that are in the list are turned into outliers
bool discardNotCleanedTracks
remove MDT outliers locally redoing the local segment fit
bool updateErrors
recalibrate the hits
bool removeBarrelEndcapOverlap
all trigger eta hits are turned into outliers
bool deweightOtherSectors
remove all hits in sectors that are not the main sector
bool updateTriggerErrors
update the errors without recalibrating
bool extrapolateToMuonEntry
de-weight all hits in sectors that are not the main sector
bool removeBEE
turn all hits in the barrel/endcap part of the track with least hits into outliers
std::set< Identifier > chambersToBeremoved
turn all hits in the BEE chambers into outliers
bool removeOtherSectors
recreate starting parameters by extrapolating from first hit on track
bool recreateStartingParameters
prepare the input track for a refit