ATLAS Offline Software
Loading...
Searching...
No Matches
MuonCalib::QuasianalyticLineReconstruction Class Reference

#include <QuasianalyticLineReconstruction.h>

Inheritance diagram for MuonCalib::QuasianalyticLineReconstruction:
Collaboration diagram for MuonCalib::QuasianalyticLineReconstruction:

Public Types

using MdtHitPtr = MuonCalibSegment::MdtHitPtr
using MdtHitVec = MuonCalibSegment::MdtHitVec
typedef std::vector< unsigned int > HitSelection

Public Member Functions

 QuasianalyticLineReconstruction ()
 Default constructor: road width for pattern recognition = 0.5 mm.
 QuasianalyticLineReconstruction (const double r_road_width)
 Constructor: user-defined road width for pattern recognition.
double roadWidth () const
 get the road width used in the pattern recognition
void setRoadWidth (const double r_road_width)
 set the road width for the pattern recognition = r_road_width
void setTimeOut (const double time_out)
 set the time-out for the track finding to time_out (in seconds)
void setMaxRadius (const double maxR)
 set the max innerRadius, default for MDT sMDT 7.1mm, MDT 14.6mm
bool fit (MuonCalibSegment &r_segment) const
 reconstruction of the track using all hits in the segment "r_segment", returns true in case of success; the algorithm overwrites the track radii, the track position, track direction, and chi^2 per degrees of freedom; warning: the errors of the track radii are only approximate
