14 #include "CLHEP/Matrix/Vector.h"
15 #include "GaudiKernel/MsgStream.h"
22 using namespace CLHEP;
25 AdaptiveResidualSmoothing::AdaptiveResidualSmoothing() {}
27 void AdaptiveResidualSmoothing::addResidual(
const double radius,
const double residual) {
29 CLHEP::HepVector point(2);
35 m_residual_point.push_back(residual_point);
39 bool AdaptiveResidualSmoothing::addResidualsFromSegment(
MuonCalibSegment &seg,
bool curved,
double road_width) {
44 CLHEP::HepVector point(2);
54 m_cfitter.setRoadWidth(road_width);
61 m_sfitter.setRoadWidth(road_width);
67 fitter->SetRefineSegmentFlag(
false);
77 if (!m_cfitter.fit(seg,
selection, curved_track))
return false;
80 if (!m_sfitter.fit(seg,
selection, straight_track))
return false;
86 for (
const auto & trackHit : trackHits) {
87 point[0] = trackHit->driftRadius();
88 point[1] = trackHit->driftRadius() - std::abs(trackHit->signedDistanceToTrack());
89 m_residual_point.emplace_back(point, 0);
102 std::vector<unsigned int> ref_coord(1);
108 if (m_residual_point.size() == 0) {
109 throw std::runtime_error(
110 Form(
"File: %s, Line: %d\nAdaptiveResidualSmoothing::performSmoothing - No residuals stored.", __FILE__, __LINE__));
113 if (m_residual_point.size() < nb_entries_per_bin) {
114 throw std::runtime_error(
115 Form(
"File: %s, Line: %d\nAdaptiveResidualSmoothing::performSmoothing - Not enough residuals stored.", __FILE__, __LINE__));
130 std::vector<double>
rad(bin_maker.
getBins().size());
131 std::vector<SamplePoint> corr(bin_maker.
getBins().size());
133 rad[
k] = (bin_maker.
getBins()[
k])->centreOfGravity()[0];
134 corr[
k].set_x1(
rad[
k]);
135 corr[
k].set_x2((bin_maker.
getBins()[
k])->centreOfGravity()[1]);
136 corr[
k].set_error(1.0);
138 std::sort(
rad.begin(),
rad.end());
140 std::vector<double> radi;
141 radi.push_back(
rad[0]);
143 for (
unsigned int k = 1;
k <
rad.size();
k++) {
145 radi.push_back(
rad[
k]);
152 fitter.fit_parameters(corr, 1, corr.size(), polygon);
155 std::vector<double> rt_params;
156 rt_params.push_back(rt_rel.
tLower());
157 rt_params.push_back(0.01 * (rt_rel.
tUpper() - rt_rel.
tLower()));
159 for (
double t = rt_rel.
tLower();
t <= rt_rel.
tUpper();
t =
t + rt_params[1]) {
161 for (
unsigned int l = 0;
l < radi.size();
l++) {
164 if (fix_t_min && (rt_rel.
radius(
t) < 0.5)) { delta_r = 0.0; }
165 if (fix_t_max && (rt_rel.
radius(
t) > 14.1)) { delta_r = 0.0; }
166 rt_params.push_back(rt_rel.
radius(
t) - delta_r);
183 unsigned int nb_bins;
184 unsigned int min_nb_entries_per_bin(20);
190 unsigned int bin_index;
202 nb_bins =
static_cast<unsigned int>(std::sqrt(m_residual_point.size() / 6.));
205 if (nb_bins == 0) { nb_bins = 1; }
206 min_nb_entries_per_bin = m_residual_point.size() / nb_bins;
212 if (m_residual_point.size() == 0) {
214 log << MSG::WARNING <<
"performSmoothing() - No residuals are stored. no correction applied to r(t)!" <<
endmsg;
217 step_size = r_max /
static_cast<double>(nb_bins);
224 std::vector<SamplePoint> corr(nb_bins);
225 std::vector<double> radii(nb_bins);
229 for (
auto &
k : m_residual_point) {
k.setReferenceComponent(1); }
230 sort(m_residual_point.begin(), m_residual_point.end());
233 std::vector<std::vector<const DataPoint *> > sample_points_per_r_bin(nb_bins);
236 for (
auto &
k : m_residual_point) {
237 if (std::abs(
k.dataVector()[0]) >= r_max) {
continue; }
238 bin_index =
static_cast<unsigned int>(std::abs(
k.dataVector()[0]) / step_size);
239 sample_points_per_r_bin[bin_index].push_back(&
k);
245 for (
unsigned int bin = 0;
bin < nb_bins;
bin++) {
250 unsigned int k_min(
static_cast<unsigned int>(0.01 * sample_points_per_r_bin[
bin].
size()));
251 unsigned int k_max(
static_cast<unsigned int>(0.99 * sample_points_per_r_bin[
bin].
size()));
256 for (
unsigned int k = k_min;
k < k_max;
k++) {
257 aux_rad = aux_rad + sample_points_per_r_bin[
bin][
k]->dataVector()[0];
258 aux_corr = aux_corr + sample_points_per_r_bin[
bin][
k]->dataVector()[1];
260 if (k_max - k_min < 0.25 * min_nb_entries_per_bin) {
261 radii[
bin] = (0.5 +
bin) * step_size;
264 radii[
bin] = aux_rad /
static_cast<double>(k_max - k_min);
265 corr[
bin] =
SamplePoint(radii[
bin], aux_corr /
static_cast<double>(k_max - k_min), 1.0);
272 fitter.fit_parameters(corr, 1, corr.size(), polygon);
275 std::vector<double> rt_params;
276 rt_params.push_back(rt_rel.
tLower());
277 rt_params.push_back(0.01 * (rt_rel.
tUpper() - rt_rel.
tLower()));
279 for (
double t = rt_rel.
tLower();
t <= rt_rel.
tUpper();
t =
t + rt_params[1]) {
281 for (
unsigned int l = 0;
l < radii.size();
l++) {
284 if (rt_rel.
radius(
t) > r_max) { delta_r = 0.0; }
285 if (fix_t_min && (rt_rel.
radius(
t) < 0.5)) { delta_r = 0.0; }
286 if (fix_t_max && (rt_rel.
radius(
t) > 14.1)) { delta_r = 0.0; }
287 rt_params.push_back(rt_rel.
radius(
t) - delta_r);
298 double AdaptiveResidualSmoothing::t_from_r(
const IRtRelation &rt_rel,
const double r) {
303 double precision(0.001);
304 double t_max(rt_rel.
tUpper());
305 double t_min(rt_rel.
tLower());
311 while (t_max - t_min > 0.1 && std::abs(rt_rel.
radius(0.5 * (t_min + t_max)) -
r) > precision) {
312 if (rt_rel.
radius(0.5 * (t_min + t_max)) >
r) {
313 t_max = 0.5 * (t_min + t_max);
315 t_min = 0.5 * (t_min + t_max);
319 return 0.5 * (t_min + t_max);