diff --git a/Tracking/TrkVertexFitter/TrkVertexFitterInterfaces/TrkVertexFitterInterfaces/IVertexTrackDensityEstimator.h b/Tracking/TrkVertexFitter/TrkVertexFitterInterfaces/TrkVertexFitterInterfaces/IVertexTrackDensityEstimator.h index f6d60e480cb7da24a35b0ba2c80bc7d03f994884..f8b9487109a863b71c3b70e191e396a652ec64a2 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) const = 0; + virtual double trackDensity(double z) = 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) const = 0; + virtual void trackDensity(double z, double& density, double& firstDerivative, double& secondDerivative) = 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 43b555f3f12352d9fd11ce5d552463a64e868bfa..61f184bbf2b510851de9424eb483757eccee5b8e 100644 --- a/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/TrkVertexSeedFinderUtils/GaussianTrackDensity.h +++ b/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/TrkVertexSeedFinderUtils/GaussianTrackDensity.h @@ -8,12 +8,13 @@ #include "AthenaBaseComps/AthAlgTool.h" #include "TrkVertexFitterInterfaces/IVertexTrackDensityEstimator.h" -#include <unordered_map> +#include <map> namespace Trk { class Track; + class GaussianTrackDensity; /** @class GaussianTrackDensity @@ -64,57 +65,62 @@ namespace Trk /** * Evaluate the density function at the specified coordinate along the beam-line. */ - virtual double trackDensity(double z) const; + virtual double trackDensity(double z); /** * Evaluate the density and its first two derivatives at the specified coordinate. */ - virtual void trackDensity(double z, double& density, double& firstDerivative, double& secondDerivativec) const; + virtual void trackDensity(double z, double& density, double& firstDerivative, double& secondDerivativec); /** * 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 + struct pred_perigee { + bool operator()(const Trk::Perigee& left, const Trk::Perigee& right) const + { + return left.parameters()[Trk::z0] < right.parameters()[Trk::z0]; + } + }; - private: struct TrackEntry { - TrackEntry(double c0, double c1, double c2); + TrackEntry(double c0, double c1, double c2, double covz); // Cached information for a single track double constant; // z-independent factor 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 }; - // functor to hash key for unordered_map - struct hash_perigee { - size_t operator()(const Trk::Perigee& perigee) const - { - return - std::hash<double>()(perigee.parameters()[Trk::d0]) ^ - std::hash<double>()(perigee.parameters()[Trk::z0]) ^ - std::hash<double>()(perigee.parameters()[Trk::phi]) ^ - std::hash<double>()(perigee.parameters()[Trk::theta]) ^ - std::hash<double>()(perigee.parameters()[Trk::qOverP]); - } - }; + typedef std::map< Perigee, + GaussianTrackDensity::TrackEntry, + GaussianTrackDensity::pred_perigee > trackMap; + typedef std::map< Perigee, + GaussianTrackDensity::TrackEntry, + GaussianTrackDensity::pred_perigee >::const_iterator trackMapIterator; + + private: + + trackMapIterator findStart(double z); + + trackMapIterator findFinish(double z); - // functor to compare two unordered_map Key values for equality - struct pred_perigee { - bool operator()(const Trk::Perigee& left, const Trk::Perigee& right) const - { - return - (left.parameters()[Trk::d0] == right.parameters()[Trk::d0]) && - (left.parameters()[Trk::z0] == right.parameters()[Trk::z0]) && - (left.parameters()[Trk::phi] == right.parameters()[Trk::phi]) && - (left.parameters()[Trk::theta] == right.parameters()[Trk::theta]) && - (left.parameters()[Trk::qOverP] == right.parameters()[Trk::qOverP]); - } - }; // Cache for track information - std::unordered_map< Trk::Perigee, Trk::GaussianTrackDensity::TrackEntry, hash_perigee, pred_perigee> m_trackMap; + //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(); // Cuts set by configurable properties @@ -123,6 +129,10 @@ namespace Trk "MaxD0Significance", 3.5, "Maximum radial impact parameter significance to use track" }; + Gaudi::Property<double> m_z0MaxSignificance { this, + "MaxZ0Significance", + 5.0, + "Maximum longitudinal impact parameter significance to include track in weight"}; }; } diff --git a/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx b/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx index 8b626a27a0b45b40916442b930c461434d0ea95c..7a16f5827c541e77772f230e9a8a1a0fbce9a049 100644 --- a/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx +++ b/Tracking/TrkVertexFitter/TrkVertexSeedFinderUtils/src/GaussianTrackDensity.cxx @@ -13,7 +13,8 @@ namespace Trk { GaussianTrackDensity::GaussianTrackDensity(const std::string& t, const std::string& n, const IInterface* p): - AthAlgTool(t, n, p) + AthAlgTool(t, n, p), + m_dirty(false) { declareInterface<IVertexTrackDensityEstimator>(this); } @@ -28,30 +29,55 @@ namespace Trk return StatusCode::SUCCESS; } - double GaussianTrackDensity::trackDensity(double z) const + GaussianTrackDensity::trackMapIterator GaussianTrackDensity::findStart(double z) { - double sum = 0.0; - for (auto& entry : m_trackMap) + trackMapIterator result = m_trackMap.cbegin(); + while (result != m_trackMap.cend() && result->first.parameters()[Trk::z0] <= z) { - sum += entry.second.constant * exp(z*(entry.second.c_1 + z*entry.second.c_2)); + result++; } - return sum; + // 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) const + void GaussianTrackDensity::trackDensity(double z, double& density, double& firstDerivative, double& secondDerivative) { + if (m_dirty) prepareTracks(); density = 0.0; firstDerivative = 0.0; secondDerivative = 0.0; - for (auto& entry : m_trackMap) + for (auto it = findStart(z); it != findFinish(z); ++it) { - double delta = entry.second.constant * exp(z*(entry.second.c_1 + z*entry.second.c_2)); + double delta = it->second.constant * exp(z*(it->second.c_1 + z*it->second.c_2)); density += delta; - double qPrime = entry.second.c_1 + 2*z*entry.second.c_2; + double qPrime = it->second.c_1 + 2*z*it->second.c_2; double deltaPrime = delta * qPrime; firstDerivative += deltaPrime; - secondDerivative += 2*entry.second.c_2*delta + qPrime*deltaPrime; + secondDerivative += 2*it->second.c_2*delta + qPrime*deltaPrime; + } + } + + double GaussianTrackDensity::trackDensity(double z) + { + if (m_dirty) prepareTracks(); + double sum = 0.0; + for (auto it = findStart(z); it != findFinish(z); ++it) + { + sum += it->second.constant * exp(z*(it->second.c_1 + z*it->second.c_2)); } + return sum; } void GaussianTrackDensity::addTracks(const std::vector<const Trk::Track*>& vectorTrk) @@ -92,6 +118,7 @@ namespace Trk if ( cov_dd <= 0 ) continue; if ( d0*d0/cov_dd > significanceCut ) 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; @@ -101,7 +128,8 @@ namespace Trk double quadraticTerm = -cov_dd / (2*covDeterminant); m_trackMap.emplace(std::piecewise_construct, std::forward_as_tuple(*itrk), - std::forward_as_tuple(constantFactor, linearTerm, quadraticTerm)); + std::forward_as_tuple(constantFactor, linearTerm, quadraticTerm, cov_zz)); + m_dirty = true; } } } @@ -115,15 +143,43 @@ namespace Trk { if (m_trackMap.count(*itrk) == 0) continue; 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; } - GaussianTrackDensity::TrackEntry::TrackEntry(double c0, double c1, double c2) : constant(c0), c_1(c1), c_2(c2) { } + GaussianTrackDensity::TrackEntry::TrackEntry(double c0, double c1, double c2, double covz) + : constant(c0), c_1(c1), c_2(c2), cov_z(covz), start(), finish() +{ } }