bool fit (MuonCalibSegment &r_segment, HitSelection r_selection) const
 reconstruction of the track using only those hits in r_segment for which the r_selection[.
bool fit (MuonCalibSegment &r_segment, HitSelection r_selection, MTStraightLine &final_track) const
void printLevel (int)
void SetRefineSegmentFlag (const bool flag)
 number of hits selected for track
bool RefineSegmentFlag () const
 get refine segment flag
void switchOnRefit ()
 switch on/off chi^2 refit after hit selection
void switchOffRefit ()
bool refit () const
 return refit flag

Protected Attributes

bool m_refine_segment
 flags
bool m_refit

Private Member Functions

void init ()
void init (const double r_road_width)
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
MTStraightLine track_candidate (const IndexSet &r_index_set, const int &r_k_cand, const int &r_l_cand, const int &r_cand_case, const std::vector< Amg::Vector3D > &r_w, const std::vector< double > &r_r, const std::vector< double > &r_sigma2, double &r_chi2) const

Private Attributes

double m_r_max
double m_road_width
double m_time_out
DCSLFitter m_nfitter
std::vector< MTStraightLinem_tangent
std::vector< int > m_nb_cand_hits
std::vector< MTStraightLinem_candidate

Detailed Description

Definition at line 34 of file QuasianalyticLineReconstruction.h.

Member Typedef Documentation

◆ HitSelection

typedef std::vector<unsigned int> MuonCalib::IMdtSegmentFitter::HitSelection
inherited

Definition at line 32 of file IMdtSegmentFitter.h.

◆ MdtHitPtr

◆ MdtHitVec

Constructor & Destructor Documentation

◆ QuasianalyticLineReconstruction() [1/2]

MuonCalib::QuasianalyticLineReconstruction::QuasianalyticLineReconstruction ( )
inline

Default constructor: road width for pattern recognition = 0.5 mm.

Definition at line 39 of file QuasianalyticLineReconstruction.h.

◆ QuasianalyticLineReconstruction() [2/2]

MuonCalib::QuasianalyticLineReconstruction::QuasianalyticLineReconstruction ( const double r_road_width)
inline

Constructor: user-defined road width for pattern recognition.

Definition at line 42 of file QuasianalyticLineReconstruction.h.

Member Function Documentation

◆ fit() [1/3]

bool QuasianalyticLineReconstruction::fit ( MuonCalibSegment & r_segment) const
virtual

reconstruction of the track using all hits in the segment "r_segment", returns true in case of success; the algorithm overwrites the track radii, the track position, track direction, and chi^2 per degrees of freedom; warning: the errors of the track radii are only approximate

Implements MuonCalib::IMdtSegmentFitter.

Definition at line 328 of file QuasianalyticLineReconstruction.cxx.

328 {
329 // select all hits //
330 HitSelection selection(r_segment.mdtHitsOnTrack(), 0);
331
332 // call the other fit function //
333 return fit(r_segment, selection);
334}
std::vector< unsigned int > HitSelection
unsigned int mdtHitsOnTrack() const
retrieve the number of MdtCalibHitBase s assigned to this segment
bool fit(MuonCalibSegment &r_segment) const
reconstruction of the track using all hits in the segment "r_segment", returns true in case of succes...
const std::string selection

◆ fit() [2/3]

bool QuasianalyticLineReconstruction::fit ( MuonCalibSegment & r_segment,
HitSelection r_selection ) const
virtual

reconstruction of the track using only those hits in r_segment for which the r_selection[.

] is 0, return true in case of success; the algorithm overwrites the track position, direction, and the chi^2 in r_segment; it updates the distances of all hits from the track, i.e. also of those hits which were rejected from the track reconstruction; warning : the errors of the track radii are only approximate

Implements MuonCalib::IMdtSegmentFitter.

Definition at line 335 of file QuasianalyticLineReconstruction.cxx.

335 {
336 MTStraightLine final_track;
337 return fit(r_segment, r_selection, final_track);
338}

◆ fit() [3/3]

bool QuasianalyticLineReconstruction::fit ( MuonCalibSegment & r_segment,
HitSelection r_selection,
MTStraightLine & final_track ) const

Definition at line 339 of file QuasianalyticLineReconstruction.cxx.

339 {
341 // VARIABLES //
343
344 time_t start, end; // start and end time (needed for time-out)
345 time(&start);
346 double diff; // difference of start and end time (needed for time-out)
347 unsigned int nb_selected_hits(0); // number of selected hits
348 MdtHitVec selected_hits; // vector of pointers to the
349 // selected hits
350 std::vector<unsigned> selected_hits_index(r_selection.size());
351 // vector containing the indices
352 // of the selected hits (needed
353 // a requested refit)
354 std::vector<Amg::Vector3D> w; // wire coordinates
355 std::vector<double> r; // drift CLHEP::radii of the selected hits
356 std::vector<double> sigma2; // sigma(r)^2 (spatial resolution in r)
357 unsigned int counter1{0}, counter2{0}, counter3{0}; // auxiliary counters
358 unsigned int max_cand_hits{0}; // the maximum number of hits on a track candidate
359 // found so far
360 int max_cand_HOTs{0}; // the maximum number of hit tubes on a track
361 // candidate found so far
362 int nb_candidates; // number of candidate tracks
363 std::vector<int> k_cand, l_cand; // candidate track index
364 std::vector<int> cand_case; // tangent case for the candidate
365 std::vector<int> nb_HOTs; // number of hits on a candidate
366 int candidate{0}; // index of the candidate which becomes the track
367 IndexSet aux_set; // auxiliary index set
368 std::vector<IndexSet> index_set; // index set for the storage of the hits
369 // forming a track
370 std::vector<double> intercept; // intercepts of track candidates
371 MTStraightLine tangents[4]; // the four tangents to the drift circles of a
372 // hit pair
373 MTStraightLine aux_track; // auxiliary track
374 double aux_chi2; // auxiliary chi^2 variable
375 Amg::Vector3D null(0.0, 0.0, 0.0);
376 Amg::Vector3D xhat(1.0, 0.0, 0.0);
377 MTStraightLine initial_track(r_segment.position(), r_segment.direction(), null, null);
378 // initial track stored in the segment
379 Amg::Vector3D aux_pos, aux_dir; // auxiliary position and direction vectors
380
382 // GET THE NUMBER OF SELECTED HITS //
384 if (r_segment.mdtHitsOnTrack() != r_selection.size()) {
385 MsgStream log(Athena::getMessageSvc(), "QuasianalyticLineReconstruction");
386 log << MSG::WARNING
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!"
389 << endmsg;
390 r_selection.clear();
391 r_selection.assign(r_segment.hitsOnTrack(), 0);
392 } else {
393 for (unsigned int k : r_selection) {
394 if (k == 0) { nb_selected_hits = nb_selected_hits + 1; }
395 }
396 }
397
399 // FIX POTENTIAL SECOND-COORDINATE PROBLEM OF THE INITIAL TRACK SEGMENT //
401
402 if (r_segment.direction().z() == 0.0) {
403 Amg::Vector3D dir(r_segment.direction().x(), r_segment.direction().y(), 1.0);
404 initial_track = MTStraightLine(r_segment.position(), dir, null, null);
405 }
406
408 // RETURN, IF THERE ARE LESS THAN 3 HITS, I.E. THE TRACK IS NOT UNIQUELY //
409 // DEFINED BY THE HITS. //
411
412 if (nb_selected_hits < 3) {
413 MsgStream log(Athena::getMessageSvc(), "QuasianalyticLineReconstruction");
414 log << MSG::WARNING << "Class QuasianalyticLineReconstruction, method fit: Too few hits for the track reconstructions!" << endmsg;
415 return false;
416 }
417
419 // COPY THE WIRE COORDINATES TO A LOCAL VECTOR //
421
422 // vector assignments //
423 selected_hits.clear(); // = vector<const MdtCalibHitBase*>(nb_selected_hits);
424 w.clear(); // = vector<Amg::Vector3D>(nb_selected_hits);
425 r.clear(); // = vector<double>(nb_selected_hits);
426 sigma2.clear(); // = vector<double>(nb_selected_hits);
427 selected_hits_index.clear(); //
428 // vector filling //
429 counter2 = 0;
430 for (unsigned int k = 0; k < r_segment.mdtHitsOnTrack(); k++) {
431 // skip the hit, if it has not been selected //
432 const MuonCalibSegment::MdtHitPtr hit = (r_segment.mdtHOT())[k];
433 if (r_selection[k] == 1 || hit->sigmaDriftRadius() > 100.0) { continue; }
434
435 // copy the hit information into local vectors //
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());
441 // if the spatial resolution has not been set, set it to 0.1 CLHEP::mm //
442 if (sigma2[counter2] == 0) { sigma2[counter2] = std::pow(0.1 * CLHEP::mm, 2); }
443
444 counter2 = counter2 + 1;
445 }
446 nb_selected_hits = selected_hits.size();
447 if (nb_selected_hits < 3) return false;
449 // TRACK RECONSTRUCTION //
451
452 // reset counters //
453 max_cand_hits = 0;
454 max_cand_HOTs = 0;
455 nb_candidates = 0;
456 // 1st step: loop over all hit pairs and determine a track candidate //
457 for (unsigned int k = 0; k < nb_selected_hits; k++) {
458 for (unsigned int l = k + 1; l < nb_selected_hits; l++) {
459 // time-out //
460 time(&end);
461 diff = difftime(end, start);
462 if (diff > m_time_out) {
463 MsgStream log(Athena::getMessageSvc(), "QuasianalyticLineReconstruction");
464 log << MSG::WARNING << "Class QuasianalyticLineReconstruction, method fit: time-out for track finding after " << m_time_out
465 << " seconds!" << endmsg;
466 return false;
467 }
468
469 // 2nd step: determine all four tangents to the drift circles of the hit pair //
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);
472 }
473
474 // 3rd step: determine additional track points within the road width around //
475 // the four tangents //
476 for (unsigned int r_case = 1; r_case < 5; r_case++) {
477 bool same(false);
478 counter1 = 0;
479 counter3 = 0;
480 std::vector<int> indices; // indices of the hits forming a
481 // track
482 for (unsigned int n = 0; n < nb_selected_hits; n++) {
483 MTStraightLine aux_line(w[n], xhat, null, null);
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);
488 }
489 }
490 if (counter1 > 2) {
491 aux_set = IndexSet(counter1, indices);
492 aux_set.sort();
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) {
495 same = true;
496 break;
497 }
498 }
499 if (same) { continue; }
500 nb_candidates = nb_candidates + 1;
501 k_cand.push_back(k);
502 l_cand.push_back(l);
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; }
508 }
509 }
510 }
511 }
512
513 // 4th step: reconstruct a straight-line trajectory for all candidates with //
514 // the maximum number of hits, keep the one with the smallest chi^2 //
515
516 // m_nb_track_hits = max_cand_hits;
517 double chi2 = -1;
518 if (max_cand_hits < 3) { return false; }
519
520 candidate = 0;
521 for (int ca = 0; ca < nb_candidates; ca++) {
522 if (index_set[ca].size() < max_cand_hits) { continue; }
523
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) {
528 chi2 = aux_chi2;
529 final_track = aux_track;
530 candidate = ca;
531 }
532 }
533 }
534
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]]; }
537
538 // make the segment in rphi as the initial segment //
539 aux_pos = Amg::Vector3D(initial_track.b_x1(), final_track.b_x2(), 0);
540 aux_dir = Amg::Vector3D(initial_track.a_x1(), final_track.a_x2(), 1.0);
541 final_track = MTStraightLine(aux_pos, aux_dir, null, null);
542
543 // 5th step: update the segment//
544 if (std::isnan(chi2)) { chi2 = 1.0e6; }
545 r_segment.set(chi2 / (max_cand_hits - 2), final_track.positionVector(), final_track.directionVector());
546
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; }
549 if (!m_refit && m_refine_segment) { r_segment.refineMdtSelection(refit_hit_selection); }
550
551 // chi^2 refit, if requested //
552 if (m_refit) {
553 if (m_nfitter.fit(r_segment, refit_hit_selection)) {
554 Amg::Vector3D dir(r_segment.direction());
555 if (dir.z() == 0.0) { dir[2] = (1.0e-99); }
556 MTStraightLine aux_line(r_segment.position(), dir, Amg::Vector3D(0.0, 0.0, 0.0), Amg::Vector3D(0.0, 0.0, 0.0));
557 double a_err(final_track.a_x2_error());
558 double b_err(final_track.b_x2_error());
559 final_track = MTStraightLine(0.0, 0.0, aux_line.a_x2(), aux_line.b_x2(), 0.0, 0.0, a_err, b_err);
560 aux_pos = Amg::Vector3D(initial_track.b_x1(), final_track.b_x2(), 0);
561 aux_dir = Amg::Vector3D(initial_track.a_x1(), final_track.a_x2(), 1.0);
562 final_track = MTStraightLine(aux_pos, aux_dir, null, null);
563 // recompute chi^2 because of different convention in DCSLFitter //
564 chi2 = 0.0;
565 for (unsigned int k = 0; k < max_cand_hits; k++) {
566 MTStraightLine wire(Amg::Vector3D(0.0, final_track_hits[k]->localPosition().y(), final_track_hits[k]->localPosition().z()),
567 xhat, null, null);
568 double d(std::abs(final_track.signDistFrom(wire)));
569 double r(std::abs(final_track_hits[k]->driftRadius()));
570 chi2 += std::pow(d - r, 2) / final_track_hits[k]->sigma2DriftRadius();
571 }
572 if (std::isnan(chi2)) { chi2 = 1.0e6; }
573
574 r_segment.set(chi2 / (max_cand_hits - 2), final_track.positionVector(), final_track.directionVector());
575 if (m_refine_segment) { r_segment.refineMdtSelection(refit_hit_selection); }
576 return true;
577 }
578 return false;
579 }
580
581 // finish the update (necessary, if no refit has been performed) //
582 for (MdtHitPtr& mdt_hit : r_segment.mdtHOT()) {
583 MdtCalibHitBase& hit = *mdt_hit;
584
585 Amg::Vector3D pos(0.0, (hit.localPosition()).y(), (hit.localPosition()).z());
586 // wire position
587 MTStraightLine aux_line(pos, xhat, null, null);
588 double dist(final_track.signDistFrom(aux_line)); // track distance
589 double dist_err(std::hypot(pos.z() * final_track.a_x2_error(), final_track.b_x2_error()));
590 // approximate error of the track distance
591 hit.setDistanceToTrack(dist, dist_err);
592 }
593 final_track.setUsedHits(final_track_hits);
594 final_track.setChi2(chi2);
595
596 return true;
597}
#define endmsg
bool hit(const Container &ids, int pdgId)
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
size_t size() const
Number of registered mappings.
#define y
#define z
void sort()
sort the indices in ascending order
Definition IndexSet.cxx:137
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
Amg::Vector3D positionVector() const
get the position vector of the straight line
double b_x2_error() const
get the slope of the intercept of the straight line in the x2-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)
double a_x2_error() const
get the error on the slope of the straight line in the x2-x3 plane
void setChi2(double chi2)
Cache the chi2.
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::shared_ptr< MdtCalibHitBase > MdtHitPtr
typedef for a collection of MdtCalibHitBase s
unsigned int hitsOnTrack() const
retrieve the sum of all XxxCalibHits assigned to the MuonCalibSegment
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)
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
MTStraightLine track_candidate(const IndexSet &r_index_set, const int &r_k_cand, const int &r_l_cand, const int &r_cand_case, const std::vector< Amg::Vector3D > &r_w, const std::vector< double > &r_r, const std::vector< double > &r_sigma2, double &r_chi2) const
double chi2(TH1 *h0, TH1 *h1)
int r
Definition globals.cxx:22
Eigen::Matrix< double, 3, 1 > Vector3D
IMessageSvc * getMessageSvc(bool quiet=false)
time(flags, cells_name, *args, **kw)
l
Printing final latex table to .tex output file.
@ driftRadius
trt, straws
Definition ParamDefs.h:53
std::pair< long int, long int > indices

