48 const Amg::Vector3D& r_w2,
const double r_r2,
const double r_sigma22,
49 const int& r_case)
const {
60 double mx1=0, bx1=0, mx2=0, bx2=0;
66 if (r_case < 1 || r_case > 4) {
67 throw std::runtime_error(
68 Form(
"File: %s, Line: %d\nQuasianalyticLineReconstruction::tangent() - Illegal case %i, must be 1,2,3, or 4.", __FILE__,
77 e3prime = (r_w2 - r_w1).
unit();
81 if (r_case == 1 || r_case == 2) {
82 sinalpha = std::abs(r_r2 - r_r1) / (r_w2 - r_w1).
mag();
83 cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
87 p1 = r_w1 + ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r1 * (cosalpha * e2prime - sinalpha * e3prime);
88 p2 = r_w2 + ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r2 * (cosalpha * e2prime - sinalpha * e3prime);
93 p1 = r_w1 - ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r1 * (cosalpha * e2prime + sinalpha * e3prime);
94 p2 = r_w2 - ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r2 * (cosalpha * e2prime + sinalpha * e3prime);
99 if (r_case == 3 || r_case == 4) {
100 sinalpha = (r_r1 + r_r2) / (r_w2 - r_w1).mag();
101 cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
105 p1 = r_w1 + r_r1 * (cosalpha * e2prime + sinalpha * e3prime);
106 p2 = r_w2 - r_r2 * (cosalpha * e2prime + sinalpha * e3prime);
111 p1 = r_w1 - r_r1 * (cosalpha * e2prime - sinalpha * e3prime);
112 p2 = r_w2 + r_r2 * (cosalpha * e2prime - sinalpha * e3prime);
117 if ((p2 - p1).
z() != 0.0) {
121 direction[2] = 1.0e-99;
128 tang =
MTStraightLine(mx1, bx1, mx2, bx2, 1.0, 1.0, std::sqrt(r_sigma12 + r_sigma22) / std::abs(p2.z() - p1.z()),
129 std::sqrt(r_sigma12 + p1.z() * p1.z() * (r_sigma12 + r_sigma22) / std::pow(p2.z() - p1.z(), 2)));
136 const int& r_cand_case,
const std::vector<Amg::Vector3D>& r_w,
137 const std::vector<double>&
r_r,
const std::vector<double>& r_sigma2,
138 double& r_chi2)
const {
143 int nb_hits(r_index_set.
size());
147 std::vector<double> mx1, bx1, mx2, bx2;
149 std::vector<double> mx1_err, bx1_err, mx2_err, bx2_err;
153 Amg::Vector3D e2prime(0.0, 0.0, 0.0), e3prime(0.0, 0.0, 0.0);
167 aux_track =
tangent(r_w[r_k_cand],
r_r[r_k_cand], r_sigma2[r_k_cand], r_w[r_l_cand],
r_r[r_l_cand], r_sigma2[r_l_cand], r_cand_case);
172 mx1.push_back(aux_track.
a_x1());
174 bx1.push_back(aux_track.
b_x1());
176 mx2.push_back(aux_track.
a_x2());
178 bx2.push_back(aux_track.
b_x2());
185 for (
int kk = 0; kk < nb_hits - 1; kk++) {
186 for (
int ll = kk + 1; ll < nb_hits; ll++) {
187 int k(r_index_set[kk]);
188 int l(r_index_set[ll]);
190 if (k == r_k_cand && l == r_l_cand) {
continue; }
193 e3prime = (r_w[l] - r_w[k]).
unit();
197 d1 = (r_w[k] -
a).
dot(u) * u - (r_w[k] -
a);
199 d2 = (r_w[l] -
a).
dot(u) * u - (r_w[l] -
a);
205 if (d1.dot(d2) >= 0) {
206 sinalpha = std::abs(
r_r[l] -
r_r[k]) / (r_w[l] - r_w[k]).
mag();
207 cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
209 if (d1.dot(e2prime) >= 0) {
211 p1 = r_w[k] +
r_r[k] * (cosalpha * e2prime - sinalpha * e3prime);
213 p1 = r_w[k] +
r_r[k] * (cosalpha * e2prime + sinalpha * e3prime);
217 p1 = r_w[k] -
r_r[k] * (cosalpha * e2prime - sinalpha * e3prime);
219 p1 = r_w[k] -
r_r[k] * (cosalpha * e2prime + sinalpha * e3prime);
223 if (d2.dot(e2prime) >= 0) {
225 p2 = r_w[l] +
r_r[l] * (cosalpha * e2prime - sinalpha * e3prime);
227 p2 = r_w[l] +
r_r[l] * (cosalpha * e2prime + sinalpha * e3prime);
231 p2 = r_w[l] -
r_r[l] * (cosalpha * e2prime - sinalpha * e3prime);
233 p2 = r_w[l] -
r_r[l] * (cosalpha * e2prime + sinalpha * e3prime);
239 if (d1.dot(d2) < 0) {
240 sinalpha = (
r_r[l] +
r_r[k]) / (r_w[l] - r_w[k]).mag();
241 cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
244 if (d1.dot(e2prime) >= 0 && d2.dot(e2prime) <= 0) {
245 p1 = r_w[k] +
r_r[k] * (cosalpha * e2prime + sinalpha * e3prime);
246 p2 = r_w[l] -
r_r[l] * (cosalpha * e2prime + sinalpha * e3prime);
250 if (d1.dot(e2prime) < 0 && d2.dot(e2prime) >= 0) {
251 p1 = r_w[k] -
r_r[k] * (cosalpha * e2prime - sinalpha * e3prime);
252 p2 = r_w[l] +
r_r[l] * (cosalpha * e2prime - sinalpha * e3prime);
257 if ((p2 - p1).
z() != 0.0) {
261 direction[2] = (1.0e-99);
264 mx1.push_back(tang.
a_x1());
265 bx1.push_back(tang.
b_x1());
266 mx2.push_back(tang.
a_x2());
267 bx2.push_back(tang.
b_x2());
269 mx1_err.push_back(1.0);
270 bx1_err.push_back(1.0);
272 mx2_err.push_back((r_sigma2[k] + r_sigma2[l]) / std::pow(p2.z() - p1.z(), 2));
273 bx2_err.push_back(r_sigma2[k] + p1.z() * p1.z() * (r_sigma2[k] + r_sigma2[l]) / std::pow(p2.z() - p1.z(), 2));
278 nb_tangents = nb_tangents + 1;
291 for (
int k = 0; k < nb_tangents; k++) {
292 if (mx2_err[k] > 0) {
293 sum[0] = sum[0] + mx2[k] / mx2_err[k];
294 sum[1] = sum[1] + 1.0 / mx2_err[k];
296 sum[0] = sum[0] + mx2[k];
297 sum[1] = sum[1] + 1.0;
299 if (bx2_err[k] > 0) {
300 sum[2] = sum[2] + bx2[k] / bx2_err[k];
301 sum[3] = sum[3] + 1.0 / bx2_err[k];
303 sum[2] = sum[2] + bx2[k];
304 sum[3] = sum[3] + 1.0;
308 aux_track =
MTStraightLine(0.0, 0.0, sum[0] / sum[1], sum[2] / sum[3], 0.0, 1.0, std::sqrt(1.0 / sum[1]), std::sqrt(1.0 / sum[3]));
311 for (
int k = 0; k < nb_hits; k++) {
312 r_chi2 = r_chi2 + std::pow(aux_track.
distFromLine(r_w[r_index_set[k]]) -
r_r[r_index_set[k]], 2) / r_sigma2[k];
347 unsigned int nb_selected_hits(0);
350 std::vector<unsigned> selected_hits_index(r_selection.size());
354 std::vector<Amg::Vector3D> w;
355 std::vector<double>
r;
356 std::vector<double> sigma2;
357 unsigned int counter1{0}, counter2{0}, counter3{0};
358 unsigned int max_cand_hits{0};
360 int max_cand_HOTs{0};
363 std::vector<int> k_cand, l_cand;
364 std::vector<int> cand_case;
365 std::vector<int> nb_HOTs;
368 std::vector<IndexSet> index_set;
370 std::vector<double> intercept;
387 <<
"Class QuasianalyticLineReconstruction, method fit: Vector with selected hits unequal to the number of hits on the segment! "
388 "The user selection will be ignored!"
393 for (
unsigned int k : r_selection) {
394 if (k == 0) { nb_selected_hits = nb_selected_hits + 1; }
412 if (nb_selected_hits < 3) {
414 log << MSG::WARNING <<
"Class QuasianalyticLineReconstruction, method fit: Too few hits for the track reconstructions!" <<
endmsg;
423 selected_hits.clear();
427 selected_hits_index.clear();
433 if (r_selection[k] == 1 ||
hit->sigmaDriftRadius() > 100.0) {
continue; }
436 selected_hits.push_back(
hit);
437 selected_hits_index.push_back(k);
439 r.push_back(std::abs(
hit->driftRadius()));
440 sigma2.push_back(
hit->sigma2DriftRadius());
442 if (sigma2[counter2] == 0) { sigma2[counter2] = std::pow(0.1 * CLHEP::mm, 2); }
444 counter2 = counter2 + 1;
446 nb_selected_hits = selected_hits.size();
447 if (nb_selected_hits < 3)
return false;
457 for (
unsigned int k = 0; k < nb_selected_hits; k++) {
458 for (
unsigned int l = k + 1; l < nb_selected_hits; l++) {
461 diff = difftime(end, start);
464 log << MSG::WARNING <<
"Class QuasianalyticLineReconstruction, method fit: time-out for track finding after " <<
m_time_out
470 for (
unsigned int r_case = 1; r_case < 5; r_case++) {
471 tangents[r_case - 1] =
tangent(w[l],
r[l], sigma2[l], w[k],
r[k], sigma2[k], r_case);
476 for (
unsigned int r_case = 1; r_case < 5; r_case++) {
480 std::vector<int> indices;
482 for (
unsigned int n = 0; n < nb_selected_hits; n++) {
484 if (std::abs(std::abs(tangents[r_case - 1].signDistFrom(aux_line)) -
r[n]) <
m_r_max) { counter3++; }
485 if (std::abs(std::abs(tangents[r_case - 1].signDistFrom(aux_line)) -
r[n]) <=
m_road_width) {
486 counter1 = counter1 + 1;
487 indices.push_back(n);
491 aux_set =
IndexSet(counter1, indices);
493 for (
int ca = 0; ca < nb_candidates; ca++) {
494 if (aux_set == index_set[ca] && std::abs(intercept[ca] - tangents[r_case - 1].b_x2()) <
m_road_width) {
499 if (same) {
continue; }
500 nb_candidates = nb_candidates + 1;
503 cand_case.push_back(r_case);
504 index_set.push_back(aux_set);
505 intercept.push_back(tangents[r_case - 1].b_x2());
506 nb_HOTs.push_back(counter3);
507 if (counter1 > max_cand_hits) { max_cand_hits = counter1; }
518 if (max_cand_hits < 3) {
return false; }
521 for (
int ca = 0; ca < nb_candidates; ca++) {
522 if (index_set[ca].
size() < max_cand_hits) {
continue; }
524 aux_track =
track_candidate(index_set[ca], k_cand[ca], l_cand[ca], cand_case[ca], w,
r, sigma2, aux_chi2);
525 if (nb_HOTs[ca] >= max_cand_HOTs) {
526 max_cand_HOTs = nb_HOTs[ca];
527 if (
chi2 == -1.0 ||
chi2 > aux_chi2) {
529 final_track = aux_track;
535 MdtHitVec final_track_hits(max_cand_hits);
536 for (
unsigned int k = 0; k < max_cand_hits; k++) { final_track_hits[k] = selected_hits[index_set[candidate][k]]; }
544 if (std::isnan(
chi2)) {
chi2 = 1.0e6; }
547 std::vector<unsigned int> refit_hit_selection(r_selection.size(), 1);
548 for (
unsigned int k = 0; k < max_cand_hits; k++) { refit_hit_selection[selected_hits_index[index_set[candidate][k]]] = 0; }
553 if (
m_nfitter.fit(r_segment, refit_hit_selection)) {
555 if (dir.z() == 0.0) { dir[2] = (1.0e-99); }
565 for (
unsigned int k = 0; k < max_cand_hits; k++) {
569 double r(std::abs(final_track_hits[k]->driftRadius()));
570 chi2 += std::pow(d -
r, 2) / final_track_hits[k]->sigma2DriftRadius();
572 if (std::isnan(
chi2)) {
chi2 = 1.0e6; }
591 hit.setDistanceToTrack(dist, dist_err);