14 #include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
15 #include "CLHEP/Units/PhysicalConstants.h"
16 #include "CLHEP/Units/SystemOfUnits.h"
17 #include "GaudiKernel/MsgStream.h"
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();
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());
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) {
294 sum[1] =
sum[1] + 1.0 / mx2_err[
k];
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];
311 for (
int k = 0;
k < nb_hits;
k++) {
322 if (maxR < 7 || maxR > 15)
323 throw std::runtime_error(Form(
324 "File: %s, Line: %d\nQuasianalyticLineReconstruction::setMaxRadius() - given radius %.3f not supported, neither MDT nor sMDT",
325 __FILE__, __LINE__, maxR));
337 return fit(r_segment, r_selection, final_track);
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);
438 w.push_back(
Amg::Vector3D(0.0, (hit->localPosition()).y(), (hit->localPosition()).z()));
439 r.push_back(std::abs(hit->driftRadius()));
440 sigma2.push_back(hit->sigma2DriftRadius());
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++) {
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++) {
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;
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; }
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; }
555 if (
dir.z() == 0.0) {
dir[2] = (1.0e-99); }
565 for (
unsigned int k = 0;
k < max_cand_hits;
k++) {
572 if (std::isnan(
chi2)) {
chi2 = 1.0e6; }