◆ init() [1/2]

void QuasianalyticLineReconstruction::init ( )
private

Definition at line 22 of file QuasianalyticLineReconstruction.cxx.

22 {
23 init(0.5 * CLHEP::mm); // default road width = 0.5 CLHEP::mm
24 return;
25}

◆ init() [2/2]

void QuasianalyticLineReconstruction::init ( const double r_road_width)
private

Definition at line 26 of file QuasianalyticLineReconstruction.cxx.

26 {
27 //::::::::::::::::::
28 //:: SET TIME-OUT ::
29 //::::::::::::::::::
30
31 m_time_out = 10.0;
32
33 //::::::::::::::::::::::::::::
34 //:: SET THE MAXIMUM RADIUS ::
35 //::::::::::::::::::::::::::::
36
37 m_r_max = 14.6;
38
39 //::::::::::::::::::::::::
40 //:: SET THE ROAD WIDTH ::
41 //::::::::::::::::::::::::
42
43 m_road_width = r_road_width;
44
45 return;
46}

◆ printLevel()

void MuonCalib::QuasianalyticLineReconstruction::printLevel ( int )
inlinevirtual

Implements MuonCalib::IMdtSegmentFitter.

Definition at line 88 of file QuasianalyticLineReconstruction.h.

88{};

◆ RefineSegmentFlag()

