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);