11#include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
12#include "CLHEP/Units/PhysicalConstants.h"
13#include "CLHEP/Units/SystemOfUnits.h"
15#include "GaudiKernel/MsgStream.h"
24 init(0.5 * CLHEP::mm);
67 const double r_r2,
const double r_sigma22,
const int &r_case)
const {
78 double mx1 = 0, bx1 = 0, mx2 = 0, bx2 = 0;
84 if (r_case < 1 || r_case > 4) {
85 throw std::runtime_error(
86 Form(
"File: %s, Line: %d\nStraightPatRec::tangent - Illegal case %i, must be 1,2,3, or 4.!", __FILE__, __LINE__, r_case));
94 e3prime = (r_w2 - r_w1).
unit();
98 if (r_case == 1 || r_case == 2) {
99 sinalpha = std::abs(r_r2 - r_r1) / (r_w2 - r_w1).
mag();
100 cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
104 p1 = r_w1 + ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r1 * (cosalpha * e2prime - sinalpha * e3prime);
105 p2 = r_w2 + ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r2 * (cosalpha * e2prime - sinalpha * e3prime);
110 p1 = r_w1 - ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r1 * (cosalpha * e2prime + sinalpha * e3prime);
111 p2 = r_w2 - ((1 && r_r2 >= r_r1) - (1 && r_r2 < r_r1)) * r_r2 * (cosalpha * e2prime + sinalpha * e3prime);
116 if (r_case == 3 || r_case == 4) {
117 sinalpha = (r_r1 + r_r2) / (r_w2 - r_w1).mag();
118 cosalpha = std::sqrt(1.0 - sinalpha * sinalpha);
122 p1 = r_w1 + r_r1 * (cosalpha * e2prime + sinalpha * e3prime);
123 p2 = r_w2 - r_r2 * (cosalpha * e2prime + sinalpha * e3prime);
128 p1 = r_w1 - r_r1 * (cosalpha * e2prime - sinalpha * e3prime);
129 p2 = r_w2 + r_r2 * (cosalpha * e2prime - sinalpha * e3prime);
134 if ((p2 - p1).
z() != 0.0) {
138 direction[2] = (1.0e-99);
145 tang =
MTStraightLine(mx1, bx1, mx2, bx2, 1.0, 1.0, std::sqrt(r_sigma12 + r_sigma22) / std::abs(p2.z() - p1.z()),
146 std::sqrt(r_sigma12 + p1.z() * p1.z() * (r_sigma12 + r_sigma22) / std::pow(p2.z() - p1.z(), 2)));
161 unsigned int num_selected_hits(0);
162 for (
unsigned int k : r_selection) {
163 if (!k) { num_selected_hits++; }
165 if (num_selected_hits < 3)
return cand_line;
177 r_segment.
mdtHOT()[k]->setDistanceToTrack(cand_line.
signDistFrom(aux_line), r_segment.
mdtHOT()[k]->sigmaDriftRadius());
183 unsigned int NLC = 2;
193 refDir = refDir.unit();
197 double rotAngle =
Amg::angle(Amg::Vector3D::UnitZ(), refDir) * (refDir.y()) / std::abs(refDir.y());
208 std::vector<Amg::Vector3D> hit_position_track;
214 WirPosTrack = RotMatr * WirPosTrack;
215 double signedDrifRadius =
216 std::abs(r_segment.
mdtHOT()[l]->driftRadius()) *
217 (r_segment.
mdtHOT()[l]->signedDistanceToTrack() / std::abs(r_segment.
mdtHOT()[l]->signedDistanceToTrack()));
219 HitPosTrack[0] = HitPosTrack.y() + signedDrifRadius;
220 HitPosTrack[1] = r_segment.
mdtHOT()[l]->sigma2DriftRadius();
222 hit_position_track.push_back(HitPosTrack);
227 delta[1] = HitPosTrack.z();
229 if (!r_selection[l]) {
230 double weight = 1.0 / (r_segment.
mdtHOT()[l]->sigma2DriftRadius());
231 Gamma += weight * delta * delta.transpose();
232 betha += weight * HitPosTrack.y() * delta;
237 Gamma = Gamma.inverse();
238 alpha = Gamma * betha;
240 double refit_chi2(0.0);
241 for (
unsigned int j = 0; j < hit_position_track.size(); j++) {
242 double res = (alpha[0] + alpha[1] * hit_position_track[j].z() - hit_position_track[j].
y());
243 if (!r_selection[j]) refit_chi2 +=
res *
res / hit_position_track[j].x();
248 seg_dir = RotMatr_inv * seg_dir;
249 seg_dir[1] = seg_dir.y() / seg_dir.z();
250 seg_dir[0] = init_dir.x() / init_dir.z();
254 seg_pos = RotMatr_inv * seg_pos;
255 seg_pos = seg_pos + refTransl;
257 seg_pos[1] = seg_pos.y() + seg_dir.y() * (init_pos.z() - seg_pos.z());
258 seg_pos[0] = init_pos.x();
259 seg_pos[2] = init_pos.z();
262 r_segment.
set(refit_chi2 / (num_selected_hits - 2), seg_pos, seg_dir);
313 std::vector<unsigned int> hit_index;
314 unsigned int try_nb_hits;
318 std::vector<unsigned int> selected_hits_index;
322 double r_min, r_max{};
323 double sigma2_min, sigma2_max;
325 unsigned int counter1;
327 unsigned int nb_candidates(0);
346 <<
"fitCallByReference() - Vector with selected hits unequal to the number of hits on the segment! The user selection will "
356 if (!r_selection[k]) {
357 selected_hits.push_back(r_segment.
mdtHOT()[k]);
358 selected_hits_index.push_back(k);
367 if (selected_hits.size() < 3) {
return false; }
385 try_nb_hits = selected_hits.size();
387 while (nb_candidates == 0) {
390 if (try_nb_hits < 5 && (selected_hits.size() - try_nb_hits) > 2)
return false;
392 double best_chi2ndf = -1.0;
404 diff = difftime(end, start);
416 tmp_selection.assign(tmp_selection.size(), 1);
417 for (
unsigned int k = 0; k < try_nb_hits; k++) { tmp_selection[selected_hits_index[hit_index[k] - 1]] = 0; }
421 w_min = selected_hits[hit_index[0] - 1]->localPosition();
422 w_max = selected_hits[hit_index[0] - 1]->localPosition();
423 r_min = selected_hits[hit_index[0] - 1]->driftRadius();
424 r_max = selected_hits[hit_index[0] - 1]->driftRadius();
425 sigma2_min = selected_hits[hit_index[0] - 1]->sigma2DriftRadius();
426 sigma2_max = selected_hits[hit_index[0] - 1]->sigma2DriftRadius();
427 for (
unsigned int k = 1; k < try_nb_hits; k++) {
428 if (selected_hits[hit_index[k] - 1]->localPosition().
z() < w_min.z()) {
429 w_min = selected_hits[hit_index[k] - 1]->localPosition();
430 r_min = selected_hits[hit_index[k] - 1]->driftRadius();
431 sigma2_min = selected_hits[hit_index[k] - 1]->sigma2DriftRadius();
433 if (selected_hits[hit_index[k] - 1]->localPosition().
z() > w_max.z()) {
434 w_max = selected_hits[hit_index[k] - 1]->localPosition();
435 r_max = selected_hits[hit_index[k] - 1]->driftRadius();
436 sigma2_max = selected_hits[hit_index[k] - 1]->sigma2DriftRadius();
441 if (sigma2_min == 0) { sigma2_min = 0.1; }
442 if (sigma2_max == 0) { sigma2_max = 0.1; }
445 for (
unsigned int r_case = 1; r_case < 5; r_case++) {
446 tangents[r_case - 1] =
tangent(w_min, r_min, sigma2_min, w_max, r_max, sigma2_max, r_case);
451 for (
unsigned int r_case = 1; r_case < 5; r_case++) {
453 for (
unsigned int n = 0; n < try_nb_hits; n++) {
454 MTStraightLine aux_line(selected_hits[hit_index[n] - 1]->localPosition(), xhat, null, null);
455 if (std::abs(std::abs(tangents[r_case - 1].signDistFrom(aux_line)) - selected_hits[hit_index[n] - 1]->driftRadius()) <=
457 counter1 = counter1 + 1;
464 if (counter1 == try_nb_hits) {
466 aux_track =
fitCandidate(r_segment, tmp_selection, tangents[r_case - 1]);
468 if ((best_chi2ndf == -1) || (best_chi2ndf > r_segment.
chi2())) {
469 best_chi2ndf = r_segment.
chi2();
470 best_aux_line = aux_track;
471 final_selection.assign(final_selection.size(), 1);
472 for (
unsigned int j = 0; j < try_nb_hits; j++) { final_selection[selected_hits_index[hit_index[j] - 1]] = 0; }
485 if (nb_candidates > 0) {
487 for (
unsigned int k = 0; k < r_selection.size(); k++) {
488 r_selection[k] = final_selection[k];
489 if (!final_selection[k]) { used_hits.push_back(r_segment.
mdtHOT()[k]); }
493 fitted_track =
fitCandidate(r_segment, final_selection, best_aux_line);
499 try_nb_hits = try_nb_hits - 1;
500 if (try_nb_hits < 3) {
return false; }
507 return fitted_track.
chi2() > 0;
Scalar mag() const
mag method
detray::unit< scalar_t > unit
std::pair< std::vector< unsigned int >, bool > res
void diff(const TrigCaloCluster &a, const TrigCaloCluster &b, std::map< std::string, double > &varChange)
void currentCombination(std::vector< unsigned int > &index_array) const
get the current combination; the result is stored in the vector index_array
unsigned int numberOfCombinations() const
get the number of combinations
void setNewParameters(const unsigned int &nb_elements, const unsigned int &wh_class)
set the number of elements = nb_elements; set the class of which the combination is = wh_class
void nextCombination(std::vector< unsigned int > &index_array)
get the next combination; the results is stored in the array index_array
bool m_refine_segment
flags
std::vector< unsigned int > HitSelection
Amg::Vector3D directionVector() const
get the direction vector of the straight line
double b_x2() const
get the intercept of the straight line in the x2-x3 plane
double a_x2() const
get the slope of the straight line in the x2-x3 plane
double b_x1() const
get the intercept of the straight line in the x1-x3 plane
Amg::Vector3D positionVector() const
get the position vector of the straight line
double a_x1() const
get the slope of the straight line in the x1-x3 plane
void setUsedHits(const MdtHitVec &hits)
double signDistFrom(const MTStraightLine &h) const
get the signed distance of two lines (if both are parallel, dist>0)
void setChi2(double chi2)
Cache the chi2.
void setNumberOfTrackHits(unsigned int n_hits)
cache the number of track hits
A MuonCalibSegment is a reconstructed three dimensional track segment in the MuonSpectrometer.
unsigned int mdtHitsOnTrack() const
retrieve the number of MdtCalibHitBase s assigned to this segment
void refineMdtSelection(const std::vector< unsigned int > &new_selection)
move trck hits to close hits
const Amg::Vector3D & direction() const
retrieve local direction of segment (on station level) retrieve the transformation from local chamber...
std::vector< MdtHitPtr > MdtHitVec
unsigned int hitsOnTrack() const
retrieve the sum of all XxxCalibHits assigned to the MuonCalibSegment
double chi2() const
retrieve chi2
const MdtHitVec & mdtHOT() const
retrieve the full set of MdtCalibHitBase s assigned to this segment
void set(double chi2, const Amg::Vector3D &pos, const Amg::Vector3D &dir)
const Amg::Vector3D & position() const
retrieve local position of segment (on station level)
void setTimeOut(const double time_out)
set the time-out for the track finding to time_out (in seconds)
double roadWidth() const
get the final track in the local co-ordinate frame, i.e.
bool fitCallByReference(MuonCalibSegment &r_segment, HitSelection &r_selection, MTStraightLine &line_track) const
MTStraightLine fitCandidate(MuonCalibSegment &r_segment, const std::vector< unsigned int > &r_selection, const MTStraightLine &cand_line) const
void setRoadWidth(const double r_road_width)
set the road width for the pattern recognition = r_road_width
bool fit(MuonCalibSegment &r_segment) const
reconstruction of the track using all hits in the segment "r_segment", returns true in case of succes...
MTStraightLine tangent(const Amg::Vector3D &r_w1, const double r_r1, const double r_sigma12, const Amg::Vector3D &r_w2, const double r_r2, const double r_sigma22, const int &r_case) const
void setFixSelection(bool fix_sel)
const std::string selection
singleton-like access to IMessageSvc via open function and helper
Eigen::AngleAxisd AngleAxis3D
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
double angle(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
calculates the opening angle between two vectors
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
IMessageSvc * getMessageSvc(bool quiet=false)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.