bool MuonCalib::IMdtPatRecFitter::RefineSegmentFlag ( ) const
inlineinherited

get refine segment flag

Definition at line 37 of file IMdtPatRecFitter.h.

37{ return m_refine_segment; }

◆ refit()

bool MuonCalib::IMdtPatRecFitter::refit ( ) const
inlineinherited

return refit flag

Definition at line 43 of file IMdtPatRecFitter.h.

43{ return m_refit; }

◆ roadWidth()

double QuasianalyticLineReconstruction::roadWidth ( ) const

get the road width used in the pattern recognition

Definition at line 318 of file QuasianalyticLineReconstruction.cxx.

318{ return m_road_width; }

◆ setMaxRadius()

void QuasianalyticLineReconstruction::setMaxRadius ( const double maxR)

set the max innerRadius, default for MDT sMDT 7.1mm, MDT 14.6mm

Definition at line 321 of file QuasianalyticLineReconstruction.cxx.

321 {
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));
326 m_r_max = maxR;
327}

◆ SetRefineSegmentFlag()

void MuonCalib::IMdtPatRecFitter::SetRefineSegmentFlag ( const bool flag)
inlineinherited

number of hits selected for track

virtual unsigned int numberOfTrackHits() const = 0; get selected track hits virtual const std::vector<const MdtCalibHitBase *> &trackHits() const = 0; set refine segment flag

