13 #include "CLHEP/GenericFunctions/CumulativeChiSquare.hh" 
   14 #include "CLHEP/Units/PhysicalConstants.h" 
   15 #include "CLHEP/Units/SystemOfUnits.h" 
   17 #include "GaudiKernel/MsgStream.h" 
   68                                        const double r_r2, 
const double r_sigma22, 
const int &r_case)
 const {
 
   79     double mx1 = 0, bx1 = 0, 
mx2 = 0, bx2 = 0;           
 
   85     if (r_case < 1 || r_case > 4) {
 
   86         throw std::runtime_error(
 
   87             Form(
"File: %s, Line: %d\nStraightPatRec::tangent - Illegal case %i, must be 1,2,3, or 4.!", __FILE__, __LINE__, r_case));
 
   95     e3prime = (r_w2 - r_w1).
unit();
 
   99     if (r_case == 1 || r_case == 2) {
 
  100         sinalpha = std::abs(r_r2 - r_r1) / (r_w2 - r_w1).
mag();
 
  101         cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
 
  105             p1 = r_w1 + ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r1 * (cosalpha * e2prime - sinalpha * e3prime);
 
  106             p2 = r_w2 + ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r2 * (cosalpha * e2prime - sinalpha * e3prime);
 
  111             p1 = r_w1 - ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r1 * (cosalpha * e2prime + sinalpha * e3prime);
 
  112             p2 = r_w2 - ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r2 * (cosalpha * e2prime + sinalpha * e3prime);
 
  117     if (r_case == 3 || r_case == 4) {
 
  118         sinalpha = (r_r1 + r_r2) / (r_w2 - r_w1).mag();
 
  119         cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
 
  123             p1 = r_w1 + r_r1 * (cosalpha * e2prime + sinalpha * e3prime);
 
  124             p2 = r_w2 - r_r2 * (cosalpha * e2prime + sinalpha * e3prime);
 
  129             p1 = r_w1 - r_r1 * (cosalpha * e2prime - sinalpha * e3prime);
 
  130             p2 = r_w2 + r_r2 * (cosalpha * e2prime - sinalpha * e3prime);
 
  135     if ((
p2 - 
p1).z() != 0.0) {
 
  139         direction[2] = (1.0e-99);
 
  146     tang = 
MTStraightLine(mx1, bx1, 
mx2, bx2, 1.0, 1.0, std::sqrt(r_sigma12 + r_sigma22) / std::abs(
p2.z() - 
p1.z()),
 
  147                           std::sqrt(r_sigma12 + 
p1.z() * 
p1.z() * (r_sigma12 + r_sigma22) / 
std::pow(
p2.z() - 
p1.z(), 2)));
 
  162     unsigned int num_selected_hits(0);
 
  163     for (
unsigned int k : r_selection) {
 
  164         if (!
k) { num_selected_hits++; }
 
  166     if (num_selected_hits < 3) 
return cand_line;
 
  184     unsigned int NLC = 2;  
 
  194     refDir = refDir.unit();
 
  198     double rotAngle = 
Amg::angle(Amg::Vector3D::UnitZ(), refDir) * (refDir.y()) / std::abs(refDir.y());
 
  209     std::vector<Amg::Vector3D> hit_position_track;
 
  215         WirPosTrack = RotMatr * WirPosTrack;
 
  216         double signedDrifRadius =
 
  217             std::abs(r_segment.
mdtHOT()[
l]->driftRadius()) *
 
  218             (r_segment.
mdtHOT()[
l]->signedDistanceToTrack() / std::abs(r_segment.
mdtHOT()[
l]->signedDistanceToTrack()));
 
  220         HitPosTrack[0] = HitPosTrack.y() + signedDrifRadius;
 
  221         HitPosTrack[1] = r_segment.
mdtHOT()[
l]->sigma2DriftRadius();  
 
  223         hit_position_track.push_back(HitPosTrack);
 
  228         delta[1] = HitPosTrack.z();
 
  230         if (!r_selection[
l]) {
 
  231             double weight = 1.0 / (r_segment.
mdtHOT()[
l]->sigma2DriftRadius());
 
  233             betha += 
weight * HitPosTrack.y() * delta;
 
  241     double refit_chi2(0.0);
 
  242     for (
unsigned int j = 0; j < hit_position_track.size(); j++) {
 
  243         double res = (
alpha[0] + 
alpha[1] * hit_position_track[j].z() - hit_position_track[j].y());
 
  244         if (!r_selection[j]) refit_chi2 += 
res * 
res / hit_position_track[j].x();
 
  249     seg_dir = RotMatr_inv * seg_dir;
 
  250     seg_dir[1] = seg_dir.y() / seg_dir.z();
 
  251     seg_dir[0] = init_dir.x() / init_dir.z();
 
  255     seg_pos = RotMatr_inv * seg_pos;
 
  256     seg_pos = seg_pos + refTransl;
 
  258     seg_pos[1] = seg_pos.y() + seg_dir.y() * (init_pos.z() - seg_pos.z());
 
  259     seg_pos[0] = init_pos.x();
 
  260     seg_pos[2] = init_pos.z();
 
  263     r_segment.
set(refit_chi2 / (num_selected_hits - 2), seg_pos, seg_dir);
 
  314     std::vector<unsigned int> hit_index;  
 
  315     unsigned int try_nb_hits;             
 
  319     std::vector<unsigned int> selected_hits_index;
 
  323     double r_min, r_max{};          
 
  324     double sigma2_min, sigma2_max;  
 
  326     unsigned int counter1;  
 
  328     unsigned int nb_candidates(0);  
 
  347             << 
"fitCallByReference() - Vector with selected hits unequal to the number of hits on the segment! The user selection will " 
  357         if (!r_selection[
k]) {
 
  358             selected_hits.push_back(r_segment.
mdtHOT()[
k]);
 
  359             selected_hits_index.push_back(
k);
 
  368     if (selected_hits.size() < 3) { 
return false; }
 
  386     try_nb_hits = selected_hits.size();
 
  388     while (nb_candidates == 0) {
 
  391         if (try_nb_hits < 5 && (selected_hits.size() - try_nb_hits) > 2) 
return false;
 
  393         double best_chi2ndf = -1.0;
 
  417             tmp_selection.assign(tmp_selection.size(), 1);
 
  418             for (
unsigned int k = 0; 
k < try_nb_hits; 
k++) { tmp_selection[selected_hits_index[hit_index[
k] - 1]] = 0; }
 
  422             w_min = selected_hits[hit_index[0] - 1]->localPosition();
 
  423             w_max = selected_hits[hit_index[0] - 1]->localPosition();
 
  424             r_min = selected_hits[hit_index[0] - 1]->driftRadius();
 
  425             r_max = selected_hits[hit_index[0] - 1]->driftRadius();
 
  426             sigma2_min = selected_hits[hit_index[0] - 1]->sigma2DriftRadius();
 
  427             sigma2_max = selected_hits[hit_index[0] - 1]->sigma2DriftRadius();
 
  428             for (
unsigned int k = 1; 
k < try_nb_hits; 
k++) {
 
  429                 if (selected_hits[hit_index[
k] - 1]->localPosition().
z() < w_min.z()) {
 
  430                     w_min = selected_hits[hit_index[
k] - 1]->localPosition();
 
  431                     r_min = selected_hits[hit_index[
k] - 1]->driftRadius();
 
  432                     sigma2_min = selected_hits[hit_index[
k] - 1]->sigma2DriftRadius();
 
  434                 if (selected_hits[hit_index[
k] - 1]->localPosition().
z() > w_max.z()) {
 
  435                     w_max = selected_hits[hit_index[
k] - 1]->localPosition();
 
  436                     r_max = selected_hits[hit_index[
k] - 1]->driftRadius();
 
  437                     sigma2_max = selected_hits[hit_index[
k] - 1]->sigma2DriftRadius();
 
  442             if (sigma2_min == 0) { sigma2_min = 0.1; }
 
  443             if (sigma2_max == 0) { sigma2_max = 0.1; }
 
  446             for (
unsigned int r_case = 1; r_case < 5; r_case++) {
 
  447                 tangents[r_case - 1] = 
tangent(w_min, r_min, sigma2_min, w_max, r_max, sigma2_max, r_case);
 
  452             for (
unsigned int r_case = 1; r_case < 5; r_case++) {
 
  454                 for (
unsigned int n = 0; 
n < try_nb_hits; 
n++) {
 
  455                     MTStraightLine aux_line(selected_hits[hit_index[
n] - 1]->localPosition(), xhat, 
null, 
null);
 
  456                     if (std::abs(std::abs(tangents[r_case - 1].signDistFrom(aux_line)) - selected_hits[hit_index[
n] - 1]->
driftRadius()) <=
 
  458                         counter1 = counter1 + 1;
 
  465                 if (counter1 == try_nb_hits) {
 
  467                     aux_track = 
fitCandidate(r_segment, tmp_selection, tangents[r_case - 1]);
 
  469                     if ((best_chi2ndf == -1) || (best_chi2ndf > r_segment.
chi2())) {
 
  470                         best_chi2ndf = r_segment.
chi2();
 
  471                         best_aux_line = aux_track;
 
  472                         final_selection.assign(final_selection.size(), 1);
 
  473                         for (
unsigned int j = 0; j < try_nb_hits; j++) { final_selection[selected_hits_index[hit_index[j] - 1]] = 0; }
 
  486         if (nb_candidates > 0) {
 
  488             for (
unsigned int k = 0; 
k < r_selection.size(); 
k++) {
 
  489                 r_selection[
k] = final_selection[
k];
 
  490                 if (!final_selection[
k]) { used_hits.push_back(r_segment.
mdtHOT()[
k]); }
 
  494             fitted_track = 
fitCandidate(r_segment, final_selection, best_aux_line);
 
  500             try_nb_hits = try_nb_hits - 1;
 
  501             if (try_nb_hits < 3) { 
return false; }
 
  508     return fitted_track.
chi2() > 0;