ATLAS Offline Software
SegmentFitHelperFunctions.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
5 
10 #include "GaudiKernel/PhysicalConstants.h"
11 #include "GeoModelKernel/throwExcept.h"
15 
16 namespace{
17  constexpr double c_inv = 1. / Gaudi::Units::c_light;
18  constexpr auto printLvl = MSG::VERBOSE;
19 }
20 
21 
22 namespace MuonR4 {
23  namespace SegmentFitHelpers{
24  using namespace SegmentFit;
26 
27 
28  double chiSqTerm(const Amg::Vector3D& posInChamber,
29  const Amg::Vector3D& dirInChamber,
30  const MuonR4::SpacePoint& measurement,
31  MsgStream& msg) {
32  double chi2{0.};
33  switch (measurement.type()) {
35  chi2 = chiSqTermMdt(posInChamber, dirInChamber,
36  measurement, msg);
37  break;
40  chi2 = chiSqTermStrip(posInChamber, dirInChamber, measurement, msg);
41  break;
42  default:
43  if (msg.level() <= MSG::WARNING) {
44  msg<<MSG::WARNING<<__FILE__<<":"<<__LINE__<<" - Unsupported measurement: "
45  <<measurement.msSector()->idHelperSvc()->toString(measurement.identify())<<endmsg;
46  }
47  }
48  return chi2;
49  }
50  double chiSqTermMdt(const Amg::Vector3D& segPos,
51  const Amg::Vector3D& segDir,
52  const MuonR4::SpacePoint& mdtSP,
53  MsgStream& msg) {
54 
56 
57  residual[Amg::y] = std::abs(Amg::signedDistance(mdtSP.positionInChamber(), mdtSP.directionInChamber(), segPos, segDir))
58  - mdtSP.driftRadius();
59  const double chi2{residual.dot(mdtSP.covariance().inverse()* residual)};
60  if (msg.level() <= printLvl) {
61  msg<<printLvl<<"Measurement "<<mdtSP.msSector()->idHelperSvc()->toString(mdtSP.identify());
62  msg<<printLvl<<", position: "<<Amg::toString(mdtSP.positionInChamber())
63  <<", driftRadius: "<<mdtSP.driftRadius()
64  <<", status: "<<static_cast<const xAOD::MdtDriftCircle*>(mdtSP.primaryMeasurement())->status()<<endmsg;
65  msg<<printLvl<<"segment: "<<Amg::toString(segPos) <<" + x "<<Amg::toString(segDir)<<","<<endmsg;
66  msg<<printLvl<<"residual: "<<Amg::toString(residual) <<", covariance: "<<std::endl
67  <<Amg::toString(mdtSP.covariance())<<std::endl<<", inverse: "
68  <<std::endl<<Amg::toString(mdtSP.covariance().inverse())<<", "<<endmsg;
69  msg<<printLvl<<"chi2 term: "<<chi2<<endmsg;
70  }
71  assert(chi2 >=0.);
72  return chi2;
73  }
74  double chiSqTermStrip(const Amg::Vector3D& segPos,
75  const Amg::Vector3D& segDir,
76  const MuonR4::SpacePoint& stripSP,
77  MsgStream& msg){
78  const Amg::Vector3D normal = stripSP.planeNormal();
79  std::optional<double> travelledDist = Amg::intersect<3>(segPos, segDir, normal, normal.dot(stripSP.positionInChamber()));
80  const Amg::Vector3D planeCrossing = segPos + travelledDist.value_or(0) * segDir;
81 
82  const Amg::Vector2D residual{(planeCrossing - stripSP.positionInChamber()).block<2,1>(0,0)};
83  const double chi2 = residual.dot(stripSP.covariance().inverse()* residual);
84  if (msg.level() <= printLvl) {
85  msg<<printLvl<<"Measurement "<<stripSP.msSector()->idHelperSvc()->toString(stripSP.identify())
86  <<", position: "<<Amg::toString(stripSP.positionInChamber())<<endmsg;
87  msg<<printLvl<<"Segment: "<<Amg::toString(segPos) <<" + x "<<Amg::toString(segDir)<<endmsg;
88  msg<<printLvl<<"Plane crossing: "<<Amg::toString(planeCrossing)<<", residual: "<<Amg::toString(residual)
89  <<", covariance: " <<std::endl<<Amg::toString(stripSP.covariance())<<", inverse: "
90  <<std::endl<<Amg::toString(stripSP.covariance().inverse())<<","<<endmsg;
91  msg<<printLvl<<"chi2 term: "<<chi2<<endmsg;
92  }
93  assert(chi2 >=0.);
94  return chi2;
95  }
96 
97  double chiSqTerm(const Amg::Vector3D& segPos, const Amg::Vector3D& segDir,
98  const double timeOffset, std::optional<double> arrivalTime,
99  const CalibratedSpacePoint& hit,
100  MsgStream& msg) {
101  double chi2{0.};
102  switch (hit.type()) {
104  chi2 = chiSqTermMdt(segPos, segDir, hit, msg);
105  break;
109  chi2 = chiSqTermStrip(segPos, segDir, timeOffset, arrivalTime, hit, msg);
110  break;
112  chi2 = chiSqTermBeamspot(segPos,segDir, hit, msg);
113  break;
114  default:
115  if (msg.level() <= MSG::WARNING) {
116  msg<<MSG::WARNING<<__FILE__<<":"<<__LINE__<<" - Unsupported measurement: "
118  }
119  }
120  return chi2;
121  }
122 
123  double chiSqTermMdt(const Amg::Vector3D& segPos,
124  const Amg::Vector3D& segDir,
125  const CalibratedSpacePoint& hit,
126  MsgStream& msg) {
128  if (hit.fitState() != State::Valid) return 0.;
129  const Amg::Vector3D& hitPos{hit.positionInChamber()};
130  const Amg::Vector3D& hitDir{hit.directionInChamber()};
131 
132  // Calculate the closest point along the segment to the wire
133  const Amg::Vector3D closePointSeg = segPos + Amg::intersect<3>(hitPos, hitDir, segPos, segDir).value_or(0)* segDir;
134  // Closest point along the wire to the segment
135  const Amg::Vector3D closePointWire = hitPos + hitDir.dot(closePointSeg - hitPos) * hitDir;
137  residual[Amg::x] = (hitPos - closePointSeg).x();
138  residual[Amg::y] = (closePointWire - closePointSeg).mag() - hit.driftRadius();
139  const double chi2{contract(inverse(hit.covariance()), residual)};
140  if (msg.level() <= printLvl) {
141  const SpacePoint* sp = hit.spacePoint();
142  msg<<printLvl<<"Calibrated measurement "<<sp->msSector()->idHelperSvc()->toString(sp->identify());
143  msg<<printLvl<<", position: "<<Amg::toString(hit.positionInChamber())<<", driftRadius: "<<hit.driftRadius()
144  <<", dimension: "<<sp->dimension()<<endmsg;
145  msg<<printLvl<<", segment: "<<Amg::toString(segPos) <<" + x "<<Amg::toString(segDir)<<endmsg;
146  msg<<printLvl<<", residual: "<<Amg::toString(residual)<<"/ "<<
147  (Amg::lineDistance<3>(hitPos, hitDir, segPos, segDir) -hit.driftRadius())<<std::endl <<", covariance: "<<std::endl
148  <<toString(hit.covariance())<<", inverse: "
149  <<std::endl<<toString(inverse(hit.covariance()))<<", "<<endmsg;
150  msg<<printLvl<<"Chi2 term: "<<chi2<<endmsg;
151  }
152  assert(chi2 >=0.);
153  return chi2;
154  }
155  double chiSqTermStrip(const Amg::Vector3D& segPos,
156  const Amg::Vector3D& segDir,
157  const double offsetTime,
158  std::optional<double> arrivalTime,
159  const CalibratedSpacePoint& strip,
160  MsgStream& msg) {
161 
163  if (strip.fitState() != State::Valid) return 0.;
164 
165  const SpacePoint* spacePoint = strip.spacePoint();
166  const Amg::Vector3D normal = spacePoint->planeNormal();
167  std::optional<double> travelledDist = Amg::intersect<3>(segPos, segDir, normal, normal.dot(spacePoint->positionInChamber()));
168  const Amg::Vector3D planeCrossing = segPos + travelledDist.value_or(0) * segDir;
169  Amg::Vector3D residual{(planeCrossing - strip.positionInChamber())};
170  if (strip.measuresTime() && arrivalTime) {
171  residual[Amg::z] = strip.time() - (*arrivalTime) - travelledDist.value_or(0) * c_inv - offsetTime;
172  } else {
173  residual[Amg::z] = 0;
174  }
175  const double chi2 = contract(inverse(strip.covariance()), residual);
176  if (msg.level() <= printLvl) {
177  msg<<printLvl<<"Calibrated measurement "<<spacePoint->msSector()->idHelperSvc()->toString(spacePoint->identify())
178  <<", position: "<<Amg::toString(strip.positionInChamber())<<endmsg;
179  msg<<printLvl<<"Segment: "<<Amg::toString(segPos) <<" + x "<<Amg::toString(segDir)<<endmsg;
180  msg<<printLvl<<"Plane crossing: "<<Amg::toString(planeCrossing)<<", residual: "<<Amg::toString(residual)
181  <<", covariance: "<<std::endl<<toString(strip.covariance())<<", inverse: "
182  <<std::endl<<toString(inverse(strip.covariance()))<<endmsg;
183  msg<<printLvl<<" -- final chi2 term: "<<chi2<<endmsg;
184  }
185  assert(chi2 >=0.);
186  return chi2;
187  }
188  double chiSqTermBeamspot(const Amg::Vector3D& segPos,
189  const Amg::Vector3D& segDir,
190  const CalibratedSpacePoint& beamSpotMeas,
191  MsgStream& msg) {
192 
194  if (beamSpotMeas.fitState() != State::Valid) return 0.;
195  const Amg::Vector3D planeCrossing{segPos + Amg::intersect<3>(segPos, segDir, Amg::Vector3D::UnitZ(),
196  beamSpotMeas.positionInChamber().z()).value_or(0) * segDir};
197 
198  const Amg::Vector2D residual = (planeCrossing - beamSpotMeas.positionInChamber()).block<2,1>(0,0);
199  const double chi2 = contract(inverse(beamSpotMeas.covariance()), residual);
200  if (msg.level() <= printLvl) {
201  msg<<printLvl<<"Print beamspot constraint "<<Amg::toString(beamSpotMeas.positionInChamber())<<endmsg;
202  msg<<printLvl<<"Segment: "<<Amg::toString(segPos) <<" + x "<<Amg::toString(segDir)<<endmsg;
203  msg<<printLvl<<"Plane crossing: "<<Amg::toString(planeCrossing)<<", residual: "<<Amg::toString(residual)
204  <<", covariance: "<<std::endl<<toString(beamSpotMeas.covariance())<<std::endl
205  <<", inverse: "<<std::endl<<toString(inverse(beamSpotMeas.covariance()))<<std::endl
206  <<"chi2 term: "<<chi2<<endmsg;
207  }
208  return chi2;
209  }
210  std::vector<int> driftSigns(const Amg::Vector3D& segPos,
211  const Amg::Vector3D& segDir,
212  const std::vector<const SpacePoint*>& uncalibHits,
213  MsgStream& msg) {
214 
215  std::vector<int> signs{};
216  signs.reserve(uncalibHits.size());
217  for (const SpacePoint* sp : uncalibHits) {
218  signs.push_back( sp ? driftSign(segPos,segDir, *sp, msg) : 0);
219  }
220  return signs;
221  }
222  std::vector<int> driftSigns(const Amg::Vector3D& segPos, const Amg::Vector3D& segDir,
223  const std::vector<std::unique_ptr<CalibratedSpacePoint>>& calibHits,
224  MsgStream& msg) {
225  std::vector<int> signs{};
226  signs.reserve(calibHits.size());
227  for (const std::unique_ptr<CalibratedSpacePoint>& hit : calibHits) {
228  signs.push_back(driftSign(segPos,segDir, *hit, msg));
229  }
230  return signs;
231  }
232  int driftSign(const Amg::Vector3D& segPos, const Amg::Vector3D& segDir,
233  const SpacePoint& sp, MsgStream& msg) {
235  return 0;
236  }
237  const double signedDist = Amg::signedDistance(segPos, segDir, sp.positionInChamber(), sp.directionInChamber());
238  if (msg.level() <= printLvl) {
239  msg<<printLvl<<"Hit "<<sp.msSector()->idHelperSvc()->toString(sp.identify())<<" drift radius "<<sp.driftRadius()
240  <<", signed distance: "<<signedDist<<", unsigned distance: "
241  <<Amg::lineDistance<3>(segPos, segDir, sp.positionInChamber(), sp.directionInChamber())<<endmsg;
242  }
243  return sign(signedDist);
244  }
245  int driftSign(const Amg::Vector3D& segPos, const Amg::Vector3D& segDir,
246  const CalibratedSpacePoint& calibHit, MsgStream& msg) {
248  return 0;
249  }
250  const double signedDist = Amg::signedDistance(segPos, segDir, calibHit.positionInChamber(), calibHit.directionInChamber());
251  if (msg.level() <= printLvl) {
252  const SpacePoint* sp = calibHit.spacePoint();
253  msg<<printLvl<<"Hit "<<sp->msSector()->idHelperSvc()->toString(sp->identify())<<" drift radius "<<calibHit.driftRadius()
254  <<", signed distance: "<<signedDist<<", unsigned distance: "
255  <<Amg::lineDistance<3>(segPos, segDir, calibHit.positionInChamber(), calibHit.directionInChamber())<<endmsg;
256  }
257  return sign(signedDist);
258  }
259  }
260 }
MuonR4::SegmentFitHelpers::driftSigns
std::vector< int > driftSigns(const Amg::Vector3D &posInChamber, const Amg::Vector3D &dirInChamber, const std::vector< const SpacePoint * > &uncalibHits, MsgStream &msg)
Calculates whether a segment line travereses the tube measurements on the left (-1) or right (1) side...
Definition: SegmentFitHelperFunctions.cxx:210
MuonR4::SpacePoint::msSector
const MuonGMR4::SpectrometerSector * msSector() const
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:116
MuonR4::SpacePoint::type
xAOD::UncalibMeasType type() const
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:131
ClusterSeg::residual
@ residual
Definition: ClusterNtuple.h:20
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
MuonR4::SpacePoint::planeNormal
Amg::Vector3D planeNormal() const
Returns the vector pointing out of the measurement plane.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:128
Amg::y
@ y
Definition: GeoPrimitives.h:35
xAOD::UncalibMeasType::MMClusterType
@ MMClusterType
MuonR4::SegmentFitHelpers::chiSqTerm
double chiSqTerm(const Amg::Vector3D &posInChamber, const Amg::Vector3D &dirInChamber, const SpacePoint &measurement, MsgStream &msg)
Calculates the chi2 contribuation to a linear segment line from an uncalibrated measurement.
Definition: SegmentFitHelperFunctions.cxx:28
x
#define x
MatrixUtils.h
MuonR4::toString
std::string toString(const CalibratedSpacePoint::Covariance_t &mat)
Returns the matrix in string.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:75
xAOD::UncalibMeasType::TgcStripType
@ TgcStripType
MuonR4::SpacePoint::primaryMeasurement
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:107
CalibratedSpacePoint.h
MuonR4::SegmentFitHelpers::driftSign
int driftSign(const Amg::Vector3D &posInChamber, const Amg::Vector3D &dirInChamber, const SpacePoint &uncalibHit, MsgStream &msg)
Calculates whether a segement line travereses the tube measurement on the left (-1) or right (1) side...
Definition: SegmentFitHelperFunctions.cxx:232
Amg::z
@ z
Definition: GeoPrimitives.h:36
MuonR4::SegmentFitHelpers::chiSqTermStrip
double chiSqTermStrip(const Amg::Vector3D &posInChamber, const Amg::Vector3D &dirInChamber, const SpacePoint &measurement, MsgStream &msg)
Calculates the chi2 contribuation to a linear segment line from an uncalibrated strip measurement.
Definition: SegmentFitHelperFunctions.cxx:74
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
MuonR4::SegmentFitHelpers::chiSqTermMdt
double chiSqTermMdt(const Amg::Vector3D &posInChamber, const Amg::Vector3D &dirInChamber, const SpacePoint &measurement, MsgStream &msg)
Calculates the chi2 contribuation to a linear segment line from an uncalibrated Mdt measurement.
Definition: SegmentFitHelperFunctions.cxx:50
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
MuonR4::inverse
CalibratedSpacePoint::Covariance_t inverse(const CalibratedSpacePoint::Covariance_t &mat)
Inverts the parsed matrix.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:65
UtilFunctions.h
SegmentFitHelperFunctions.h
Amg::x
@ x
Definition: GeoPrimitives.h:34
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:523
MuonR4::CalibratedSpacePoint::State
State
State flag to distinguish different space point states.
Definition: CalibratedSpacePoint.h:24
xAOD::Other
@ Other
MuonR4::CalibratedSpacePoint::type
xAOD::UncalibMeasType type() const
Returns the space point type.
Definition: CalibratedSpacePoint.cxx:36
MdtDriftCircle.h
MuonR4::CalibratedSpacePoint::State::Valid
@ Valid
MuonR4::SpacePoint
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/MuonSpacePoint/SpacePoint.h:18
MuonR4::SpacePoint::directionInChamber
const Amg::Vector3D & directionInChamber() const
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:122
MuonR4::sign
constexpr double sign(const double x)
Returns the sign of a number.
Definition: MatrixUtils.h:11
MuonGMR4::SpectrometerSector::idHelperSvc
const Muon::IMuonIdHelperSvc * idHelperSvc() const
Returns the IdHelpeSvc.
Definition: SpectrometerSector.cxx:40
MuonR4::CalibratedSpacePoint::fitState
State fitState() const
Returns the state of the calibrated space point.
Definition: CalibratedSpacePoint.cxx:55
MuonR4::CalibratedSpacePoint::positionInChamber
const Amg::Vector3D & positionInChamber() const
The position of the calibrated space point inside the chamber.
Definition: CalibratedSpacePoint.cxx:21
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:63
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
MuonR4::SpacePoint::positionInChamber
const Amg::Vector3D & positionInChamber() const
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:119
SegmentFitterEventData.h
Muon::IMuonIdHelperSvc::toString
virtual std::string toString(const Identifier &id) const =0
print all fields to string
GeoPrimitivesHelpers.h
MuonR4::CalibratedSpacePoint
The calibrated Space point is created during the calibration process.
Definition: CalibratedSpacePoint.h:15
MuonR4::SpacePoint::dimension
unsigned int dimension() const
Is the space point a 1D or combined 2D measurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:160
AthMessaging.h
Amg::signedDistance
double signedDistance(const Amg::Vector3D &posA, const Amg::Vector3D &dirA, const Amg::Vector3D &posB, const Amg::Vector3D &dirB)
Calculates the signed distance between two lines in 3D space.
Definition: GeoPrimitivesHelpers.h:329
MuonR4::SpacePoint::driftRadius
double driftRadius() const
: Returns the size of the drift radius
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:143
merge.status
status
Definition: merge.py:17
MuonR4::CalibratedSpacePoint::covariance
const Covariance_t & covariance() const
Definition: CalibratedSpacePoint.cxx:33
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
xAOD::MdtDriftCircle_v1
https://gitlab.cern.ch/atlas/athena/-/blob/master/MuonSpectrometer/MuonReconstruction/MuonRecEvent/Mu...
Definition: MdtDriftCircle_v1.h:21
MuonR4::CalibratedSpacePoint::spacePoint
const SpacePoint * spacePoint() const
The pointer to the space point out of which this space point has been built.
Definition: CalibratedSpacePoint.cxx:18
MuonR4::CalibratedSpacePoint::directionInChamber
const Amg::Vector3D & directionInChamber() const
The direction of the calibrated space point inside the chamber.
Definition: CalibratedSpacePoint.cxx:24
xAOD::UncalibMeasType::RpcStripType
@ RpcStripType
MuonR4::CalibratedSpacePoint::driftRadius
double driftRadius() const
The drift radius of the calibrated space point.
Definition: CalibratedSpacePoint.cxx:27
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
xAOD::UncalibMeasType::MdtDriftCircleType
@ MdtDriftCircleType
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:26
MuonR4::SpacePoint::identify
const Identifier & identify() const
: Identifier of the primary measurement
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:140
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
MuonR4::SegmentFitHelpers::chiSqTermBeamspot
double chiSqTermBeamspot(const Amg::Vector3D &posInChamber, const Amg::Vector3D &dirInChamber, const CalibratedSpacePoint &beamSpotMeas, MsgStream &msg)
Calculates the chi2 contribution from an external beam spot constraint.
Definition: SegmentFitHelperFunctions.cxx:188
MuonR4::contract
double contract(const CalibratedSpacePoint::Covariance_t &mat, const Amg::Vector3D &a, const Amg::Vector3D &b)
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:13