Parameters
flagif true the hit selection is changed in the segment

Definition at line 34 of file IMdtPatRecFitter.h.

bool flag
Definition master.py:29

◆ setRoadWidth()

void QuasianalyticLineReconstruction::setRoadWidth ( const double r_road_width)
virtual

set the road width for the pattern recognition = r_road_width

Implements MuonCalib::IMdtPatRecFitter.

Definition at line 319 of file QuasianalyticLineReconstruction.cxx.

319{ m_road_width = std::abs(r_road_width); }

◆ setTimeOut()

void QuasianalyticLineReconstruction::setTimeOut ( const double time_out)

set the time-out for the track finding to time_out (in seconds)

Definition at line 320 of file QuasianalyticLineReconstruction.cxx.

320{ m_time_out = time_out; }

◆ switchOffRefit()

void MuonCalib::IMdtPatRecFitter::switchOffRefit ( )
inlineinherited

Definition at line 41 of file IMdtPatRecFitter.h.

41{ m_refit = false; }

◆ switchOnRefit()

void MuonCalib::IMdtPatRecFitter::switchOnRefit ( )
inlineinherited

switch on/off chi^2 refit after hit selection

Definition at line 40 of file IMdtPatRecFitter.h.

40{ m_refit = true; }

◆ tangent()

