diff --git a/Tracking/TrkVertexFitter/TrkVertexFitterInterfaces/TrkVertexFitterInterfaces/IVertexTrackDensityEstimator.h b/Tracking/TrkVertexFitter/TrkVertexFitterInterfaces/TrkVertexFitterInterfaces/IVertexTrackDensityEstimator.h index f8b9487109a863b71c3b70e191e396a652ec64a2..f6d60e480cb7da24a35b0ba2c80bc7d03f994884 100755 --- a/Tracking/TrkVertexFitter/TrkVertexFitterInterfaces/TrkVertexFitterInterfaces/IVertexTrackDensityEstimator.h +++ b/Tracking/TrkVertexFitter/TrkVertexFitterInterfaces/TrkVertexFitterInterfaces/IVertexTrackDensityEstimator.h @@ -70,12 +70,12 @@ namespace Trk /** * Evaluate the density function at the specified coordinate along the beam-line. */ - virtual double trackDensity(double z) = 0; + virtual double trackDensity(double z) const = 0; /* * Evaluate the density function and its first two derivatives at the specified coordinate. */ - virtual void trackDensity(double z, double& density, double& firstDerivative, double& secondDerivative) = 0; + virtual void trackDensity(double z, double& density, double& firstDerivative, double& secondDerivative) const = 0; /** * Resets the internal state of the tool, forgetting all tracks previously added. diff --git a/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/TrkVertexSeedFinderUtils/GaussianTrackDensity.h b/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/TrkVertexSeedFinderUtils/GaussianTrackDensity.h index 61f184bbf2b510851de9424eb483757eccee5b8e..f7b451e83d1a84cdcd3f14dfc86a50b792dadc5e 100644 --- a/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/TrkVertexSeedFinderUtils/GaussianTrackDensity.h +++ b/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/TrkVertexSeedFinderUtils/GaussianTrackDensity.h @@ -43,43 +43,43 @@ namespace Trk /** * Adds a list of tracks, whose impact parameters will contribute to the density function. */ - virtual void addTracks(const std::vector<const Trk::Track*>& vectorTrk); + virtual void addTracks(const std::vector<const Track*>& vectorTrk); /** * Adds a list of track perigee parameters, whose impact parameters will contribute to * the density function. */ - virtual void addTracks(const std::vector<const Trk::TrackParameters*>& perigeeList); + virtual void addTracks(const std::vector<const TrackParameters*>& perigeeList); /** * Removes a list of tracks, which will no longer contribute to the density function. */ - virtual void removeTracks(const std::vector<const Trk::Track*>& vectorTrk); + virtual void removeTracks(const std::vector<const Track*>& vectorTrk); /** * Removes a list of track perigee parameters, which will no longer contribute to * the density function. */ - virtual void removeTracks(const std::vector<const Trk::TrackParameters*>& perigeeList); + virtual void removeTracks(const std::vector<const TrackParameters*>& perigeeList); /** * Evaluate the density function at the specified coordinate along the beam-line. */ - virtual double trackDensity(double z); + virtual double trackDensity(double z) const; /** * Evaluate the density and its first two derivatives at the specified coordinate. */ - virtual void trackDensity(double z, double& density, double& firstDerivative, double& secondDerivativec); + virtual void trackDensity(double z, double& density, double& firstDerivative, double& secondDerivativec) const; /** * Resets the internal state of the tool, forgetting all tracks previously added. */ virtual void reset(); - // functor to compare two unordered_map Key values for equality + // functor to compare two Perigee values struct pred_perigee { - bool operator()(const Trk::Perigee& left, const Trk::Perigee& right) const + bool operator()(const Perigee& left, const Perigee& right) const { return left.parameters()[Trk::z0] < right.parameters()[Trk::z0]; } @@ -87,40 +87,63 @@ namespace Trk struct TrackEntry { - TrackEntry(double c0, double c1, double c2, double covz); + TrackEntry() { c_0 = 0; c_1 = 0; c_2 = 0; lowerBound = 0; upperBound = 0; } + TrackEntry(double c0, double c1, double c2, double zMin, double zMax); + TrackEntry(double zProbe); // Cached information for a single track - double constant; // z-independent factor + double c_0; // z-independent term in exponent double c_1; // linear coefficient in exponent double c_2; // quadratic coefficient in exponent - double cov_z; // z0 variance from track error matrix - std::map< Perigee, TrackEntry, pred_perigee >::const_iterator start; - // will point to the left-most TrackEntry close enough to affect the weight at this one - std::map< Perigee, TrackEntry, pred_perigee >::const_iterator finish; - // will point to the right-most TrackEntry close enough to affect the weight at this one + double lowerBound; + double upperBound; + }; + + // functor to compare two TrackEntry values based on their lower limits (low to high) + struct pred_entry_by_min { + bool operator()(const TrackEntry& left, const TrackEntry& right) const + { + return left.lowerBound < right.lowerBound; + } + }; + + // functor to compare two TrackEntry values based on their upper limits (low to high) + struct pred_entry_by_max { + bool operator()(const TrackEntry& left, const TrackEntry& right) const + { + return left.upperBound < right.upperBound; + } }; typedef std::map< Perigee, GaussianTrackDensity::TrackEntry, GaussianTrackDensity::pred_perigee > trackMap; + typedef std::map< Perigee, GaussianTrackDensity::TrackEntry, GaussianTrackDensity::pred_perigee >::const_iterator trackMapIterator; - private: + typedef std::map< GaussianTrackDensity::TrackEntry, + Perigee, + GaussianTrackDensity::pred_entry_by_max > lowerMap; - trackMapIterator findStart(double z); + typedef std::map< GaussianTrackDensity::TrackEntry, + Perigee, + GaussianTrackDensity::pred_entry_by_max >::const_iterator lowerMapIterator; - trackMapIterator findFinish(double z); + typedef std::map< GaussianTrackDensity::TrackEntry, + Perigee, + GaussianTrackDensity::pred_entry_by_min > upperMap; + typedef std::map< GaussianTrackDensity::TrackEntry, + Perigee, + GaussianTrackDensity::pred_entry_by_min >::const_iterator upperMapIterator; + + private: // Cache for track information - //std::unordered_map< Trk::Perigee, Trk::GaussianTrackDensity::TrackEntry, hash_perigee, pred_perigee> m_trackMap; trackMap m_trackMap; - - // Indicates whether track data needs to be refreshed before evaluation - bool m_dirty; - - void prepareTracks(); + lowerMap m_lowerMap; + upperMap m_upperMap; // Cuts set by configurable properties diff --git a/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx b/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx index 7a16f5827c541e77772f230e9a8a1a0fbce9a049..4927333a742a17d4b4bca11c8107262eb2def78b 100644 --- a/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx +++ b/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx @@ -13,8 +13,7 @@ namespace Trk { GaussianTrackDensity::GaussianTrackDensity(const std::string& t, const std::string& n, const IInterface* p): - AthAlgTool(t, n, p), - m_dirty(false) + AthAlgTool(t, n, p) { declareInterface<IVertexTrackDensityEstimator>(this); } @@ -29,58 +28,43 @@ namespace Trk return StatusCode::SUCCESS; } - GaussianTrackDensity::trackMapIterator GaussianTrackDensity::findStart(double z) + void GaussianTrackDensity::trackDensity(double z, double& density, double& firstDerivative, double& secondDerivative) const { - trackMapIterator result = m_trackMap.cbegin(); - while (result != m_trackMap.cend() && result->first.parameters()[Trk::z0] <= z) - { - result++; - } - // always goes one past the track immediately to left of z - return (--result)->second.start; - } - - GaussianTrackDensity::trackMapIterator GaussianTrackDensity::findFinish(double z) - { - trackMapIterator result = m_trackMap.cend(); - result--; - while (result != m_trackMap.cbegin() && result->first.parameters()[Trk::z0] > z) - { - result--; - } - if (result->first.parameters()[Trk::z0] < z) result++; - return result->second.finish; - } - - void GaussianTrackDensity::trackDensity(double z, double& density, double& firstDerivative, double& secondDerivative) - { - if (m_dirty) prepareTracks(); + TrackEntry target(z); + lowerMapIterator first = m_lowerMap.lower_bound(target); + upperMapIterator final = m_upperMap.upper_bound(target); + trackMapIterator firstLoop = m_trackMap.find(first->second); + trackMapIterator finalLoop = m_trackMap.find(final->second); density = 0.0; firstDerivative = 0.0; secondDerivative = 0.0; - for (auto it = findStart(z); it != findFinish(z); ++it) + for (auto itrk = firstLoop; itrk != finalLoop && itrk != m_trackMap.end(); itrk++) { - double delta = it->second.constant * exp(z*(it->second.c_1 + z*it->second.c_2)); + double delta = exp(itrk->second.c_0+z*(itrk->second.c_1 + z*itrk->second.c_2)); density += delta; - double qPrime = it->second.c_1 + 2*z*it->second.c_2; + double qPrime = itrk->second.c_1 + 2*z*itrk->second.c_2; double deltaPrime = delta * qPrime; firstDerivative += deltaPrime; - secondDerivative += 2*it->second.c_2*delta + qPrime*deltaPrime; + secondDerivative += 2*itrk->second.c_2*delta + qPrime*deltaPrime; } } - double GaussianTrackDensity::trackDensity(double z) + double GaussianTrackDensity::trackDensity(double z) const { - if (m_dirty) prepareTracks(); + TrackEntry target(z); + lowerMapIterator first = m_lowerMap.lower_bound(target); + upperMapIterator final = m_upperMap.upper_bound(target); + trackMapIterator firstLoop = m_trackMap.find(first->second); + trackMapIterator finalLoop = m_trackMap.find(final->second); double sum = 0.0; - for (auto it = findStart(z); it != findFinish(z); ++it) + for (auto itrk = firstLoop; itrk != finalLoop && itrk != m_trackMap.end(); itrk++) { - sum += it->second.constant * exp(z*(it->second.c_1 + z*it->second.c_2)); + sum += exp(itrk->second.c_0+z*(itrk->second.c_1 + itrk->second.c_2)); } return sum; } - void GaussianTrackDensity::addTracks(const std::vector<const Trk::Track*>& vectorTrk) + void GaussianTrackDensity::addTracks(const std::vector<const Track*>& vectorTrk) { std::vector<const TrackParameters*> perigeeList; for (auto itrk : vectorTrk) @@ -91,7 +75,7 @@ namespace Trk addTracks(perigeeList); } - void GaussianTrackDensity::removeTracks(const std::vector<const Trk::Track*>& vectorTrk) + void GaussianTrackDensity::removeTracks(const std::vector<const Track*>& vectorTrk) { std::vector<const TrackParameters*> perigeeList; for (auto itrk : vectorTrk) @@ -104,7 +88,8 @@ namespace Trk void GaussianTrackDensity::addTracks(const std::vector<const TrackParameters*>& perigeeList) { - double significanceCut = m_d0MaxSignificance * m_d0MaxSignificance; + double d0SignificanceCut = m_d0MaxSignificance * m_d0MaxSignificance; + double z0SignificanceCut = m_z0MaxSignificance * m_z0MaxSignificance; for (auto iparam : perigeeList) { const Perigee* itrk = dynamic_cast<const Perigee*>(iparam); @@ -116,20 +101,30 @@ namespace Trk const AmgSymMatrix(5) & perigeeCov = *(itrk->covariance()); double cov_dd = perigeeCov(Trk::d0, Trk::d0); if ( cov_dd <= 0 ) continue; - if ( d0*d0/cov_dd > significanceCut ) continue; + if ( d0*d0/cov_dd > d0SignificanceCut ) continue; double cov_zz = perigeeCov(Trk::z0, Trk::z0); if (cov_zz <= 0 ) continue; double cov_dz = perigeeCov(Trk::d0, Trk::z0); double covDeterminant = cov_dd*cov_zz - cov_dz*cov_dz; if ( covDeterminant <= 0 ) continue; - double constantArg = (d0*d0*cov_zz + z0*z0*cov_dd + 2*d0*z0*cov_dz) / (2*covDeterminant); - double constantFactor = exp(-constantArg) / (2*Gaudi::Units::pi*covDeterminant); + double constantTerm = -(d0*d0*cov_zz + z0*z0*cov_dd + 2*d0*z0*cov_dz) / (2*covDeterminant); double linearTerm = (d0*cov_dz + z0*cov_dd) / covDeterminant ; // minus signs and factors of 2 cancel... double quadraticTerm = -cov_dd / (2*covDeterminant); + double discriminant = linearTerm*linearTerm - 4*quadraticTerm*(constantTerm + 2*z0SignificanceCut*cov_zz); + if (discriminant < 0) continue; + discriminant = sqrt(discriminant); + double zMin = (-linearTerm - discriminant)/(2*quadraticTerm); + double zMax = (-linearTerm + discriminant)/(2*quadraticTerm); + constantTerm -= log(2*Gaudi::Units::pi*covDeterminant); m_trackMap.emplace(std::piecewise_construct, std::forward_as_tuple(*itrk), - std::forward_as_tuple(constantFactor, linearTerm, quadraticTerm, cov_zz)); - m_dirty = true; + std::forward_as_tuple(constantTerm, linearTerm, quadraticTerm, zMin, zMax)); + m_lowerMap.emplace(std::piecewise_construct, + std::forward_as_tuple(constantTerm, linearTerm, quadraticTerm, zMin, zMax), + std::forward_as_tuple(*itrk)); + m_upperMap.emplace(std::piecewise_construct, + std::forward_as_tuple(constantTerm, linearTerm, quadraticTerm, zMin, zMax), + std::forward_as_tuple(*itrk)); } } } @@ -142,44 +137,28 @@ namespace Trk if (itrk != nullptr) { if (m_trackMap.count(*itrk) == 0) continue; + const auto& entry = m_trackMap[*itrk]; + if (m_lowerMap.count(entry) > 0) m_lowerMap.erase(entry); + if (m_upperMap.count(entry) > 0) m_upperMap.erase(entry); m_trackMap.erase(*itrk); - m_dirty = true; } } } - void GaussianTrackDensity::prepareTracks() - { - trackMapIterator left = m_trackMap.cbegin(); - double z0Cut = m_z0MaxSignificance * m_z0MaxSignificance; - for (auto& entry : m_trackMap) - { - double myZ0 = entry.first.parameters()[Trk::z0]; - // left should advance to the left-most track to the left of "entry" that is within n sigma of it, - // or no track to the left of "entry" passes, it should stop at "entry" itself - while (pow(myZ0 - left->first.parameters()[Trk::z0],2) > z0Cut*left->second.cov_z && - left->first.parameters()[Trk::z0] < myZ0) - left++; - // right should advance to the element after the right-most element within n-sigma of "entry" - trackMapIterator right = m_trackMap.cend(); - while((--right)->first.parameters()[Trk::z0] > myZ0) - { - if (pow(myZ0 - right->first.parameters()[Trk::z0],2) < z0Cut*right->second.cov_z) break; - } - entry.second.start = left; - entry.second.finish = ++right; - } - m_dirty = false; - } - void GaussianTrackDensity::reset() { m_trackMap.clear(); - m_dirty = false; + m_lowerMap.clear(); + m_upperMap.clear(); } - GaussianTrackDensity::TrackEntry::TrackEntry(double c0, double c1, double c2, double covz) - : constant(c0), c_1(c1), c_2(c2), cov_z(covz), start(), finish() + GaussianTrackDensity::TrackEntry::TrackEntry(double c0, double c1, double c2, double zMin, double zMax) + : c_0(c0), c_1(c1), c_2(c2), lowerBound(zMin), upperBound(zMax) +{ } + + // Dummy constructor for binary search + GaussianTrackDensity::TrackEntry::TrackEntry(double z) + : c_0(0), c_1(0), c_2(0), lowerBound(z), upperBound(z) { } }