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;
239 alpha =
Gamma * betha;
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;