MTStraightLine QuasianalyticLineReconstruction::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
private

Definition at line 47 of file QuasianalyticLineReconstruction.cxx.

49 {
50 //:::::::::::::::
51 //:: VARIABLES ::
52 //:::::::::::::::
53
54 double sinalpha; // auxiliary sinus of an angle
55 double cosalpha; // auxiliary sinus of an angle
56 Amg::Vector3D e2prime(0., 0., 0.), e3prime(0., 0., 0.); // auxiliary direction vectors
57 MTStraightLine tang; // tangent to drift circles of a hit pair
58 Amg::Vector3D p1(0., 0., 0.), p2(0., 0., 0.); // hit points defining a tangent
59 Amg::Vector3D null_vec(0.0, 0.0, 0.0); // auxiliary 0 vector
60 double mx1=0, bx1=0, mx2=0, bx2=0; // auxiliary track parameters
61
62 //::::::::::::::::::::::::::::::::::::::::::::
63 //:: CHECK WHETHER THE SELECTED CASE EXISTS ::
64 //::::::::::::::::::::::::::::::::::::::::::::
65
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__,
69 __LINE__, r_case));
70 }
71
72 //:::::::::::::::::::::::::::::::::::::
73 //:: CALCULATE THE REQUESTED TANGENT ::
74 //:::::::::::::::::::::::::::::::::::::
75
76 // local coordinate axis vectors //
77 e3prime = (r_w2 - r_w1).unit();
78 e2prime = Amg::Vector3D(0.0, e3prime.z(), -e3prime.y());
79
80 // case 1 and 2 //
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);
84
85 // case 1 //
86 if (r_case == 1) {
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);
89 }
90
91 // case 2 //
92 if (r_case == 2) {
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);
95 }
96 }
97
98 // case 3 and 4 //
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);
102
103 // case 3 //
104 if (r_case == 3) {
105 p1 = r_w1 + r_r1 * (cosalpha * e2prime + sinalpha * e3prime);
106 p2 = r_w2 - r_r2 * (cosalpha * e2prime + sinalpha * e3prime);
107 }
108
109 // case 4 //
110 if (r_case == 4) {
111 p1 = r_w1 - r_r1 * (cosalpha * e2prime - sinalpha * e3prime);
112 p2 = r_w2 + r_r2 * (cosalpha * e2prime - sinalpha * e3prime);
113 }
114 }
115
116 // calculation of the tangent and estimation of its errors //
117 if ((p2 - p1).z() != 0.0) {
118 tang = MTStraightLine(p1, p2 - p1, null_vec, null_vec);
119 } else {
120 Amg::Vector3D direction(p2 - p1);
121 direction[2] = 1.0e-99;
122 tang = MTStraightLine(p1, direction, null_vec, null_vec);
123 }
124 mx1 = tang.a_x1();
125 bx1 = tang.b_x1();
126 mx2 = tang.a_x2();
127 bx2 = tang.b_x2();
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)));
130 // errors in mx1 and bx1 are arbitrary since they are
131 // not used at a later stage.
132
133 return tang;
134}
Scalar mag() const
mag method
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
double b_x1() const
get the intercept of the straight line in the x1-x3 plane
double a_x1() const
get the slope of the straight line in the x1-x3 plane
const Amg::Vector3D & direction() const
Method to retrieve the direction at the Intersection.

◆ track_candidate()

MTStraightLine QuasianalyticLineReconstruction::track_candidate ( const IndexSet & r_index_set,
const int & r_k_cand,
const int & r_l_cand,
const int & r_cand_case,
const std::vector< Amg::Vector3D > & r_w,
const std::vector< double > & r_r,
const std::vector< double > & r_sigma2,
double & r_chi2 ) const
private

