From f74a2cbc35524e1547a163264bd0aed281f09ec8 Mon Sep 17 00:00:00 2001 From: William Axel Leight <william.axel.leight@cern.ch> Date: Wed, 12 Aug 2020 18:30:27 +0000 Subject: [PATCH] Remove const_cast from MuonErrorOptimisationTool As the track passed into the tool is always non-const, there was no reason for the tracks that are being passed around inside the tool, or the MuonRefitTool that it calls, to be const. The const_casts compensated for this not-really-constness: removing it means that they can be removed as well. Additionally, I took advantage of this change to switch to using unique_ptr for the tracks, and did some minor cleanup in the MuonRefitTool. --- .../IMuonErrorOptimisationTool.h | 2 +- .../MuonRecToolInterfaces/IMuonRefitTool.h | 4 +- .../src/MuonErrorOptimisationTool.cxx | 62 +-- .../src/MuonErrorOptimisationTool.h | 2 +- .../src/MuonRefitTool.cxx | 452 +++++++++--------- .../MuonTrackFinderTools/src/MuonRefitTool.h | 16 +- .../src/MooTrackBuilder.cxx | 4 +- .../src/CombinedMuonTrackBuilder.cxx | 190 ++++---- .../src/OutwardsCombinedMuonTrackBuilder.cxx | 15 +- 9 files changed, 355 insertions(+), 392 deletions(-) diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonErrorOptimisationTool.h b/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonErrorOptimisationTool.h index e4780b929d0..8b490fb8667 100644 --- a/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonErrorOptimisationTool.h +++ b/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonErrorOptimisationTool.h @@ -23,7 +23,7 @@ namespace Muon { static const InterfaceID& interfaceID(); /** optimise errors on a track to maximize the momentum resolution */ - virtual Trk::Track* optimiseErrors(Trk::Track& track ) const = 0; + virtual std::unique_ptr<Trk::Track> optimiseErrors(Trk::Track* track ) const = 0; }; diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonRefitTool.h b/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonRefitTool.h index e4c5b72ae0f..72ba99d9746 100644 --- a/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonRefitTool.h +++ b/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonRefitTool.h @@ -53,10 +53,10 @@ namespace Muon { static const InterfaceID& interfaceID(); /** refit a track */ - virtual const Trk::Track* refit( const Trk::Track& track, const Settings* settings = 0 ) const = 0; + virtual std::unique_ptr<Trk::Track> refit( Trk::Track* track, const Settings* settings = 0 ) const = 0; /** refit and back extrapolate a vector of track pairs */ - virtual std::vector<const Trk::Track*> refit( const std::vector<const Trk::Track*>& tracks, const Settings* settings = 0 ) const = 0; + virtual std::vector<std::unique_ptr<Trk::Track> > refit( std::vector<Trk::Track*>& tracks, const Settings* settings = 0 ) const = 0; }; diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.cxx index 100e3a5bb43..7679206d8f0 100644 --- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.cxx +++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.cxx @@ -63,24 +63,22 @@ namespace Muon { return StatusCode::SUCCESS; } - Trk::Track* MuonErrorOptimisationTool::optimiseErrors( Trk::Track& track ) const { + std::unique_ptr<Trk::Track> MuonErrorOptimisationTool::optimiseErrors( Trk::Track* track ) const { - if( m_refitTool.empty() ) return 0; - const Trk::Perigee* pp = track.perigeeParameters(); + if( m_refitTool.empty() ) return std::unique_ptr<Trk::Track>(); + const Trk::Perigee* pp = track->perigeeParameters(); bool isLowPt = false; if( pp && pp->momentum().mag() < m_lowPtThreshold ) isLowPt = true; if( isLowPt ) ++m_nrefitAllLowPt; else ++m_nrefitAll; - - const Trk::Track* refittedTrack = 0; - const Trk::Track* result1 = 0; - const Trk::Track* result2 = 0; + std::unique_ptr<Trk::Track> result1; + std::unique_ptr<Trk::Track> result2; // first refit with precise errors IMuonRefitTool::Settings settings = m_refitSettings; settings.broad = false; - refittedTrack = m_refitTool->refit(track,&settings); + std::unique_ptr<Trk::Track> refittedTrack = m_refitTool->refit(track,&settings); if( refittedTrack ){ // check whether it is ok @@ -88,8 +86,7 @@ namespace Muon { ATH_MSG_VERBOSE("Precise fit bad " << std::endl << m_printer->print(*refittedTrack) << std::endl << m_printer->printStations(*refittedTrack)); // if not delete track - result1 = refittedTrack != &track ? refittedTrack : 0; - refittedTrack = 0; + result1.swap(refittedTrack); }else{ ATH_MSG_VERBOSE("Precise fit ok " << std::endl << m_printer->print(*refittedTrack) << std::endl << m_printer->printStations(*refittedTrack)); if( isLowPt ) ++m_nrefitPreciseLowPt; @@ -110,8 +107,7 @@ namespace Muon { if( !m_edmHelperSvc->goodTrack(*refittedTrack,m_chi2NdofCutRefit) ) { ATH_MSG_VERBOSE("Loose fit bad " << std::endl << m_printer->print(*refittedTrack) << std::endl << m_printer->printStations(*refittedTrack)); // if not delete track - result2 = refittedTrack != &track ? refittedTrack : 0; - refittedTrack = 0; + result2.swap(refittedTrack); }else{ ATH_MSG_VERBOSE("Loose fit ok " << std::endl << m_printer->print(*refittedTrack) << std::endl << m_printer->printStations(*refittedTrack)); if( isLowPt ) ++m_nrefitLowPt; @@ -124,13 +120,13 @@ namespace Muon { } // if failed to refit or refit returned original track, return 0 - if( !refittedTrack || refittedTrack == &track ){ + if( !refittedTrack || *refittedTrack->perigeeParameters() == *track->perigeeParameters() ){ // check if any refit succeeded - if( !result1 && !result2 ) return 0; + if( !result1 && !result2 ) return std::unique_ptr<Trk::Track>(); // now compare chi2 - const Trk::FitQuality* fq0 = track.fitQuality(); + const Trk::FitQuality* fq0 = track->fitQuality(); const Trk::FitQuality* fq1 = result1 ? result1->fitQuality() : 0; const Trk::FitQuality* fq2 = result2 ? result2->fitQuality() : 0; @@ -147,56 +143,56 @@ namespace Muon { doSelection = false; // ugly bit of code to get the hit counts for the three tracks int nhits0 = -1; - Trk::TrackSummary* summary0 = track.trackSummary(); + Trk::TrackSummary* summary0 = track->trackSummary(); Trk::MuonTrackSummary* muonSummary0 = 0; if( summary0 ){ if( summary0->muonTrackSummary() ) { muonSummary0 = summary0->muonTrackSummary(); if( muonSummary0 ) nhits0 = muonSummary0->netaHits()+ muonSummary0->nphiHits(); - }else{ + }else{ Trk::TrackSummary tmpSum(*summary0); - m_trackSummaryTool->addDetailedTrackSummary(track,tmpSum); + m_trackSummaryTool->addDetailedTrackSummary(*track,tmpSum); if( tmpSum.muonTrackSummary() ) nhits0 = muonSummary0->netaHits()+ muonSummary0->nphiHits(); } }else{ Trk::TrackSummary tmpSummary; - m_trackSummaryTool->addDetailedTrackSummary(track,tmpSummary); + m_trackSummaryTool->addDetailedTrackSummary(*track,tmpSummary); if( tmpSummary.muonTrackSummary() ) muonSummary0 = tmpSummary.muonTrackSummary(); if( muonSummary0 ) nhits0 = muonSummary0->netaHits()+ muonSummary0->nphiHits(); } int nhits1 = -1; - Trk::TrackSummary* summary1 = track.trackSummary(); + Trk::TrackSummary* summary1 = track->trackSummary(); Trk::MuonTrackSummary* muonSummary1 = 0; if( summary1 ){ if( summary1->muonTrackSummary() ) muonSummary1 = summary1->muonTrackSummary(); else{ Trk::TrackSummary* tmpSum = summary1; - if( tmpSum ) m_trackSummaryTool->addDetailedTrackSummary(track,*tmpSum); + if( tmpSum ) m_trackSummaryTool->addDetailedTrackSummary(*track,*tmpSum); if( tmpSum->muonTrackSummary() ) muonSummary1 = tmpSum->muonTrackSummary(); } if( muonSummary1 ) nhits1 = muonSummary1->netaHits()+ muonSummary1->nphiHits(); }else{ Trk::TrackSummary tmpSummary; - m_trackSummaryTool->addDetailedTrackSummary(track,tmpSummary); + m_trackSummaryTool->addDetailedTrackSummary(*track,tmpSummary); if( tmpSummary.muonTrackSummary() ) muonSummary1 = tmpSummary.muonTrackSummary(); if( muonSummary1 ) nhits1 = muonSummary1->netaHits()+ muonSummary1->nphiHits(); } int nhits2 = -1; - Trk::TrackSummary* summary2 = track.trackSummary(); + Trk::TrackSummary* summary2 = track->trackSummary(); Trk::MuonTrackSummary* muonSummary2 = 0; if( summary2 ){ if( summary2->muonTrackSummary() ) muonSummary2 = summary2->muonTrackSummary(); else{ Trk::TrackSummary* tmpSum = summary2; - if( tmpSum ) m_trackSummaryTool->addDetailedTrackSummary(track,*tmpSum); + if( tmpSum ) m_trackSummaryTool->addDetailedTrackSummary(*track,*tmpSum); if( tmpSum->muonTrackSummary() ) muonSummary2 = tmpSum->muonTrackSummary(); } if( muonSummary2 ) nhits2 = muonSummary2->netaHits()+ muonSummary2->nphiHits(); }else{ Trk::TrackSummary tmpSummary; - m_trackSummaryTool->addDetailedTrackSummary(track,tmpSummary); + m_trackSummaryTool->addDetailedTrackSummary(*track,tmpSummary); if( tmpSummary.muonTrackSummary() ) muonSummary2 = tmpSummary.muonTrackSummary(); if( muonSummary2 ) nhits2 = muonSummary2->netaHits()+ muonSummary2->nphiHits(); } @@ -220,27 +216,19 @@ namespace Muon { if( chi2Refit < fq0->chiSquared() ){ if( firstIsBest ) { ATH_MSG_DEBUG("Keeping precise refit"); - delete result2; ++m_nbetterPreciseFit; - return const_cast<Trk::Track*>(result1); + return result1; }else{ ATH_MSG_DEBUG("Keeping loose refit"); - delete result1; ++m_nbetterFit; - return const_cast<Trk::Track*>(result2); + return result2; } } } - // clean up - delete result1; - delete result2; - return 0; + return std::unique_ptr<Trk::Track>(); } - // clean up - if( result1 && result1 != refittedTrack ) delete result1; -// if( result2 && result2 != refittedTrack ) delete result2; - return const_cast<Trk::Track*>(refittedTrack); + return refittedTrack; } } diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.h b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.h index e144fa27f12..a1e46f51676 100644 --- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.h +++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonErrorOptimisationTool.h @@ -30,7 +30,7 @@ namespace Muon { virtual StatusCode finalize() override; /** optimise the error strategy used for the track */ - virtual Trk::Track* optimiseErrors( Trk::Track& track ) const override; + virtual std::unique_ptr<Trk::Track> optimiseErrors( Trk::Track* track ) const override; private: ServiceHandle<IMuonEDMHelperSvc> m_edmHelperSvc {this, "edmHelper", "Muon::MuonEDMHelperSvc/MuonEDMHelperSvc", "Handle to the service providing the IMuonEDMHelperSvc interface" }; diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.cxx index 28a5a250145..1d3969d285e 100644 --- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.cxx +++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.cxx @@ -155,255 +155,247 @@ namespace Muon { return StatusCode::SUCCESS; } - const Trk::Track* MuonRefitTool::refit( const Trk::Track& track, const IMuonRefitTool::Settings* set ) const { + std::unique_ptr<Trk::Track> MuonRefitTool::refit( Trk::Track* track, const IMuonRefitTool::Settings* set ) const { const IMuonRefitTool::Settings& settings = set ? *set : m_defaultSettings; + //to keep track of the latest track + std::unique_ptr<Trk::Track> newTrack; ++m_nrefits; - const Trk::Track* newTrack = &track; if( settings.removeOutliers ){ - const Trk::Track* cleanedTrack = removeOutliers(*newTrack,settings); + std::unique_ptr<Trk::Track> cleanedTrack = removeOutliers(track,settings); if( !cleanedTrack ){ ATH_MSG_DEBUG("Track lost during outlier removal"); ++m_failedOutlierRemoval; - return newTrack; + return std::make_unique<Trk::Track>(*track); } - if( cleanedTrack != newTrack ){ + if( cleanedTrack->perigeeParameters() != track->perigeeParameters() ){ ATH_MSG_DEBUG("Outlier removal removed hits from track"); - if( newTrack != &track ) delete newTrack; - } - newTrack = cleanedTrack; + } + newTrack.swap(cleanedTrack); } + else newTrack=std::make_unique<Trk::Track>(*track); if( settings.updateErrors ){ - Trk::Track* updateErrorTrack = m_alignmentErrors ? updateAlignmentErrors(*newTrack,settings) : updateErrors(*newTrack,settings); + std::unique_ptr<Trk::Track> updateErrorTrack = m_alignmentErrors ? updateAlignmentErrors(newTrack.get(),settings) : updateErrors(newTrack.get(),settings); if( !updateErrorTrack ) { ATH_MSG_WARNING("Failed to update errors"); ++m_failedErrorUpdate; return newTrack; } - if( updateErrorTrack != newTrack && newTrack != &track ) delete newTrack; - newTrack = updateErrorTrack; + newTrack.swap(updateErrorTrack); } if( settings.refit ){ - ATH_MSG_DEBUG("Original track" << m_printer->print(*&track) ); + ATH_MSG_DEBUG("Original track" << m_printer->print(*track) ); -// do not put AEOTs on extremely bad chi2 tracks and do not refit them + // do not put AEOTs on extremely bad chi2 tracks and do not refit them - Trk::Track* refittedTrack = track.fitQuality()&&track.fitQuality()->chiSquared()<10000*track.fitQuality()->numberDoF() ? m_trackFitter->fit(*newTrack,false,Trk::muon) : 0 ; + std::unique_ptr<Trk::Track> refittedTrack; + if(track->fitQuality() && track->fitQuality()->chiSquared()<10000*track->fitQuality()->numberDoF()) + refittedTrack= std::unique_ptr<Trk::Track>(m_trackFitter->fit(*newTrack,false,Trk::muon)); if( !refittedTrack ){ ATH_MSG_DEBUG("Failed to refit track"); ++m_failedRefit; -// BUG fix Peter - delete newTrack; - newTrack = &track; - return newTrack; + // BUG fix Peter + return std::make_unique<Trk::Track>(*track); } ATH_MSG_DEBUG("Refitted track" << m_printer->print(*refittedTrack) ); ATH_MSG_DEBUG("Refitted track" << m_printer->printMeasurements(*refittedTrack) ); - if( refittedTrack != newTrack && newTrack != &track ) delete newTrack; - newTrack = refittedTrack; + newTrack.swap(refittedTrack); } if( settings.extrapolateToMuonEntry ){ - Trk::Track* extrapolatedTrack = m_muonEntryTrackExtrapolator->extrapolate(*newTrack); + std::unique_ptr<Trk::Track> extrapolatedTrack(m_muonEntryTrackExtrapolator->extrapolate(*newTrack)); if( !extrapolatedTrack ){ ATH_MSG_WARNING("Failed to back-extrapolate track"); ++m_failedExtrapolationMuonEntry; return newTrack; } ATH_MSG_DEBUG("Entry track " << m_printer->print(*extrapolatedTrack) ); - if( extrapolatedTrack != newTrack && newTrack != &track ) delete newTrack; - newTrack = extrapolatedTrack; + newTrack.swap(extrapolatedTrack); } ++m_ngoodRefits; return newTrack; } - std::vector<const Trk::Track*> MuonRefitTool::refit( const std::vector<const Trk::Track*>& tracks, const IMuonRefitTool::Settings* set ) const { + std::vector<std::unique_ptr<Trk::Track> > MuonRefitTool::refit( std::vector<Trk::Track*>& tracks, const IMuonRefitTool::Settings* set ) const { - std::vector<const Trk::Track*> refittedTracks; + std::vector<std::unique_ptr<Trk::Track> > refittedTracks; refittedTracks.reserve(tracks.size()); - std::vector<const Trk::Track*>::const_iterator it = tracks.begin(); - std::vector<const Trk::Track*>::const_iterator it_end = tracks.end(); + std::vector<Trk::Track*>::const_iterator it = tracks.begin(); + std::vector<Trk::Track*>::const_iterator it_end = tracks.end(); for( ;it!=it_end;++it ){ - const Trk::Track* refittedTrack = refit(**it,set); - if( refittedTrack == *it ) refittedTrack = new Trk::Track(**it); - - if(refittedTrack) refittedTracks.push_back(refittedTrack); + refittedTracks.push_back(refit(*it,set)); } return refittedTracks; } - Trk::Track* MuonRefitTool::updateAlignmentErrors( const Trk::Track& track, const IMuonRefitTool::Settings& settings ) const { - + std::unique_ptr<Trk::Track> MuonRefitTool::updateAlignmentErrors( Trk::Track* track, const IMuonRefitTool::Settings& settings ) const { -// first scale the Mdt errors + // first scale the Mdt errors - const Trk::Track* inputTrack = &track; - Trk::Track* updatedTrack = updateMdtErrors(*inputTrack,settings); - - Trk::Track* updatedAEOTsTrack = m_simpleAEOTs ? makeSimpleAEOTs(*updatedTrack) : makeAEOTs(*updatedTrack); - if( updatedAEOTsTrack != updatedTrack ) delete updatedTrack; + std::unique_ptr<Trk::Track> updatedTrack = updateMdtErrors(track,settings); + + std::unique_ptr<Trk::Track> updatedAEOTsTrack = m_simpleAEOTs ? makeSimpleAEOTs(updatedTrack.get()) : makeAEOTs(updatedTrack.get()); - return updatedAEOTsTrack; + return updatedAEOTsTrack; } - Trk::Track* MuonRefitTool::makeAEOTs( const Trk::Track& track ) const { + std::unique_ptr<Trk::Track> MuonRefitTool::makeAEOTs( Trk::Track* track ) const { -// -// use the new AlignmentEffectsOnTrack class and alignmentErrorTool -// + // + // use the new AlignmentEffectsOnTrack class and alignmentErrorTool + // if( m_alignErrorTool.empty() ) { - Trk::Track* newTrack = new Trk::Track( track ); + std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>( *track ); return newTrack; } -// -// Use the alignmentErrorTool and store a list of hits with error on position and angle -// + // + // Use the alignmentErrorTool and store a list of hits with error on position and angle + // std::map< std::vector<Identifier>, std::pair <double, double> > alignerrmap; - std::vector<Trk::AlignmentDeviation*> align_deviations; - m_alignErrorTool->makeAlignmentDeviations(track, align_deviations); - - int iok = 0; - bool isSmallChamber = false; - bool isLargeChamber = false; - bool isEndcap = false; - bool isBarrel = false; - std::vector <int> usedRotations; - - // loop on deviations - for(auto it : align_deviations){ - double angleError = 0.; - double translationError = 0.; - bool differentChambers = false; - int jdifferent = -1; - isSmallChamber = false; - isLargeChamber = false; - isEndcap = false; - isBarrel = false; - - if( dynamic_cast<MuonAlign::AlignmentTranslationDeviation*>(it) ) { - translationError = std::sqrt(it->getCovariance(0,0)); - // vector to store hit id - std::vector<Identifier> hitids; - std::vector<const Trk::RIO_OnTrack*> vec_riowithdev; - it->getListOfHits(vec_riowithdev); - // bool to decide if deviation should be skipped (if it's for more than 1 station) - for(auto riowithdev : vec_riowithdev){ - Identifier id_riowithdev = riowithdev->identify(); - if(m_idHelperSvc->isEndcap(id_riowithdev)) { - isEndcap = true; - } else { - isBarrel = true; - } - if(m_idHelperSvc->isSmallChamber(id_riowithdev)) { - isSmallChamber = true; - } else { - isLargeChamber = true; - } - hitids.push_back(id_riowithdev); - if( hitids.size()>1 && m_idHelperSvc->chamberId(id_riowithdev) != m_idHelperSvc->chamberId(hitids[0]) ) { - differentChambers = true; - jdifferent = hitids.size()-1; - } - } - bool matchFound = false; - if( hitids.size()>0) { - int iRot = -1; - for(auto itRot : align_deviations){ - iRot++; - if( dynamic_cast<MuonAlign::AlignmentRotationDeviation*>(itRot) ) { - if( itRot->hasValidHashOfHits() && it->hasValidHashOfHits() ) { - if( itRot->getHashOfHits() == it->getHashOfHits() ){ - angleError = std::sqrt(itRot->getCovariance(0,0)); - matchFound = true; - usedRotations.push_back(iRot); - } - } else { - ATH_MSG_ERROR("One of the alignment deviations has an invalid hash created from the hits."); - } - } - if(matchFound) break; - } - } - // if deviation is accepted (i.e. only on one station) store the hit IDs associated with the deviation and the error - -// store (all) translationError with or without a matched angleError - iok++; - alignerrmap.insert( std::pair < std::vector<Identifier>, std::pair < double, double > > ( hitids, std::pair < double, double > (translationError,angleError) ) ); - - if(matchFound) ATH_MSG_DEBUG(" AlignmentMap entry " << iok << " filled with nr hitids " << hitids.size() << " " << m_idHelperSvc->toString(hitids[0]) << " translationError " << translationError << " angleError " << angleError ); - if(!matchFound) ATH_MSG_DEBUG(" AlignmentMap entry No angleError" << iok << " filled with nr hitids " << hitids.size() << " " << m_idHelperSvc->toString(hitids[0]) << " translationError " << translationError << " angleError " << angleError ); - if(isEndcap) ATH_MSG_DEBUG(" AlignmentMap Endcap Chamber "); - if(isBarrel) ATH_MSG_DEBUG(" AlignmentMap Barrel Chamber "); - if(isSmallChamber) ATH_MSG_DEBUG(" AlignmentMap Small Chamber "); - if(isLargeChamber) ATH_MSG_DEBUG(" AlignmentMap Large Chamber "); - if(differentChambers) ATH_MSG_DEBUG(" AlignmentMap entry " << iok << " for different Chamber " << m_idHelperSvc->toString(hitids[jdifferent]) ); - } + std::vector<Trk::AlignmentDeviation*> align_deviations; + m_alignErrorTool->makeAlignmentDeviations(*track, align_deviations); + + int iok = 0; + bool isSmallChamber = false; + bool isLargeChamber = false; + bool isEndcap = false; + bool isBarrel = false; + std::vector <int> usedRotations; + + // loop on deviations + for(auto it : align_deviations){ + double angleError = 0.; + double translationError = 0.; + bool differentChambers = false; + int jdifferent = -1; + isSmallChamber = false; + isLargeChamber = false; + isEndcap = false; + isBarrel = false; + + if( dynamic_cast<MuonAlign::AlignmentTranslationDeviation*>(it) ) { + translationError = std::sqrt(it->getCovariance(0,0)); + // vector to store hit id + std::vector<Identifier> hitids; + std::vector<const Trk::RIO_OnTrack*> vec_riowithdev; + it->getListOfHits(vec_riowithdev); + // bool to decide if deviation should be skipped (if it's for more than 1 station) + for(auto riowithdev : vec_riowithdev){ + Identifier id_riowithdev = riowithdev->identify(); + if(m_idHelperSvc->isEndcap(id_riowithdev)) { + isEndcap = true; + } else { + isBarrel = true; + } + if(m_idHelperSvc->isSmallChamber(id_riowithdev)) { + isSmallChamber = true; + } else { + isLargeChamber = true; + } + hitids.push_back(id_riowithdev); + if( hitids.size()>1 && m_idHelperSvc->chamberId(id_riowithdev) != m_idHelperSvc->chamberId(hitids[0]) ) { + differentChambers = true; + jdifferent = hitids.size()-1; + } + } + bool matchFound = false; + if( hitids.size()>0) { + int iRot = -1; + for(auto itRot : align_deviations){ + iRot++; + if( dynamic_cast<MuonAlign::AlignmentRotationDeviation*>(itRot) ) { + if( itRot->hasValidHashOfHits() && it->hasValidHashOfHits() ) { + if( itRot->getHashOfHits() == it->getHashOfHits() ){ + angleError = std::sqrt(itRot->getCovariance(0,0)); + matchFound = true; + usedRotations.push_back(iRot); + } + } else { + ATH_MSG_ERROR("One of the alignment deviations has an invalid hash created from the hits."); + } + } + if(matchFound) break; + } + } + // if deviation is accepted (i.e. only on one station) store the hit IDs associated with the deviation and the error + + // store (all) translationError with or without a matched angleError + iok++; + alignerrmap.insert( std::pair < std::vector<Identifier>, std::pair < double, double > > ( hitids, std::pair < double, double > (translationError,angleError) ) ); + + if(matchFound) ATH_MSG_DEBUG(" AlignmentMap entry " << iok << " filled with nr hitids " << hitids.size() << " " << m_idHelperSvc->toString(hitids[0]) << " translationError " << translationError << " angleError " << angleError ); + if(!matchFound) ATH_MSG_DEBUG(" AlignmentMap entry No angleError" << iok << " filled with nr hitids " << hitids.size() << " " << m_idHelperSvc->toString(hitids[0]) << " translationError " << translationError << " angleError " << angleError ); + if(isEndcap) ATH_MSG_DEBUG(" AlignmentMap Endcap Chamber "); + if(isBarrel) ATH_MSG_DEBUG(" AlignmentMap Barrel Chamber "); + if(isSmallChamber) ATH_MSG_DEBUG(" AlignmentMap Small Chamber "); + if(isLargeChamber) ATH_MSG_DEBUG(" AlignmentMap Large Chamber "); + if(differentChambers) ATH_MSG_DEBUG(" AlignmentMap entry " << iok << " for different Chamber " << m_idHelperSvc->toString(hitids[jdifferent]) ); } + } -// now add the angleErrors that were NOT matched to a translationError - - int iRot = -1; - for(auto itRot : align_deviations){ - iRot++; - isSmallChamber = false; - isLargeChamber = false; - isEndcap = false; - isBarrel = false; - if( dynamic_cast<MuonAlign::AlignmentRotationDeviation*>(itRot) ) { - bool used = false; - for (unsigned int i = 0; i < usedRotations.size(); i++) { - if(iRot == usedRotations[i]) used = true; - } - if(used) continue; - ATH_MSG_ERROR("This following code should not be reached anymore!"); - std::vector<const Trk::RIO_OnTrack*> vec_riowithdev; - itRot->getListOfHits(vec_riowithdev); - - std::vector<Identifier> hitids; - // bool to decide if deviation should be skipped (if it's for more than 1 station) - for(auto riowithdev : vec_riowithdev){ - Identifier id_riowithdev = riowithdev->identify(); - if(m_idHelperSvc->isEndcap(id_riowithdev)) { - isEndcap = true; - } else { - isBarrel = true; - } - if(m_idHelperSvc->isSmallChamber(id_riowithdev)) { - isSmallChamber = true; - } else { - isLargeChamber = true; - } - hitids.push_back(id_riowithdev); - } - - double translationError = 0.; - double angleError = std::sqrt(itRot->getCovariance(0,0)); - - iok++; - alignerrmap.insert( std::pair < std::vector<Identifier>, std::pair < double, double > > ( hitids, std::pair < double, double > (translationError,angleError) ) ); - ATH_MSG_DEBUG(" AlignmentMap entry No Translation Error " << iok << " filled with nr hitids " << hitids.size() << " " << m_idHelperSvc->toString(hitids[0]) << " translationError " << translationError << " angleError " << angleError ); - if(isEndcap) ATH_MSG_DEBUG(" AlignmentMap Endcap Chamber"); - if(isBarrel) ATH_MSG_DEBUG(" AlignmentMap Barrel Chamber"); - if(isSmallChamber) ATH_MSG_DEBUG(" AlignmentMap Small Chamber "); - if(isLargeChamber) ATH_MSG_DEBUG(" AlignmentMap Large Chamber "); - } + // now add the angleErrors that were NOT matched to a translationError + + int iRot = -1; + for(auto itRot : align_deviations){ + iRot++; + isSmallChamber = false; + isLargeChamber = false; + isEndcap = false; + isBarrel = false; + if( dynamic_cast<MuonAlign::AlignmentRotationDeviation*>(itRot) ) { + bool used = false; + for (unsigned int i = 0; i < usedRotations.size(); i++) { + if(iRot == usedRotations[i]) used = true; + } + if(used) continue; + ATH_MSG_ERROR("This following code should not be reached anymore!"); + std::vector<const Trk::RIO_OnTrack*> vec_riowithdev; + itRot->getListOfHits(vec_riowithdev); + + std::vector<Identifier> hitids; + // bool to decide if deviation should be skipped (if it's for more than 1 station) + for(auto riowithdev : vec_riowithdev){ + Identifier id_riowithdev = riowithdev->identify(); + if(m_idHelperSvc->isEndcap(id_riowithdev)) { + isEndcap = true; + } else { + isBarrel = true; + } + if(m_idHelperSvc->isSmallChamber(id_riowithdev)) { + isSmallChamber = true; + } else { + isLargeChamber = true; + } + hitids.push_back(id_riowithdev); + } + + double translationError = 0.; + double angleError = std::sqrt(itRot->getCovariance(0,0)); + + iok++; + alignerrmap.insert( std::pair < std::vector<Identifier>, std::pair < double, double > > ( hitids, std::pair < double, double > (translationError,angleError) ) ); + ATH_MSG_DEBUG(" AlignmentMap entry No Translation Error " << iok << " filled with nr hitids " << hitids.size() << " " << m_idHelperSvc->toString(hitids[0]) << " translationError " << translationError << " angleError " << angleError ); + if(isEndcap) ATH_MSG_DEBUG(" AlignmentMap Endcap Chamber"); + if(isBarrel) ATH_MSG_DEBUG(" AlignmentMap Barrel Chamber"); + if(isSmallChamber) ATH_MSG_DEBUG(" AlignmentMap Small Chamber "); + if(isLargeChamber) ATH_MSG_DEBUG(" AlignmentMap Large Chamber "); } + } - // clean-up of alignment deviations - for(auto it : align_deviations) delete it; - align_deviations.clear(); + // clean-up of alignment deviations + for(auto it : align_deviations) delete it; + align_deviations.clear(); - const DataVector<const Trk::TrackStateOnSurface>* states = track.trackStateOnSurfaces(); + const DataVector<const Trk::TrackStateOnSurface>* states = track->trackStateOnSurfaces(); if( !states ){ ATH_MSG_WARNING(" track without states, discarding track "); return 0; @@ -439,7 +431,7 @@ namespace Muon { if( m_idHelperSvc->isMdt(id) ) stationIds.insert( m_idHelperSvc->chamberIndex(id) ); -// make Alignment Effect using the surface of the TSOS + // make Alignment Effect using the surface of the TSOS if(idMiddle==id) { double deltaError = itAli.second.first; @@ -457,9 +449,9 @@ namespace Muon { if(!found) ATH_MSG_WARNING(" This should not happen Identifier from AlignmentErrorTool is not found"); } -// -// clone the TSOSs and add the tsosAEOTs -// + // + // clone the TSOSs and add the tsosAEOTs + // DataVector<const Trk::TrackStateOnSurface>* trackStateOnSurfaces = new DataVector<const Trk::TrackStateOnSurface>(); trackStateOnSurfaces->reserve(states->size()+indexAEOTs.size()); tsit = states->begin(); @@ -482,7 +474,7 @@ namespace Muon { if(indexAEOTs.size()==0 && stationIds.size() > 1) ATH_MSG_WARNING(" Track without AEOT "); - Trk::Track* newTrack = new Trk::Track( track.info(), trackStateOnSurfaces, track.fitQuality() ? track.fitQuality()->clone():0 ); + std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>( track->info(), trackStateOnSurfaces, track->fitQuality() ? track->fitQuality()->clone():0 ); ATH_MSG_DEBUG(m_printer->print(*newTrack)); ATH_MSG_DEBUG(m_printer->printMeasurements(*newTrack)); @@ -491,22 +483,22 @@ namespace Muon { } - Trk::Track* MuonRefitTool::makeSimpleAEOTs( const Trk::Track& track ) const { + std::unique_ptr<Trk::Track> MuonRefitTool::makeSimpleAEOTs( Trk::Track* track ) const { -// use the new AlignmentEffectsOnTrack class + // use the new AlignmentEffectsOnTrack class - const DataVector<const Trk::TrackStateOnSurface>* states = track.trackStateOnSurfaces(); + const DataVector<const Trk::TrackStateOnSurface>* states = track->trackStateOnSurfaces(); if( !states ){ ATH_MSG_WARNING(" track without states, discarding track "); - return 0; + return std::unique_ptr<Trk::Track>(); } DataVector<const Trk::TrackStateOnSurface>::const_iterator tsit = states->begin(); DataVector<const Trk::TrackStateOnSurface>::const_iterator tsit_end = states->end(); -// -// first clone the TSOSs -// + // + // first clone the TSOSs + // DataVector<const Trk::TrackStateOnSurface>* trackStateOnSurfaces = new DataVector<const Trk::TrackStateOnSurface>(); trackStateOnSurfaces->reserve(states->size()+1); for( ;tsit!=tsit_end ; ++tsit ){ @@ -514,7 +506,7 @@ namespace Muon { } -// loop over TSOSs and look for EM or BM chambers + // loop over TSOSs and look for EM or BM chambers tsit = trackStateOnSurfaces->begin(); tsit_end = trackStateOnSurfaces->end(); std::vector<const Trk::TrackStateOnSurface*> indicesOfAffectedTSOS; @@ -524,7 +516,6 @@ namespace Muon { int index = -1; int indexFirst = -1; int indexFirstInner = -1; -// const Trk::Surface *surf = 0; for( ; tsit!=tsit_end ; ++tsit ){ index++; if( !*tsit ) continue; //sanity check @@ -548,30 +539,28 @@ namespace Muon { // Not a ROT, else it would have had an identifier. Keep the TSOS. if( !id.is_valid() || !m_idHelperSvc->isMuon(id) ) continue; MuonStationIndex::StIndex stIndex = m_idHelperSvc->stationIndex(id); -// skip phi measurements + // skip phi measurements if( (m_idHelperSvc->isTrigger(id)&&m_idHelperSvc->measuresPhi(id)) || (m_idHelperSvc->isCsc(id)&&m_idHelperSvc->measuresPhi(id) ) ) continue; if(m_addAll) { -// skip RPC and TGC eta (to avoid code crashes) + // skip RPC and TGC eta (to avoid code crashes) if( m_idHelperSvc->isTrigger(id)) continue; if(indexFirst==-1) indexFirst = index; indicesOfAffectedTSOS.push_back(*tsit); indicesOfAffectedIds.push_back(id); } else { -// skip trigger hits and CSC phi measurements and select precision hits + // skip trigger hits and CSC phi measurements and select precision hits if( m_idHelperSvc->isTrigger(id)) continue; if( stIndex == MuonStationIndex::BM || stIndex == MuonStationIndex::EM) { if(indexFirst==-1) indexFirst = index; indicesOfAffectedTSOS.push_back(*tsit); indicesOfAffectedIds.push_back(id); -// two alignment discontinuities + // two alignment discontinuities if(m_addTwo) { if(indexFirstInner==-1) indexFirstInner = index; indicesOfAffectedTSOSInner.push_back(*tsit); indicesOfAffectedIdsInner.push_back(id); } } -// if( stIndex == MuonStationIndex::BO || stIndex == MuonStationIndex::EO || -// stIndex == MuonStationIndex::BI || stIndex == MuonStationIndex::EI) { if( stIndex == MuonStationIndex::BI || stIndex == MuonStationIndex::EI) { if(indexFirstInner==-1) indexFirstInner = index; indicesOfAffectedTSOSInner.push_back(*tsit); @@ -581,7 +570,7 @@ namespace Muon { } if(indicesOfAffectedTSOS.size()==0&&indicesOfAffectedTSOSInner.size()==0) { - Trk::Track* newTrack = new Trk::Track( track.info(), trackStateOnSurfaces, track.fitQuality() ? track.fitQuality()->clone():0 ); + std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>( track->info(), trackStateOnSurfaces, track->fitQuality() ? track->fitQuality()->clone():0 ); return newTrack; } @@ -601,7 +590,6 @@ namespace Muon { if(indicesOfAffectedTSOSInner.size()>0&&(m_addInner||m_addTwo)) { int middle = indicesOfAffectedTSOSInner.size()/2; const Trk::TrackStateOnSurface* tsosInner = indicesOfAffectedTSOSInner[middle]; -// const Trk::Surface *surfInner = dynamic_cast <Trk::Surface*> ((tsosInner->measurementOnTrack()->associatedSurface()).clone()); Trk::AlignmentEffectsOnTrack* aEOTInner = new Trk::AlignmentEffectsOnTrack(m_alignmentDelta,m_alignmentDeltaError,m_alignmentAngle,m_alignmentAngleError,indicesOfAffectedIdsInner,&(tsosInner->measurementOnTrack()->associatedSurface())); tsosAEOTInner = new Trk::TrackStateOnSurface(0,tsosInner->trackParameters()->clone(),0,0,typePattern,aEOTInner); } @@ -629,19 +617,7 @@ namespace Muon { if(!m_addInner&&!m_addTwo&&tsosAEOTInner) delete tsosAEOTInner; if(!m_addMiddle&&!m_addAll&&tsosAEOT) delete tsosAEOT; -// trackStateOnSurfacesAEOT->push_back(tsosAEOT); -// if(m_addInner) trackStateOnSurfacesAEOT->push_back(tsosAEOTInner); - - Trk::Track* newTrack = new Trk::Track( track.info(), trackStateOnSurfacesAEOT, track.fitQuality() ? track.fitQuality()->clone():0 ); - -// dump it -// const DataVector<const Trk::TrackStateOnSurface>* trackStateOnSurfacesNew = newTrack->trackStateOnSurfaces(); -// tsit = trackStateOnSurfacesNew->begin(); -// tsit_end = trackStateOnSurfacesNew->end(); -// for( ; tsit!=tsit_end ; ++tsit ){ -// if((*tsit)->alignmentEffectsOnTrack()) std::cout << " Peter alignmentEffectsOnTrack found with track pars " << (*tsit)->trackParameters() << std::endl; -// } - + std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>( track->info(), trackStateOnSurfacesAEOT, track->fitQuality() ? track->fitQuality()->clone():0 ); if(aEOT) ATH_MSG_DEBUG(" AlignmentEffectsOnTrack on surface " << aEOT->associatedSurface() << " nr of tsos affected " << indicesOfAffectedTSOS.size()); ATH_MSG_DEBUG(m_printer->print(*newTrack)); @@ -650,13 +626,13 @@ namespace Muon { return newTrack; } - Trk::Track* MuonRefitTool::updateErrors( const Trk::Track& track, const IMuonRefitTool::Settings& settings ) const { + std::unique_ptr<Trk::Track> MuonRefitTool::updateErrors( Trk::Track* track, const IMuonRefitTool::Settings& settings ) const { // loop over track and calculate residuals - const DataVector<const Trk::TrackStateOnSurface>* states = track.trackStateOnSurfaces(); + const DataVector<const Trk::TrackStateOnSurface>* states = track->trackStateOnSurfaces(); if( !states ){ ATH_MSG_WARNING(" track without states, discarding track "); - return 0; + return std::unique_ptr<Trk::Track>(); } // vector to store states, the boolean indicated whether the state was create in this routine (true) or belongs to the track (false) @@ -707,11 +683,11 @@ namespace Muon { } if( !startPars ){ - if( !track.trackParameters() || track.trackParameters()->empty() ){ + if( !track->trackParameters() || track->trackParameters()->empty() ){ ATH_MSG_WARNING("Track without parameters, cannot update errors"); - return 0; + return std::unique_ptr<Trk::Track>(); } - startPars = track.trackParameters()->front(); + startPars = track->trackParameters()->front(); ATH_MSG_VERBOSE("Did not find fit starting parameters, using first parameters " << m_printer->print(*startPars)); } @@ -1025,20 +1001,20 @@ namespace Muon { // 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 trackStateOnSurfaces->push_back( nit->first ? nit->second : nit->second->clone() ); } - Trk::Track* newTrack = new Trk::Track( track.info(), trackStateOnSurfaces, track.fitQuality() ? track.fitQuality()->clone():0 ); + std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>( track->info(), trackStateOnSurfaces, track->fitQuality() ? track->fitQuality()->clone():0 ); return newTrack; } - Trk::Track* MuonRefitTool::updateMdtErrors( const Trk::Track& track, const IMuonRefitTool::Settings& settings ) const { + std::unique_ptr<Trk::Track> MuonRefitTool::updateMdtErrors( Trk::Track* track, const IMuonRefitTool::Settings& settings ) const { -// uses the muonErrorStrategy + // uses the muonErrorStrategy // loop over track and calculate residuals - const DataVector<const Trk::TrackStateOnSurface>* states = track.trackStateOnSurfaces(); + const DataVector<const Trk::TrackStateOnSurface>* states = track->trackStateOnSurfaces(); if( !states ){ ATH_MSG_WARNING(" track without states, discarding track "); - return 0; + return std::unique_ptr<Trk::Track>(); } // vector to store states, the boolean indicated whether the state was create in this routine (true) or belongs to the track (false) @@ -1085,11 +1061,11 @@ namespace Muon { } if( !startPars ){ - if( !track.trackParameters() || track.trackParameters()->empty() ){ + if( !track->trackParameters() || track->trackParameters()->empty() ){ ATH_MSG_WARNING("Track without parameters, cannot update errors"); - return 0; + return std::unique_ptr<Trk::Track>(); } - startPars = track.trackParameters()->front(); + startPars = track->trackParameters()->front(); ATH_MSG_VERBOSE("Did not find fit starting parameters, using first parameters " << m_printer->print(*startPars)); } @@ -1175,7 +1151,7 @@ namespace Muon { } bool hasT0Fit = false; - if( mdt->errorStrategy().creationParameter(Muon::MuonDriftCircleErrorStrategy::T0Refit)) hasT0Fit = true; + if( mdt->errorStrategy().creationParameter(Muon::MuonDriftCircleErrorStrategy::T0Refit)) hasT0Fit = true; const Trk::RIO_OnTrack* rot = 0; Trk::TrackStateOnSurface::TrackStateOnSurfaceType type = (*tsit)->type(Trk::TrackStateOnSurface::Outlier) ? @@ -1183,7 +1159,7 @@ namespace Muon { stIndex = m_idHelperSvc->stationIndex(id); -// use the muonErrorStrategy + // use the muonErrorStrategy MuonDriftCircleErrorStrategy strat(m_muonErrorStrategy); if( hasT0Fit ) strat.setParameter(MuonDriftCircleErrorStrategy::T0Refit,true); if( settings.broad ) strat.setParameter(MuonDriftCircleErrorStrategy::BroadError,true); @@ -1240,7 +1216,6 @@ namespace Muon { } - }else{ if( settings.updateTriggerErrors ){ @@ -1274,18 +1249,18 @@ namespace Muon { // 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 trackStateOnSurfaces->push_back( nit->first ? nit->second : nit->second->clone() ); } - Trk::Track* newTrack = new Trk::Track( track.info(), trackStateOnSurfaces, track.fitQuality() ? track.fitQuality()->clone():0 ); + std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>( track->info(), trackStateOnSurfaces, track->fitQuality() ? track->fitQuality()->clone():0 ); return newTrack; } - const Trk::Track* MuonRefitTool::removeOutliers( const Trk::Track& track, const IMuonRefitTool::Settings& settings ) const { + std::unique_ptr<Trk::Track> MuonRefitTool::removeOutliers( Trk::Track* track, const IMuonRefitTool::Settings& settings ) const { // loop over track and calculate residuals - const DataVector<const Trk::TrackStateOnSurface>* states = track.trackStateOnSurfaces(); + const DataVector<const Trk::TrackStateOnSurface>* states = track->trackStateOnSurfaces(); if( !states ){ ATH_MSG_WARNING(" track without states, discarding track "); - return 0; + return std::unique_ptr<Trk::Track>(); } Identifier currentMdtChId; @@ -1340,7 +1315,7 @@ namespace Muon { if( chamberPars ){ if( !removeMdtOutliers(*chamberPars,mdts,removedIdentifiers,settings) ){ if( mdts.size() > 4 ) ATH_MSG_WARNING("Problem removing outliers in chamber " << m_idHelperSvc->toStringChamber(currentMdtChId) << " hits " << mdts.size()); - if( settings.discardNotCleanedTracks ) return 0; + if( settings.discardNotCleanedTracks ) return std::unique_ptr<Trk::Track>(); } } // update to new chamber @@ -1357,13 +1332,13 @@ namespace Muon { if( chamberPars ){ if( !removeMdtOutliers(*chamberPars,mdts,removedIdentifiers,settings) ){ if( mdts.size() > 4 ) ATH_MSG_WARNING("Problem removing outliers in chamber " << m_idHelperSvc->toStringChamber(currentMdtChId) << " hits " << mdts.size()); - if( settings.discardNotCleanedTracks ) return 0; + if( settings.discardNotCleanedTracks ) return std::unique_ptr<Trk::Track>(); } } if( removedIdentifiers.empty() ){ ATH_MSG_DEBUG("No hits remove, returning original track"); - return &track; + return std::make_unique<Trk::Track>(*track); } // states were added, create a new track @@ -1394,8 +1369,7 @@ namespace Muon { trackStateOnSurfaces->push_back( (*tsit)->clone() ); } - Trk::Track* newTrack = new Trk::Track( track.info(), trackStateOnSurfaces, track.fitQuality() ? track.fitQuality()->clone():0 ); - + std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>( track->info(), trackStateOnSurfaces, track->fitQuality() ? track->fitQuality()->clone():0 ); return newTrack; } diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.h b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.h index bc6c2a819d1..e6a23a411f6 100644 --- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.h +++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonRefitTool.h @@ -41,25 +41,25 @@ namespace Muon { virtual StatusCode finalize() override; /** refit a track */ - const Trk::Track* refit( const Trk::Track& track, const Settings* settings = 0 ) const override; + std::unique_ptr<Trk::Track> refit( Trk::Track* track, const Settings* settings = 0 ) const override; /** refit and back extrapolate a vector of track pairs */ - std::vector<const Trk::Track*> refit( const std::vector<const Trk::Track*>& tracks, const Settings* settings = 0 ) const override; + std::vector<std::unique_ptr<Trk::Track> > refit( std::vector<Trk::Track*>& tracks, const Settings* settings = 0 ) const override; protected: /** update errors on a muon track */ - Trk::Track* updateErrors( const Trk::Track& track, const Settings& settings ) const; + std::unique_ptr<Trk::Track> updateErrors( Trk::Track* track, const Settings& settings ) const; - Trk::Track* updateMdtErrors( const Trk::Track& track, const Settings& settings ) const; + std::unique_ptr<Trk::Track> updateMdtErrors( Trk::Track* track, const Settings& settings ) const; - Trk::Track* updateAlignmentErrors( const Trk::Track& track, const Settings& settings ) const; + std::unique_ptr<Trk::Track> updateAlignmentErrors( Trk::Track* track, const Settings& settings ) const; - Trk::Track* makeAEOTs( const Trk::Track& track ) const; + std::unique_ptr<Trk::Track> makeAEOTs( Trk::Track* track ) const; - Trk::Track* makeSimpleAEOTs( const Trk::Track& track ) const; + std::unique_ptr<Trk::Track> makeSimpleAEOTs( Trk::Track* track ) const; - const Trk::Track* removeOutliers( const Trk::Track& track,const Settings& settings ) const; + std::unique_ptr<Trk::Track> removeOutliers( Trk::Track* track,const Settings& settings ) const; bool removeMdtOutliers( const Trk::TrackParameters& pars, const std::vector<const MdtDriftCircleOnTrack*>& hits, std::set<Identifier>& removedIdentifiers, const Settings& settings ) const; diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MooTrackBuilder.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MooTrackBuilder.cxx index cf21aacec5c..9e11681eec6 100644 --- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MooTrackBuilder.cxx +++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MooTrackBuilder.cxx @@ -94,7 +94,9 @@ namespace Muon { // if not refit tool specified do a pure refit if( m_errorOptimisationTool.empty() ) return m_fitter->refit(track); - return m_errorOptimisationTool->optimiseErrors(track); + std::unique_ptr<Trk::Track> optTrack=m_errorOptimisationTool->optimiseErrors(&track); + //have to use release until the whole tool uses unique_ptr + return optTrack.release(); } MuPatTrack* MooTrackBuilder::refine( MuPatTrack& track ) const { diff --git a/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx b/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx index 6b05614defd..bf23fea72ae 100755 --- a/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx +++ b/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx @@ -2212,46 +2212,45 @@ CombinedMuonTrackBuilder::standaloneRefit(const Trk::Track& combinedTrack, float return nullptr; } - if (refittedTrack) { - if (!refittedTrack->fitQuality()) { - delete refittedTrack; - delete vertex; - return nullptr; + //eventually this whole tool will use unique_ptrs + //in the meantime, this allows the MuonErrorOptimisationTool and MuonRefitTool to use them + std::unique_ptr<Trk::Track> refittedTrackUnique(refittedTrack); + if (refittedTrackUnique) { + if (!refittedTrackUnique->fitQuality()) { + delete vertex; + return nullptr; } - if (!m_trackQuery->isCaloAssociated(*refittedTrack)) { + if (!m_trackQuery->isCaloAssociated(*refittedTrackUnique)) { // fail as calo incorrectly described m_messageHelper->printWarning(28); - delete refittedTrack; delete vertex; return nullptr; } - countAEOTs(refittedTrack, " standaloneRefit final refittedTrack "); + countAEOTs(refittedTrackUnique.get(), " standaloneRefit final refittedTrack "); // fit with optimized spectrometer errors // this should also be inside the "if(refittedTrack) statement - if (!m_muonErrorOptimizer.empty() && !refittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack) - && countAEOTs(refittedTrack, " before optimize ") == 0) + if (!m_muonErrorOptimizer.empty() && !refittedTrackUnique->info().trackProperties(Trk::TrackInfo::StraightTrack) + && countAEOTs(refittedTrackUnique.get(), " before optimize ") == 0) { ATH_MSG_VERBOSE(" perform spectrometer error optimization after cleaning "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*refittedTrack); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(refittedTrackUnique.get()); if (optimizedTrack) { - if (checkTrack("standaloneRefitOpt", optimizedTrack, refittedTrack)) { - delete refittedTrack; - refittedTrack = optimizedTrack; - countAEOTs(refittedTrack, " standaloneRefit alignment errors Track "); - } else { - delete optimizedTrack; - } + if (checkTrack("standaloneRefitOpt", optimizedTrack.get(), refittedTrackUnique.get())) { + refittedTrackUnique.swap(optimizedTrack); + countAEOTs(refittedTrackUnique.get(), " standaloneRefit alignment errors Track "); + } } } } delete vertex; - return refittedTrack; + //have to release it until the whole tool is migrated to unique_ptr + return refittedTrackUnique.release(); } /** refit a track */ @@ -2381,42 +2380,42 @@ CombinedMuonTrackBuilder::fit(Trk::Track& track, const Trk::RunOutlierRemoval ru return nullptr; } + //eventually this whole tool will use unique_ptrs + //in the meantime, this allows the MuonErrorOptimisationTool and MuonRefitTool to use them + std::unique_ptr<Trk::Track> fittedTrackUnique(fittedTrack); // track cleaning if (runOutlier) { - // fit with optimized spectrometer errors + // fit with optimized spectrometer errors - if (!m_muonErrorOptimizer.empty() && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack) - && optimizeErrors(fittedTrack)) + if (!m_muonErrorOptimizer.empty() && !fittedTrackUnique->info().trackProperties(Trk::TrackInfo::StraightTrack) + && optimizeErrors(fittedTrackUnique.get())) { ATH_MSG_VERBOSE(" perform spectrometer error optimization after cleaning "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*fittedTrack); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(fittedTrackUnique.get()); if (optimizedTrack) { - if (checkTrack("fitInterface1Opt", optimizedTrack, fittedTrack)) { - delete fittedTrack; - fittedTrack = optimizedTrack; - countAEOTs(fittedTrack, " re fit scaled errors Track "); - } else { - delete optimizedTrack; - } + if (checkTrack("fitInterface1Opt", optimizedTrack.get(), fittedTrackUnique.get())) { + fittedTrackUnique.swap(optimizedTrack); + countAEOTs(fittedTrackUnique.get(), " re fit scaled errors Track "); + } } } // chi2 before clean - double chi2Before = normalizedChi2(*fittedTrack); + double chi2Before = normalizedChi2(*fittedTrackUnique); // muon cleaner - ATH_MSG_VERBOSE(" perform track cleaning... " << m_printer->print(*fittedTrack) << std::endl - << m_printer->printStations(*fittedTrack)); + ATH_MSG_VERBOSE(" perform track cleaning... " << m_printer->print(*fittedTrackUnique) << std::endl + << m_printer->printStations(*fittedTrackUnique)); - if (fittedTrack) countAEOTs(fittedTrack, " refit: fitted track before cleaning "); + if (fittedTrackUnique) countAEOTs(fittedTrackUnique.get(), " refit: fitted track before cleaning "); - std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrack); + std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrackUnique); if (cleanTrack) countAEOTs(cleanTrack.get(), " refit: after cleaning"); - if (cleanTrack && !checkTrack("fitInterface1Cleaner", cleanTrack.get(), fittedTrack)) { + if (cleanTrack && !checkTrack("fitInterface1Cleaner", cleanTrack.get(), fittedTrackUnique.get())) { cleanTrack.reset(); } @@ -2424,32 +2423,30 @@ CombinedMuonTrackBuilder::fit(Trk::Track& track, const Trk::RunOutlierRemoval ru if (m_allowCleanerVeto && chi2Before > m_badFitChi2) { ATH_MSG_DEBUG(" cleaner veto A "); ++m_countStandaloneCleanerVeto; - delete fittedTrack; - fittedTrack = nullptr; + fittedTrackUnique.reset(); } else { ATH_MSG_DEBUG(" keep original standalone track despite cleaner veto "); } - } else if (!(*cleanTrack->perigeeParameters() == *fittedTrack->perigeeParameters())) { + } else if (!(*cleanTrack->perigeeParameters() == *fittedTrackUnique->perigeeParameters())) { double chi2After = normalizedChi2(*cleanTrack); if (chi2After < m_badFitChi2 || chi2After < chi2Before) { ATH_MSG_VERBOSE(" found and removed spectrometer outlier(s) "); - delete fittedTrack; - // using release until the entire code can be migrated to use smart pointers - fittedTrack = cleanTrack.release(); + fittedTrackUnique.swap(cleanTrack); } else { ATH_MSG_VERBOSE(" keep original track despite cleaning "); } } // FIXME: provide indet cleaner - if (fittedTrack) { - ATH_MSG_VERBOSE(" finished track cleaning... " << m_printer->print(*fittedTrack) << std::endl - << m_printer->printStations(*fittedTrack)); + if (fittedTrackUnique) { + ATH_MSG_VERBOSE(" finished track cleaning... " << m_printer->print(*fittedTrackUnique) << std::endl + << m_printer->printStations(*fittedTrackUnique)); } } - return fittedTrack; + //have to use release until the whole tool uses unique_ptr + return fittedTrackUnique.release(); } /** @@ -2519,40 +2516,40 @@ CombinedMuonTrackBuilder::fit(const Trk::MeasurementSet& measurementSet, const T return nullptr; } + //eventually this whole tool will use unique_ptrs + //in the meantime, this allows the MuonErrorOptimisationTool and MuonRefitTool to use them + std::unique_ptr<Trk::Track> fittedTrackUnique(fittedTrack); // track cleaning if (runOutlier) { // fit with optimized spectrometer errors - if (!m_muonErrorOptimizer.empty() && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack) - && optimizeErrors(fittedTrack)) + if (!m_muonErrorOptimizer.empty() && !fittedTrackUnique->info().trackProperties(Trk::TrackInfo::StraightTrack) + && optimizeErrors(fittedTrackUnique.get())) { ATH_MSG_VERBOSE(" perform spectrometer error optimization after cleaning "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*fittedTrack); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(fittedTrackUnique.get()); if (optimizedTrack) { - if (checkTrack("fitInterface2Opt", optimizedTrack, fittedTrack)) { - delete fittedTrack; - fittedTrack = optimizedTrack; - countAEOTs(fittedTrack, " fit mstSet scaled errors Track "); - } else { - delete optimizedTrack; - } + if (checkTrack("fitInterface2Opt", optimizedTrack.get(), fittedTrackUnique.get())) { + fittedTrackUnique.swap(optimizedTrack); + countAEOTs(fittedTrackUnique.get(), " fit mstSet scaled errors Track "); + } } } // chi2 before clean - double chi2Before = normalizedChi2(*fittedTrack); + double chi2Before = normalizedChi2(*fittedTrackUnique); // muon cleaner ATH_MSG_VERBOSE(" perform track cleaning... "); - if (fittedTrack) countAEOTs(fittedTrack, " fit mstSet before cleaning "); + if (fittedTrackUnique) countAEOTs(fittedTrackUnique.get(), " fit mstSet before cleaning "); - std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrack); + std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrackUnique); if (cleanTrack) countAEOTs(cleanTrack.get(), " fit mstSet clean Track "); - if (cleanTrack && !checkTrack("fitInterface2Cleaner", cleanTrack.get(), fittedTrack)) { + if (cleanTrack && !checkTrack("fitInterface2Cleaner", cleanTrack.get(), fittedTrackUnique.get())) { cleanTrack.reset(); } @@ -2560,19 +2557,15 @@ CombinedMuonTrackBuilder::fit(const Trk::MeasurementSet& measurementSet, const T if (m_allowCleanerVeto && chi2Before > m_badFitChi2) { ATH_MSG_DEBUG(" cleaner veto B"); ++m_countExtensionCleanerVeto; - delete fittedTrack; - fittedTrack = nullptr; + fittedTrackUnique.reset(); } else { ATH_MSG_DEBUG(" keep original extension track despite cleaner veto "); } - } else if (!(*cleanTrack->perigeeParameters() == *fittedTrack->perigeeParameters())) { + } else if (!(*cleanTrack->perigeeParameters() == *fittedTrackUnique->perigeeParameters())) { double chi2After = normalizedChi2(*cleanTrack); if (chi2After < m_badFitChi2 || chi2After < chi2Before) { ATH_MSG_VERBOSE(" found and removed spectrometer outlier(s) "); - - delete fittedTrack; - // using release until the entire code can be migrated to use smart pointers - fittedTrack = cleanTrack.release(); + fittedTrackUnique.swap(cleanTrack); } else { ATH_MSG_VERBOSE(" keep original track despite cleaning "); } @@ -2581,8 +2574,8 @@ CombinedMuonTrackBuilder::fit(const Trk::MeasurementSet& measurementSet, const T // FIXME: provide indet cleaner ATH_MSG_VERBOSE(" finished cleaning"); } - - return fittedTrack; + //have to use release until the whole code uses unique_ptr + return fittedTrackUnique.release(); } @@ -2644,34 +2637,37 @@ CombinedMuonTrackBuilder::fit(const Trk::Track& indetTrack, Trk::Track& extrapol if (!fittedTrack) return nullptr; + //eventually this whole tool will use unique_ptrs + //in the meantime, this allows the MuonErrorOptimisationTool and MuonRefitTool to use them + std::unique_ptr<Trk::Track> fittedTrackUnique(fittedTrack); + // track cleaning if (runOutlier) { // fit with optimized spectrometer errors if (!m_muonErrorOptimizer.empty() && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack) - && optimizeErrors(fittedTrack)) + && optimizeErrors(fittedTrackUnique.get())) { ATH_MSG_VERBOSE(" perform spectrometer error optimization after cleaning "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*fittedTrack); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(fittedTrackUnique.get()); if (optimizedTrack) { - delete fittedTrack; - fittedTrack = optimizedTrack; - countAEOTs(fittedTrack, " cbfit scaled errors Track "); + fittedTrackUnique.swap(optimizedTrack); + countAEOTs(fittedTrackUnique.get(), " cbfit scaled errors Track "); } } // chi2 before clean - double chi2Before = normalizedChi2(*fittedTrack); + double chi2Before = normalizedChi2(*fittedTrackUnique.get()); // muon cleaner - ATH_MSG_VERBOSE(" perform track cleaning... " << m_printer->print(*fittedTrack) << std::endl - << m_printer->printStations(*fittedTrack)); + ATH_MSG_VERBOSE(" perform track cleaning... " << m_printer->print(*fittedTrackUnique) << std::endl + << m_printer->printStations(*fittedTrackUnique)); - if (fittedTrack) { - countAEOTs(fittedTrack, " cb before clean Track "); + if (fittedTrackUnique) { + countAEOTs(fittedTrackUnique.get(), " cb before clean Track "); } - std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrack); + std::unique_ptr<Trk::Track> cleanTrack = m_cleaner->clean(*fittedTrackUnique); if (cleanTrack) { countAEOTs(cleanTrack.get(), " cb after clean Track "); } @@ -2680,19 +2676,15 @@ CombinedMuonTrackBuilder::fit(const Trk::Track& indetTrack, Trk::Track& extrapol if (m_allowCleanerVeto && chi2Before > m_badFitChi2) { ATH_MSG_DEBUG(" cleaner veto C"); ++m_countCombinedCleanerVeto; - delete fittedTrack; - fittedTrack = nullptr; + fittedTrackUnique.reset(); } else { ATH_MSG_DEBUG(" keep original combined track despite cleaner veto "); } - } else if (!(*cleanTrack->perigeeParameters() == *fittedTrack->perigeeParameters())) { + } else if (!(*cleanTrack->perigeeParameters() == *fittedTrackUnique->perigeeParameters())) { double chi2After = normalizedChi2(*cleanTrack); if (chi2After < m_badFitChi2 || chi2After < chi2Before) { ATH_MSG_VERBOSE(" found and removed spectrometer outlier(s) "); - - delete fittedTrack; - // using release until the entire code can be migrated to use smart pointers - fittedTrack = cleanTrack.release(); + fittedTrackUnique.swap(cleanTrack); } else { ATH_MSG_VERBOSE(" keep original track despite cleaning "); } @@ -2701,8 +2693,8 @@ CombinedMuonTrackBuilder::fit(const Trk::Track& indetTrack, Trk::Track& extrapol // FIXME: provide indet cleaner ATH_MSG_VERBOSE(" finished cleaning"); } - - return fittedTrack; + //have to use release until the whole code uses unique_ptr + return fittedTrackUnique.release(); } /* private methods follow */ @@ -4285,21 +4277,25 @@ CombinedMuonTrackBuilder::finalTrackBuild(Trk::Track*& track) const ATH_MSG_VERBOSE(" finished hole recovery procedure "); } + //eventually this whole tool will use unique_ptrs + //in the meantime, this allows the MuonErrorOptimisationTool and MuonRefitTool to use them + std::unique_ptr<Trk::Track> trackUnique(track); // final fit with optimized spectrometer errors - if (!m_muonErrorOptimizer.empty() && !track->info().trackProperties(Trk::TrackInfo::StraightTrack) - && countAEOTs(track, " before optimize ") == 0) + if (!m_muonErrorOptimizer.empty() && !trackUnique->info().trackProperties(Trk::TrackInfo::StraightTrack) + && countAEOTs(trackUnique.get(), " before optimize ") == 0) { ATH_MSG_VERBOSE(" perform spectrometer error optimization... "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*track); - if (optimizedTrack && checkTrack("finalTrackBuild2", optimizedTrack, track)) { - delete track; - track = optimizedTrack; - countAEOTs(track, " finalTrackBuilt alignment errors Track "); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(trackUnique.get()); + if (optimizedTrack && checkTrack("finalTrackBuild2", optimizedTrack.get(), trackUnique.get())) { + trackUnique.swap(optimizedTrack); + countAEOTs(track, " finalTrackBuilt alignment errors Track "); } } // add the track summary - m_trackSummary->updateTrack(*track); + m_trackSummary->updateTrack(*trackUnique); + //have to use release until the whole code uses unique_ptr + track=trackUnique.release(); } Trk::Track* diff --git a/Reconstruction/MuonIdentification/MuidTrackBuilder/src/OutwardsCombinedMuonTrackBuilder.cxx b/Reconstruction/MuonIdentification/MuidTrackBuilder/src/OutwardsCombinedMuonTrackBuilder.cxx index ee5260697a8..516bbe8ffe6 100755 --- a/Reconstruction/MuonIdentification/MuidTrackBuilder/src/OutwardsCombinedMuonTrackBuilder.cxx +++ b/Reconstruction/MuonIdentification/MuidTrackBuilder/src/OutwardsCombinedMuonTrackBuilder.cxx @@ -386,10 +386,11 @@ OutwardsCombinedMuonTrackBuilder::fit(Trk::Track& track, const Trk::RunOutlierRe if (!m_muonErrorOptimizer.empty() && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack)) { ATH_MSG_VERBOSE(" perform spectrometer error optimization before cleaning "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*fittedTrack); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(fittedTrack); if (optimizedTrack) { delete fittedTrack; - fittedTrack = optimizedTrack; + //until code is updated to use unique_ptr or removed + fittedTrack = optimizedTrack.release(); } } @@ -467,10 +468,11 @@ OutwardsCombinedMuonTrackBuilder::fit(const Trk::Track& indetTrack, const Trk::T // fit with optimized spectrometer errors if (!m_muonErrorOptimizer.empty() && !fittedTrack->info().trackProperties(Trk::TrackInfo::StraightTrack)) { ATH_MSG_VERBOSE(" perform spectrometer error optimization before cleaning "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*fittedTrack); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(fittedTrack); if (optimizedTrack) { delete fittedTrack; - fittedTrack = optimizedTrack; + //until code is updated to use unique_ptr or removed + fittedTrack = optimizedTrack.release(); } } // muon cleaner @@ -580,10 +582,11 @@ OutwardsCombinedMuonTrackBuilder::fit(const Trk::Track& indetTrack, const Trk::T ATH_MSG_VERBOSE(" perform spectrometer error optimization... "); - Trk::Track* optimizedTrack = m_muonErrorOptimizer->optimiseErrors(*fittedTrack); + std::unique_ptr<Trk::Track> optimizedTrack = m_muonErrorOptimizer->optimiseErrors(fittedTrack); if (optimizedTrack) { delete fittedTrack; - fittedTrack = optimizedTrack; + //until the code uses unique ptrs (or is removed since it's deprecated) + fittedTrack = optimizedTrack.release(); } } return fittedTrack; -- GitLab