17 const IInterface*
parent) :
18 AthAlgTool(
type,
name,
parent), m_calorimeterVolume(nullptr), m_indetVolume(nullptr), m_inDetOnly(true), m_refitInDetOnly(true) {
19 declareInterface<IMuonScatteringAngleSignificance>(
this);
26 ATH_MSG_INFO(
"Initializing MuonScatAngleSignificanceTool");
30 if (
m_fitter.retrieve().isFailure()) {
41 return StatusCode::FAILURE;
48 return StatusCode::SUCCESS;
55 muon.trackParticle(xAOD::Muon::CombinedTrackParticle) ?
muon.trackParticle(xAOD::Muon::CombinedTrackParticle)->track() :
nullptr;
57 if (theTrack ==
nullptr) {
58 theTrack =
muon.trackParticle(xAOD::Muon::InnerDetectorTrackParticle)
59 ?
muon.trackParticle(xAOD::Muon::InnerDetectorTrackParticle)->track()
63 if (theTrack ==
nullptr) {
64 ATH_MSG_DEBUG(
"No track, returning empty scatterer-significance object.");
77 if (!
m_fitter.empty() &&
track.perigeeParameters() &&
track.measurementsOnTrack() &&
track.measurementsOnTrack()->size() > 3) {
80 std::vector<const Trk::MeasurementBase*>
vec;
82 for (; measIter !=
track.measurementsOnTrack()->
end(); ++measIter) {
83 const Amg::Vector3D& position = (*measIter)->globalPosition();
85 vec.push_back((*measIter));
87 ATH_MSG_DEBUG(
"Refitting ID-part of track, meast vector of size " <<
vec.size());
88 refittedTrack =
m_fitter->fit(Gaudi::Hive::currentContext(),
90 *(
track.perigeeParameters()),
97 fullTrack = refittedTrack;
99 ATH_MSG_DEBUG(
"Detected slimmed track, " << (refittedTrack ?
"refit was successful" :
"but could not refit it!"));
108 unsigned measurements = 0;
109 double neighbourRadius = 0.;
110 double neighbourSignificance = 0.;
111 unsigned neighbours = 0;
112 unsigned scatterers = 0;
113 unsigned startMeasurement = 0;
114 std::vector<bool> isMeasurement;
115 std::vector<unsigned> measurementNumber;
116 std::vector<double> radii;
117 std::vector<double> sigmas;
118 double significance = 0.;
119 double totalSigma = 0.;
120 double weightedRadius = 0.;
124 if ((**s).measurementOnTrack()) {
126 }
else if (!measurements)
130 if (!(**s).materialEffectsOnTrack())
continue;
140 if (!scattering)
continue;
143 double radius = (**s).trackParameters()->position().perp();
145 if ((**s).measurementOnTrack()) {
146 isMeasurement.push_back(
true);
148 isMeasurement.push_back(
false);
150 measurementNumber.push_back(measurements);
155 significance +=
sigma;
157 if (neighbours > 1 && measurements > startMeasurement) {
158 double norm = 1. / sqrt(
static_cast<double>(neighbours));
159 if (
norm * fabs(significance) > fabs(neighbourSignificance)) {
160 if (significance == 0.) {
163 neighbourRadius = weightedRadius / significance;
165 neighbourSignificance =
norm * significance;
166 ATH_MSG_VERBOSE(
" current maximum for neighbourSignificance " << neighbourSignificance <<
" from " << neighbours
167 <<
" scatterers at radius " << neighbourRadius);
169 ATH_MSG_VERBOSE(
" reset neighbour after " << significance <<
" /sqrt(" << neighbours <<
") at radius " <<
radius);
172 startMeasurement = measurements;
174 if (isMeasurement.back()) {
176 significance +=
sigma;
182 sigmas.push_back(
sigma);
185 ATH_MSG_VERBOSE(scatterers <<
" " << measurements <<
" " << isMeasurement.back() <<
" radius "
186 << (**s).trackParameters()->position().perp() <<
" deltaPhi " << scattering->
deltaPhi()
187 <<
" significance " <<
sigma <<
" integralSignificance " << totalSigma);
191 delete refittedTrack;
193 while (scatterers && measurementNumber.back() == measurements && !isMeasurement.back()) {
195 totalSigma -= sigmas.back();
196 isMeasurement.pop_back();
197 measurementNumber.pop_back();
211 double curvatureSignificance = totalSigma;
212 double curvatureRadius = *radii.rbegin();
213 unsigned index = scatterers - 1;
215 ATH_MSG_VERBOSE(
" scatteringAngleSignificance " << totalSigma <<
" at radius " << radii[
index] <<
" at scatterer " << scatterers
216 <<
" sigmas.size() " << sigmas.size());
218 for (std::vector<double>::const_reverse_iterator
r = sigmas.rbegin();
r != sigmas.rend(); ++
r, --
index) {
219 totalSigma -= 2. * (*r);
221 ATH_MSG_VERBOSE(
" scatteringAngleSignificance " << totalSigma <<
" at radius " << radii[
index - 1] <<
" at scatterer "
224 if (fabs(totalSigma) > fabs(curvatureSignificance) &&
index > 1) {
225 curvatureSignificance = totalSigma;
226 curvatureRadius = radii[
index - 1];
231 curvatureSignificance /= sqrt(
static_cast<double>(scatterers));
233 ATH_MSG_DEBUG(
" scatteringAngleSignificance" << std::setiosflags(std::ios::fixed) << std::setw(7) << std::setprecision(2)
234 << curvatureSignificance <<
" at radius " << std::setw(6) << std::setprecision(1)
235 << curvatureRadius <<
" neighbourSignificance " << std::setw(7) << std::setprecision(2)
236 << neighbourSignificance <<
" at radius " << std::setw(6) << std::setprecision(1)
237 << neighbourRadius <<
" from " << scatterers <<
" scatterers");
244 s !=
track.trackStateOnSurfaces()->end(); ++
s) {
245 if ((**s).trackParameters())
continue;
247 ATH_MSG_VERBOSE(
"track is slimmed (found TSOS without trackParameters) ");
251 ATH_MSG_VERBOSE(
"track is not slimmed (all TSOS have trackParameters) ");