Definition at line 135 of file QuasianalyticLineReconstruction.cxx.

138 {
139 //:::::::::::::::
140 //:: VARIABLES ::
141 //:::::::::::::::
142
143 int nb_hits(r_index_set.size()); // number of hits used in the track
144 // reconstruction
145 int nb_tangents(0); // number of tangents used in the track
146 // reconstruction
147 std::vector<double> mx1, bx1, mx2, bx2; // slopes and intercepts of the
148 // tangents building the track
149 std::vector<double> mx1_err, bx1_err, mx2_err, bx2_err; // their errors
150 MTStraightLine aux_track; // auxiliary straight line
151 MTStraightLine tang; // tangent to drift circles of a hit pair
152 Amg::Vector3D d1(0.0, 0.0, 0.0), d2(0.0, 0.0, 0.0); // auxiliary distance vectors
153 Amg::Vector3D e2prime(0.0, 0.0, 0.0), e3prime(0.0, 0.0, 0.0); // auxiliary basis vectors
154 Amg::Vector3D a(0.0, 0.0, 0.0), u(0.0, 0.0, 0.0); // position and direction vector of the candidate
155 // tangent
156 double sinalpha; // auxiliary sinus of an angle
157 double cosalpha; // auxiliary sinus of an angle
158 Amg::Vector3D p1(0.0, 0.0, 0.0), p2(0.0, 0.0, 0.0); // hit points defining a tangent
159 Amg::Vector3D null_vec(0.0, 0.0, 0.0); // auxiliary 0 vector
160 double sum[4]; // auxiliary summation variables
161
162 //:::::::::::::::::::::
163 //:: GET THE TANGENT ::
164 //:::::::::::::::::::::
165
166 // calculate the tangent //
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);
168 a = aux_track.positionVector();
169 u = (aux_track.directionVector()).unit();
170
171 // store the parameters of this tangent //
172 mx1.push_back(aux_track.a_x1());
173 mx1_err.push_back(aux_track.a_x1_error());
174 bx1.push_back(aux_track.b_x1());
175 bx1_err.push_back(aux_track.b_x1_error());
176 mx2.push_back(aux_track.a_x2());
177 mx2_err.push_back(aux_track.a_x2_error());
178 bx2.push_back(aux_track.b_x2());
179 bx2_err.push_back(aux_track.b_x2_error());
180
181 //:::::::::::::::::::::::::::::::::::::::::::::::::::::
182 //:: LOOP OVER THE OTHER HITS AND CALCULATE TANGENTS :: //
183 //:::::::::::::::::::::::::::::::::::::::::::::::::::::
184
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]);
189
190 if (k == r_k_cand && l == r_l_cand) { continue; }
191
192 // local coordinate axis vectors //
193 e3prime = (r_w[l] - r_w[k]).unit();
194 e2prime = Amg::Vector3D(0.0, e3prime.z(), -e3prime.y());
195
196 // distance vectors //
197 d1 = (r_w[k] - a).dot(u) * u - (r_w[k] - a);
198 d1[0] = (0.0);
199 d2 = (r_w[l] - a).dot(u) * u - (r_w[l] - a);
200 d2[0] = (0.0);
201
202 // one must distinguish 2 cases //
203
204 // case 1: candidate tangent passes both wires on the same side //
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);
208
209 if (d1.dot(e2prime) >= 0) {
210 if (r_r[k] <= r_r[l]) {
211 p1 = r_w[k] + r_r[k] * (cosalpha * e2prime - sinalpha * e3prime);
212 } else {
213 p1 = r_w[k] + r_r[k] * (cosalpha * e2prime + sinalpha * e3prime);
214 }
215 } else {
216 if (r_r[k] >= r_r[l]) {
217 p1 = r_w[k] - r_r[k] * (cosalpha * e2prime - sinalpha * e3prime);
218 } else {
219 p1 = r_w[k] - r_r[k] * (cosalpha * e2prime + sinalpha * e3prime);
220 }
221 }
222
223 if (d2.dot(e2prime) >= 0) {
224 if (r_r[k] <= r_r[l]) {
225 p2 = r_w[l] + r_r[l] * (cosalpha * e2prime - sinalpha * e3prime);
226 } else {
227 p2 = r_w[l] + r_r[l] * (cosalpha * e2prime + sinalpha * e3prime);
228 }
229 } else {
230 if (r_r[k] >= r_r[l]) {
231 p2 = r_w[l] - r_r[l] * (cosalpha * e2prime - sinalpha * e3prime);
232 } else {
233 p2 = r_w[l] - r_r[l] * (cosalpha * e2prime + sinalpha * e3prime);
234 }
235 }
236 }
237
238 // case 2: candidate tangent passes both wires on opposite sides //
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);
242
243 // case 2(a) //
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);
247 }
248
249 // case 2(b) //
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);
253 }
254 }
255
256 // get the slope and intercept of the new tangents and error estimates //
257 if ((p2 - p1).z() != 0.0) {
258 tang = MTStraightLine(p1, p2 - p1, null_vec, null_vec);
259 } else {
260 Amg::Vector3D direction(p2 - p1);
261 direction[2] = (1.0e-99);
262 tang = MTStraightLine(p1, direction, null_vec, null_vec);
263 }
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());
268
269 mx1_err.push_back(1.0);
270 bx1_err.push_back(1.0);
271
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));
274 // errors in x1 and x2 are arbitrary since they are not
275 // used at a later stage.
276
277 // increase the number of tangents //
278 nb_tangents = nb_tangents + 1;
279 }
280 }
281
282 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
283 //:: CALCULATE A WEIGHTED AVERAGE OVER THE TANGENTS AND THE chi^2 FOR ::
284 //:: THE RECONSTRUCTED TRAJECTORY ::
285 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
286
287 sum[0] = 0.0;
288 sum[1] = 0.0;
289 sum[2] = 0.0;
290 sum[3] = 0.0;
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];
295 } else {
296 sum[0] = sum[0] + mx2[k];
297 sum[1] = sum[1] + 1.0;
298 }
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];
302 } else {
303 sum[2] = sum[2] + bx2[k];
304 sum[3] = sum[3] + 1.0;
305 }
306 }
307
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]));
309
310 r_chi2 = 0.0;
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];
313 }
314
315 return aux_track;
316}
const std::string r_r
static Double_t a
unsigned int size() const
get the number of indices
Definition IndexSet.cxx:82
double distFromLine(const Amg::Vector3D &point) const
get the distance of point point from straight line
double b_x1_error() const
get the error on the intercept of the straight line in the x1-x3 plane
double a_x1_error() const
get the error on the slope of the straight line in the x1-x3 plane
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77
long long ll
dot(G, fn, nodesToHighlight=[])
Definition dot.py:5

Member Data Documentation

◆ m_candidate

std::vector<MTStraightLine> MuonCalib::QuasianalyticLineReconstruction::m_candidate
private

Definition at line 111 of file QuasianalyticLineReconstruction.h.

◆ m_nb_cand_hits

std::vector<int> MuonCalib::QuasianalyticLineReconstruction::m_nb_cand_hits
private

Definition at line 110 of file QuasianalyticLineReconstruction.h.

◆ m_nfitter

DCSLFitter MuonCalib::QuasianalyticLineReconstruction::m_nfitter
private

Definition at line 105 of file QuasianalyticLineReconstruction.h.

◆ m_r_max

double MuonCalib::QuasianalyticLineReconstruction::m_r_max
private

Definition at line 100 of file QuasianalyticLineReconstruction.h.

◆ m_refine_segment

bool MuonCalib::IMdtPatRecFitter::m_refine_segment
protectedinherited

flags

Definition at line 49 of file IMdtPatRecFitter.h.

◆ m_refit

bool MuonCalib::IMdtPatRecFitter::m_refit
protectedinherited

Definition at line 50 of file IMdtPatRecFitter.h.

◆ m_road_width

double MuonCalib::QuasianalyticLineReconstruction::m_road_width
private

Definition at line 101 of file QuasianalyticLineReconstruction.h.

◆ m_tangent

std::vector<MTStraightLine> MuonCalib::QuasianalyticLineReconstruction::m_tangent
private

Definition at line 108 of file QuasianalyticLineReconstruction.h.

◆ m_time_out

double MuonCalib::QuasianalyticLineReconstruction::m_time_out
private

Definition at line 102 of file QuasianalyticLineReconstruction.h.


The documentation for this class was generated from the following files: