Loading [MathJax]/jax/output/SVG/config.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MdtSegmentFitter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
9 #include <GaudiKernel/PhysicalConstants.h>
11 #include <CxxUtils/sincos.h>
12 
13 #include <format>
14 /* * Residual strip hit: R= (P + <P-H|D>*D -H)
15  * dR
16  * --> -- dP = dP + <dP|D>*D
17  * dP
18  *
19  * dR
20  * -- dD = <P-H|D>dD + <P-H|dD>*D
21  * dD
22  *
23  * chi2 = <R|1./cov^{2} | R>
24  *
25  * dchi2 = <dR | 1./cov^{2} | R> + <R | 1./cov^{2} | dR>
26  */
27 namespace {
28  constexpr double c_inv = 1. / Gaudi::Units::c_light;
29  /* Cut off value for the determinant. Hessian matrices with a determinant smaller than this
30  are considered to be invalid */
31  constexpr double detCutOff = 1.e-8;
32 }
33 
34 namespace MuonR4{
35  using namespace SegmentFit;
38 
41  RangeArray rng{};
42  constexpr double spatRang = 10.*Gaudi::Units::m;
43  constexpr double timeTange = 25 * Gaudi::Units::ns;
44  rng[toInt(ParamDefs::y0)] = std::array{-spatRang, spatRang};
45  rng[toInt(ParamDefs::x0)] = std::array{-spatRang, spatRang};
48  rng[toInt(ParamDefs::time)] = std::array{-timeTange, timeTange};
49  return rng;
50  }
53  m_cfg{std::move(config)}{}
54 
55  inline void MdtSegmentFitter::updateDriftSigns(const Amg::Vector3D& segPos, const Amg::Vector3D& segDir,
56  SegmentFitResult& fitResult) const {
57  for (std::unique_ptr<CalibratedSpacePoint>& meas : fitResult.calibMeasurements) {
58  meas->setDriftRadius(SegmentFitHelpers::driftSign(segPos,segDir, *meas, msg())*meas->driftRadius());
59  }
60  }
61 
62  inline bool MdtSegmentFitter::recalibrate(const EventContext& ctx,
63  SegmentFitResult& fitResult) const{
64 
65  const auto [segPos, segDir] = makeLine(fitResult.segmentPars);
66 
67  fitResult.calibMeasurements = m_cfg.calibrator->calibrate(ctx, std::move(fitResult.calibMeasurements), segPos, segDir,
68  fitResult.segmentPars[toInt(ParamDefs::time)]);
69  if (!updateHitSummary(fitResult)){
70  return false;
71  }
72  updateDriftSigns(segPos, segDir, fitResult);
74  if (fitResult.timeFit && fitResult.nDoF <= 1) {
75  fitResult.timeFit = false;
76  ATH_MSG_DEBUG("Switch of the time fit because nDoF: "<<fitResult.nDoF);
77  fitResult.segmentPars[toInt(ParamDefs::time)] = 0.;
79  fitResult.calibMeasurements = m_cfg.calibrator->calibrate(ctx, std::move(fitResult.calibMeasurements), segPos, segDir,
80  fitResult.segmentPars[toInt(ParamDefs::time)]);
82  } else if (!fitResult.timeFit && m_cfg.doTimeFit) {
83  ATH_MSG_DEBUG("Somehow a measurement is on the narrow ridge of validity. Let's try if the time can be fitted now ");
84  fitResult.timeFit = true;
85  }
86 
87  return true;
88  }
89  inline bool MdtSegmentFitter::updateHitSummary(SegmentFitResult& fitResult) const {
92  fitResult.nPhiMeas = fitResult.nDoF = fitResult.nTimeMeas = 0;
93  for (const HitType& hit : fitResult.calibMeasurements) {
94  if (hit->fitState() != State::Valid){
95  continue;
96  }
97 
98  fitResult.nPhiMeas+= hit->measuresPhi();
99  fitResult.nDoF+= hit->measuresPhi();
100  fitResult.nDoF+= hit->measuresEta();
102  fitResult.nDoF += (m_cfg.doTimeFit && hit->type() != xAOD::UncalibMeasType::MdtDriftCircleType && hit->measuresTime());
103  fitResult.nTimeMeas+=hit->measuresTime();
104  }
105  if (!fitResult.nDoF) {
106  ATH_MSG_VERBOSE("Measurements rejected.");
107  return false;
108  }
109  if (!fitResult.nPhiMeas) {
110  ATH_MSG_VERBOSE("No phi measurements are left.");
111  fitResult.segmentPars[toInt(ParamDefs::phi)] = 90. * Gaudi::Units::deg;
112  fitResult.segmentPars[toInt(ParamDefs::x0)] = 0;
113  }
114 
115  fitResult.nDoF = fitResult.nDoF - 2 - (fitResult.nPhiMeas > 0 ? 2 : 0);
116 
117  return true;
118  }
121 
126  line.gradient[toInt(ParamDefs::x0)] = Amg::Vector3D::UnitX();
127  line.gradient[toInt(ParamDefs::y0)] = Amg::Vector3D::UnitY();
139  phi{params[toInt(ParamDefs::phi)]};
140  line.gradient[toInt(ParamDefs::theta)] = Amg::Vector3D{phi.cs*theta.cs, phi.sn*theta.cs, -theta.sn};
141  line.gradient[toInt(ParamDefs::phi)] = Amg::Vector3D{-theta.sn *phi.sn, theta.sn*phi.cs, 0};
142  /*********************************************************************************
143  * Non-vanishing second order derivatives
144  *
145  * d^{2} segDir d^{2} segDir cos phi
146  * ------------- = - segDir , ------------ = - sin(theta) sin phi
147  * d^{2} theta d^{2} phi 0
148  *
149  * d^{2} segDir -sin phi
150  * ------------- = cos(theta) cos phi
151  * d theta dPhi 0
152  ************************************************************************************/
153  constexpr unsigned nPars = LineWithPartials::nPars;
154  constexpr int idxThetaSq = vecIdxFromSymMat<nPars>(toInt(ParamDefs::theta), toInt(ParamDefs::theta));
155  constexpr int idxPhiSq = vecIdxFromSymMat<nPars>(toInt(ParamDefs::phi), toInt(ParamDefs::phi));
156  constexpr int idxPhiTheta = vecIdxFromSymMat<nPars>(toInt(ParamDefs::theta), toInt(ParamDefs::phi));
157  line.hessian[idxThetaSq] = - Amg::Vector3D{phi.cs*theta.sn,phi.sn*theta.sn, theta.cs};
158  line.hessian[idxPhiSq] = -theta.sn * Amg::Vector3D{phi.cs, phi.sn, 0.};
159  line.hessian[idxPhiTheta] = theta.cs * Amg::Vector3D{-phi.sn, phi.cs, 0.};
160  }
162  const CalibratedSpacePoint& hit,
163  ResidualWithPartials& resObj) const {
165  const Amg::Vector3D& hitPos{hit.positionInChamber()};
166  const Amg::Vector3D& hitDir{hit.directionInChamber()};
168  resObj.projIntoWirePlane = line.dir.dot(hitDir);
169  resObj.projDirLenSq = 1. - resObj.projIntoWirePlane*resObj.projIntoWirePlane;
170  if (resObj.projDirLenSq < std::numeric_limits<float>::epsilon()) {
171  resObj.residual.setZero();
172  for (Amg::Vector3D& grad : resObj.gradient){
173  grad.setZero();
174  }
175  if (m_cfg.useSecOrderDeriv) {
176  for (Amg::Vector3D& hess : resObj.hessian) {
177  hess.setZero();
178  }
179  }
180  ATH_MSG_WARNING("Segment is parallel along the wire");
181  return;
182  }
183  resObj.invProjLenSq = 1. / resObj.projDirLenSq;
184  resObj.invProjLen = std::sqrt(resObj.invProjLenSq);
186  resObj.projDir = (line.dir - resObj.projIntoWirePlane*hitDir) * resObj.invProjLen;
188  const Amg::Vector3D hitMinSeg = hitPos - line.pos ;
190  const double lineDist = resObj.projDir.cross(hitDir).dot(hitMinSeg);
191  const double resVal = (lineDist - hit.driftRadius());
192  resObj.residual = resVal * Amg::Vector3D::Unit(toInt(AxisDefs::eta));
193  ATH_MSG_VERBOSE("Mdt drift radius: "<<hit.driftRadius()<<" distance: "<<lineDist<<";"
194  <<Amg::signedDistance(hitPos, hitDir, line.pos, line.dir)<<", residual: "<<resVal);
197  if (hit.dimension() == 2) {
198  resObj.residual[toInt(AxisDefs::phi)] = (hitMinSeg.dot(line.dir)*resObj.projIntoWirePlane - hitMinSeg.dot(hitDir)) * resObj.invProjLenSq;
199  }
200  constexpr unsigned nLinePars = LineWithPartials::nPars;
202  for (const int param : {toInt(ParamDefs::y0), toInt(ParamDefs::x0),
204  if (!resObj.evalPhiPars && (param == toInt(ParamDefs::x0) || param == toInt(ParamDefs::phi))){
205  continue;
206  }
207  switch (param) {
208  case toInt(ParamDefs::theta):
209  case toInt(ParamDefs::phi): {
210  resObj.partWirePlaneProj[param] = line.gradient[param].dot(hitDir);
211  resObj.partProjDir[param] = (line.gradient[param] - resObj.partWirePlaneProj[param]*hitDir) * resObj.invProjLen
212  + resObj.partWirePlaneProj[param]*resObj.projIntoWirePlane* resObj.projDir * resObj.invProjLenSq;
213  const double partialDist = resObj.partProjDir[param].cross(hitDir).dot(hitMinSeg);
214 
215  resObj.gradient[param] = partialDist * Amg::Vector3D::Unit(toInt(AxisDefs::eta));
216  if (hit.dimension() == 2) {
217  resObj.gradient[param][toInt(AxisDefs::phi)] =
218  ( hitMinSeg.dot(line.gradient[param]) * resObj.projIntoWirePlane +
219  hitMinSeg.dot(line.dir)*resObj.partWirePlaneProj[param]) * resObj.invProjLenSq
220  +2.* resObj.residual[toInt(AxisDefs::phi)]*( resObj.projIntoWirePlane * resObj.partWirePlaneProj[param]) * resObj.invProjLenSq;
221  }
222  break;
223  } case toInt(ParamDefs::y0):
224  case toInt(ParamDefs::x0): {
225  const double partialDist = - resObj.projDir.cross(hitDir).dot(line.gradient[param]);
226  resObj.gradient[param] = partialDist * Amg::Vector3D::Unit(toInt(AxisDefs::eta));
227  if (hit.dimension() == 2) {
228  resObj.gradient[param][toInt(AxisDefs::phi)] = -(line.gradient[param].dot(line.dir) * resObj.projIntoWirePlane -
229  line.gradient[param].dot(hitDir)) * resObj.invProjLenSq;
230  }
231  break;
232  }
234  default:
235  break;
236  }
237  }
238  if (!m_cfg.useSecOrderDeriv) {
239  return;
240  }
242  for (int param = toInt(ParamDefs::phi); param >=0; --param){
243  if (!resObj.evalPhiPars && (param == toInt(ParamDefs::x0) || param == toInt(ParamDefs::phi))){
244  continue;
245  }
246  for (int param1 = param; param1>=0; --param1) {
247  if (!resObj.evalPhiPars && (param1 == toInt(ParamDefs::x0) || param1 == toInt(ParamDefs::phi))){
248  continue;
249  }
250  const int lineIdx = vecIdxFromSymMat<nLinePars>(param, param1);
251  const int resIdx = vecIdxFromSymMat<toInt(ParamDefs::nPars)>(param, param1);
253  if ( (param == toInt(ParamDefs::theta) || param == toInt(ParamDefs::phi)) &&
254  (param1 == toInt(ParamDefs::theta) || param1 == toInt(ParamDefs::phi))) {
255 
256  const double partSqLineProject = line.hessian[lineIdx].dot(hitDir);
257  const Amg::Vector3D projDirPartSq = (line.hessian[lineIdx] - partSqLineProject * hitDir) * resObj.invProjLen
258  + (resObj.partWirePlaneProj[param1] * resObj.projIntoWirePlane) * resObj.invProjLenSq * resObj.partProjDir[param]
259  + (resObj.partWirePlaneProj[param] * resObj.projIntoWirePlane) * resObj.invProjLenSq * resObj.partProjDir[param1]
260  + (partSqLineProject*resObj.projIntoWirePlane) * resObj.invProjLenSq * resObj.projDir
261  + (resObj.partWirePlaneProj[param1] * resObj.partWirePlaneProj[param]) * std::pow(resObj.invProjLenSq, 2) * resObj.projDir;
262 
263  const double partialSqDist = projDirPartSq.cross(hitDir).dot(hitMinSeg);
264  resObj.hessian[resIdx] = partialSqDist * Amg::Vector3D::Unit(toInt(AxisDefs::eta));
265  if (hit.dimension() == 2) {
266  const double partialSqAlongWire =2.*resObj.residual[toInt(AxisDefs::phi)]*resObj.projIntoWirePlane*partSqLineProject * resObj.invProjLenSq
267  +2.*resObj.residual[toInt(AxisDefs::phi)]*resObj.partWirePlaneProj[param]*resObj.partWirePlaneProj[param1]*resObj.invProjLenSq
268  +2.*resObj.gradient[param1][toInt(AxisDefs::phi)]*resObj.projIntoWirePlane*resObj.partWirePlaneProj[param]*resObj.invProjLenSq
269  +2.*resObj.gradient[param][toInt(AxisDefs::phi)]*resObj.projIntoWirePlane*resObj.partWirePlaneProj[param1]*resObj.invProjLenSq
270  + hitMinSeg.dot(line.hessian[lineIdx]) *resObj.projIntoWirePlane * resObj.invProjLenSq
271  + hitMinSeg.dot(line.dir)*partSqLineProject * resObj.invProjLenSq
272  + hitMinSeg.dot(line.gradient[param])*resObj.partWirePlaneProj[param1]*resObj.invProjLenSq
273  + hitMinSeg.dot(line.gradient[param1])*resObj.partWirePlaneProj[param]*resObj.invProjLenSq;
274  resObj.hessian[resIdx][toInt(AxisDefs::phi)] = partialSqAlongWire;
275  }
276  }
278  else if (param == toInt(ParamDefs::theta) || param == toInt(ParamDefs::phi)){
279  const double partialSqDist = - resObj.partProjDir[param].cross(hitDir).dot(line.gradient[param1]);
280  resObj.hessian[resIdx] = partialSqDist * Amg::Vector3D::Unit(toInt(AxisDefs::eta));
281  if (hit.dimension() == 2) {
282  const double partialSqAlongWire = -(line.gradient[param1].dot(line.gradient[param])*resObj.projIntoWirePlane +
283  line.gradient[param1].dot(line.dir)*resObj.partWirePlaneProj[param]) * resObj.invProjLenSq
284  + 2.* resObj.gradient[param1][toInt(AxisDefs::phi)]*( resObj.projIntoWirePlane * resObj.partWirePlaneProj[param]) * resObj.invProjLenSq;
285  resObj.hessian[resIdx][toInt(AxisDefs::phi)] = partialSqAlongWire;
286  }
287  }
288  }
289  }
290  }
292  const CalibratedSpacePoint& hit,
294 
295 
296  const Amg::Vector3D& hitPos{hit.positionInChamber()};
297  const Amg::Vector3D normal = hit.type() != xAOD::UncalibMeasType::Other
298  ? hit.spacePoint()->planeNormal() : Amg::Vector3D::UnitZ();
299  const double planeOffSet = normal.dot(hitPos);
300 
301  const double normDot = normal.dot(line.dir);
302  if (std::abs(normDot) < std::numeric_limits<double>::epsilon()){
303  residual.residual.setZero();
304  for (Amg::Vector3D& deriv: residual.gradient) {
305  deriv.setZero();
306  }
307  if (m_cfg.useSecOrderDeriv) {
308  for (Amg::Vector3D& hessian : residual.hessian){
309  hessian.setZero();
310  }
311  }
312  ATH_MSG_WARNING("The hit parallel with the segment line "<<Amg::toString(line.dir));
313  return;
314  }
315  const double travelledDist = (planeOffSet - line.pos.dot(normal)) / normDot;
316 
317  const Amg::Vector3D planeIsect = line.pos + travelledDist * line.dir;
319  residual.residual.block<2,1>(0,0) = (planeIsect - hitPos).block<2,1>(0,0);
320 
321  for (unsigned fitPar = 0; fitPar < line.gradient.size(); ++fitPar) {
322  switch (fitPar) {
323  case toInt(ParamDefs::phi):
324  case toInt(ParamDefs::theta):{
325  const double partialDist = - travelledDist / normDot * normal.dot(line.gradient[fitPar]);
326  residual.gradient[fitPar].block<2,1>(0,0) = (travelledDist * line.gradient[fitPar] + partialDist * line.dir).block<2,1>(0,0);
327  break;
328  } case toInt(ParamDefs::y0):
329  case toInt(ParamDefs::x0): {
330  residual.gradient[fitPar].block<2,1>(0,0) = (line.gradient[fitPar] - line.gradient[fitPar].dot(normal) / normDot * line.dir).block<2,1>(0,0);
331  break;
332  }
333  default: {
334  break;
335  }
336  }
337  }
338  if (!m_cfg.useSecOrderDeriv) {
339  return;
340  }
341  constexpr unsigned nLinePars = LineWithPartials::nPars;
342  for (int param = toInt(ParamDefs::phi); param >=0; --param){
343  for (int param1 = param; param1>=0; --param1) {
344  const int lineIdx = vecIdxFromSymMat<nLinePars>(param, param1);
345  const int resIdx = vecIdxFromSymMat<toInt(ParamDefs::nPars)>(param, param1);
346  if ( (param == toInt(ParamDefs::theta) || param == toInt(ParamDefs::phi)) &&
347  (param1 == toInt(ParamDefs::theta) || param1 == toInt(ParamDefs::phi))) {
348  residual.hessian[resIdx].block<2,1>(0,0) =(
349  travelledDist * line.hessian[lineIdx] - travelledDist *(normal.dot(line.hessian[lineIdx])) / normDot * line.dir
350  - normal.dot(line.gradient[param1]) / normDot * residual.gradient[param]
351  - normal.dot(line.gradient[param]) / normDot * residual.gradient[param1]).block<2,1>(0,0);
352  } else if (param == toInt(ParamDefs::theta) || param == toInt(ParamDefs::phi)) {
353  const double gradientDisplace = normal.dot(line.gradient[param1]);
354  if (gradientDisplace > std::numeric_limits<float>::epsilon()){
355  residual.hessian[resIdx].block<2,1>(0,0) = gradientDisplace*( normal.dot(line.gradient[param]) / std::pow(normDot,2)*line.dir
356  - line.gradient[param] / normDot ).block<2,1>(0,0);
357  } else {
358  residual.hessian[resIdx].setZero();
359  }
360  }
361  }
362  }
363  }
364 
366  HitVec&& calibHits,
367  const Parameters& startPars,
368  const Amg::Transform3D& localToGlobal) const {
369 
370  const Muon::IMuonIdHelperSvc* idHelperSvc{calibHits[0]->spacePoint()->msSector()->idHelperSvc()};
372 
373  if (msgLvl(MSG::VERBOSE)) {
374  std::stringstream hitStream{};
375  const auto [startPos, startDir] = makeLine(startPars);
376  for (const HitType& hit : calibHits) {
377  hitStream<<" **** "<<(hit->type() != xAOD::UncalibMeasType::Other ? idHelperSvc->toString(hit->spacePoint()->identify()): "beamspot" )
378  <<" position: "<<Amg::toString(hit->positionInChamber());
379  if (hit->type() == xAOD::UncalibMeasType::MdtDriftCircleType) {
380  hitStream<<", driftRadius: "<<SegmentFitHelpers::driftSign(startPos,startDir, *hit, msg())*hit->driftRadius() ;
381  }
382  hitStream<<", channel dir: "<<Amg::toString(hit->directionInChamber())<<std::endl;
383  }
384  ATH_MSG_VERBOSE("Start segment fit with parameters "<<toString(startPars)
385  <<", plane location: "<<Amg::toString(localToGlobal)<<std::endl<<hitStream.str());
386 
387  }
388 
389  SegmentFitResult fitResult{};
390  fitResult.segmentPars = startPars;
391  fitResult.timeFit = m_cfg.doTimeFit;
392  fitResult.calibMeasurements = std::move(calibHits);
393  if (!updateHitSummary(fitResult)) {
394  ATH_MSG_WARNING("No valid segment seed parsed from the beginning");
395  return fitResult;
396  }
397  if (!m_cfg.reCalibrate) {
398  const auto [segPos, segDir] = makeLine(startPars);
399  updateDriftSigns(segPos, segDir, fitResult);
400  }
401  Parameters gradient{AmgVector(5)::Zero()}, prevGrad{AmgVector(5)::Zero()}, prevPars{AmgVector(5)::Zero()};
402  AmgSymMatrix(5) hessian{AmgSymMatrix(5)::Zero()};
403 
405  LineWithPartials segmentLine{};
408 
409  unsigned int noChangeIter{0};
410  while (fitResult.nIter++ < m_cfg.nMaxCalls) {
411  ATH_MSG_DEBUG("Iteration: "<<fitResult.nIter<<" parameters: "<<toString(fitResult.segmentPars)<<", chi2: "<<fitResult.chi2);
413  updateLinePartials(fitResult.segmentPars, segmentLine);
414 
416  if (m_cfg.reCalibrate && !recalibrate(ctx, fitResult)) {
417  break;
418  }
420  fitResult.chi2 = 0;
421  hessian.setZero();
422  gradient.setZero();
423 
425  for (HitType& hit : fitResult.calibMeasurements) {
426  if (hit->fitState() != State::Valid) {
427  continue;
428  }
429  const Amg::Vector3D& hitPos{hit->positionInChamber()};
430  const Amg::Vector3D& hitDir{hit->directionInChamber()};
431  ATH_MSG_DEBUG("Update chi2 from measurement "<<(hit->spacePoint() ? idHelperSvc->toString(hit->spacePoint()->identify())
432  : "pseudo meas")<<" position: "<<Amg::toString(hitPos)<<" + "<<Amg::toString(hitDir));
433 
434  const int start = toInt(fitResult.nPhiMeas ? ParamDefs::phi : ParamDefs::theta);
435  switch (hit->type()) {
439  const double dSign = (hit->driftRadius() > 0 ? 1. : -1.);
440  if (fitResult.timeFit && !m_cfg.reCalibrate && fitResult.nIter > 1) {
441  hit = m_cfg.calibrator->calibrate(ctx, *hit, segmentLine.pos, segmentLine.dir,
442  fitResult.segmentPars[toInt(ParamDefs::time)]);
443  hit->setDriftRadius(dSign*hit->driftRadius());
444  }
445  calculateWireResiduals(segmentLine, *hit, residual);
446 
447  if (!fitResult.timeFit) {
448  break;
449  }
451  residual.gradient[toInt(ParamDefs::time)] = dSign*m_cfg.calibrator->driftVelocity(ctx, *hit) * Amg::Vector3D::Unit(toInt(AxisDefs::eta));
452  if (m_cfg.useSecOrderDeriv) {
453  constexpr unsigned hessIdx = vecIdxFromSymMat<ResidualWithPartials::nPars>(toInt(ParamDefs::time), toInt(ParamDefs::time));
454  residual.hessian[hessIdx] = dSign*m_cfg.calibrator->driftAcceleration(ctx, *hit) * Amg::Vector3D::Unit(toInt(AxisDefs::eta));
455  }
456  break;
457  }
462  calculateStripResiduals(segmentLine, *hit, residual);
463  if (!fitResult.timeFit || !hit->measuresTime()) {
464  break;
465  }
466  constexpr ParamDefs par = ParamDefs::time;
467  residual.gradient[toInt(par)] = -Amg::Vector3D::Unit(toInt(AxisDefs::t0));
468  const Amg::Vector3D planeIsect = residual.residual + hitPos;
469  const double totFlightDist = (localToGlobal * planeIsect).mag() * c_inv;
470  residual.residual[toInt(AxisDefs::t0)] = hit->time() - totFlightDist * c_inv - fitResult.segmentPars[toInt(ParamDefs::time)];
471 
472  for (int p = start; p >= 0; --p) {
473  residual.gradient[p][toInt(AxisDefs::t0)] = -residual.gradient[p].perp() * c_inv;
474  ATH_MSG_VERBOSE("Partial derivative of "<<idHelperSvc->toString(hit->spacePoint()->identify())
475  <<" residual "<<Amg::toString(residual.residual)<<" "<<Amg::toString(multiply(inverse(hit->covariance()), residual.residual))
476  <<" "<<std::endl<<toString(hit->covariance())<<std::endl<<" w.r.t "
477  <<toString(static_cast<ParamDefs>(p))<<"="<<Amg::toString(residual.gradient[p]));
478  }
479  break;
481  calculateStripResiduals(segmentLine, *hit, residual);
482  break;
483  } default: {
484  const auto &measurement = *hit->spacePoint()->primaryMeasurement();
485  ATH_MSG_WARNING("MdtSegmentFitter() - Unsupported measurment type" <<typeid(measurement).name());
486  }
487  }
488 
489  ATH_MSG_VERBOSE("Update derivatives for hit "<< (hit->spacePoint() ? idHelperSvc->toString(hit->spacePoint()->identify()) : "beamspot"));
490  updateDerivatives(residual, hit->covariance(), gradient, hessian, fitResult.chi2,
491  fitResult.timeFit && hit->measuresTime() ? toInt(ParamDefs::time) : start);
492  }
493 
495  for (int k =1; k < 5 - (!fitResult.timeFit); ++k){
496  for (int l = 0; l< k; ++l){
497  hessian(l,k) = hessian(k,l);
498  }
499  }
501  if (gradient.mag() < m_cfg.tolerance) {
502  fitResult.converged = true;
503  ATH_MSG_VERBOSE("Fit converged after "<<fitResult.nIter<<" iterations with "<<fitResult.chi2);
504  break;
505  }
506  ATH_MSG_VERBOSE("Chi2: "<<fitResult.chi2<<", gradient: "<<Amg::toString(gradient)<<"hessian: "<<std::endl<<hessian);
509  if (!fitResult.nPhiMeas && !fitResult.timeFit) {
510  paramUpdate = updateParameters<2>(fitResult.segmentPars, prevPars, gradient, prevGrad, hessian);
511  } else if (!fitResult.nPhiMeas && fitResult.timeFit) {
514  hessian.col(2).swap(hessian.col(toInt(ParamDefs::time)));
515  hessian.row(2).swap(hessian.row(toInt(ParamDefs::time)));
516  std::swap(gradient[2], gradient[toInt(ParamDefs::time)]);
517  std::swap(fitResult.segmentPars[2], fitResult.segmentPars[toInt(ParamDefs::time)]);
518 
519  paramUpdate = updateParameters<3>(fitResult.segmentPars, prevPars, gradient, prevGrad, hessian);
520 
521  std::swap(fitResult.segmentPars[2], fitResult.segmentPars[toInt(ParamDefs::time)]);
522  hessian.col(2).swap(hessian.col(toInt(ParamDefs::time)));
523  hessian.row(2).swap(hessian.row(toInt(ParamDefs::time)));
524  std::swap(gradient[2], gradient[toInt(ParamDefs::time)]);
525  } else if (fitResult.nPhiMeas && !fitResult.timeFit) {
526  paramUpdate = updateParameters<4>(fitResult.segmentPars, prevPars, gradient, prevGrad, hessian);
527  } else if (fitResult.nPhiMeas && fitResult.timeFit) {
528  paramUpdate = updateParameters<5>(fitResult.segmentPars, prevPars, gradient, prevGrad, hessian);
529  }
530  if (paramUpdate == UpdateStatus::noChange) {
531  if ((++noChangeIter) >= m_cfg.noMoveIter){
532  fitResult.converged = true;
533  break;
534  }
535  } else if (paramUpdate == UpdateStatus::allOkay) {
536  noChangeIter = 0;
537  } else if (paramUpdate == UpdateStatus::outOfBounds){
538  return fitResult;
539  }
540  }
541 
543  fitResult.nDoF-=fitResult.timeFit;
544 
546  const auto [segPos, segDir] = fitResult.makeLine();
547  fitResult.chi2 =0.;
548 
549  std::optional<double> toF = fitResult.timeFit ? std::make_optional<double>((localToGlobal * segPos).mag() * c_inv) : std::nullopt;
551  std::ranges::stable_sort(fitResult.calibMeasurements, [](const HitType&a, const HitType& b){
552  return a->positionInChamber().z() < b->positionInChamber().z();
553  });
554 
555  /*** Remove the drift sign again */
556  fitResult.chi2 =0.;
557  for (const HitType& hit : fitResult.calibMeasurements) {
558  hit->setDriftRadius(std::abs(hit->driftRadius()));
559  fitResult.chi2 +=SegmentFitHelpers::chiSqTerm(segPos, segDir, fitResult.segmentPars[toInt(ParamDefs::time)], toF, *hit, msg());
560  }
562  if (!fitResult.nPhiMeas&& !fitResult.timeFit) {
563  blockCovariance<2>(std::move(hessian), /* std::move(gradient), std::move(prevGrad), */ fitResult.segmentParErrs);
564  }else if (!fitResult.nPhiMeas && fitResult.timeFit) {
565  hessian.col(2).swap(hessian.col(toInt(ParamDefs::time)));
566  hessian.row(2).swap(hessian.row(toInt(ParamDefs::time)));
567  blockCovariance<3>(std::move(hessian),/* std::move(gradient), std::move(prevGrad), */ fitResult.segmentParErrs);
568  fitResult.segmentParErrs.col(2).swap(fitResult.segmentParErrs.col(toInt(ParamDefs::time)));
569  fitResult.segmentParErrs.row(2).swap(fitResult.segmentParErrs.row(toInt(ParamDefs::time)));
570  } else if (fitResult.nPhiMeas) {
571  blockCovariance<4>(std::move(hessian), /* std::move(gradient), std::move(prevGrad), */ fitResult.segmentParErrs);
572  } else if (fitResult.nPhiMeas && fitResult.timeFit) {
573  blockCovariance<5>(std::move(hessian),/* std::move(gradient), std::move(prevGrad), */ fitResult.segmentParErrs);
574  }
575  return fitResult;
576  }
577 
579  const MeasCov_t& covariance,
580  AmgVector(5)& gradient, AmgSymMatrix(5)& hessian,
581  double& chi2, int startPar) const {
582  const MeasCov_t invCov{inverse(covariance)};
583  const Amg::Vector3D covRes = multiply(invCov, fitMeas.residual);
584  chi2 += covRes.dot(fitMeas.residual);
585  for (int p = startPar; p >=0 ; --p) {
586  gradient[p] +=2.*covRes.dot(fitMeas.gradient[p]);
587  for (int k=p; k>=0; --k) {
588  hessian(p,k)+= 2.*contract(invCov, fitMeas.gradient[p], fitMeas.gradient[k]);
589  if (m_cfg.useSecOrderDeriv) {
590  const int symMatIdx = vecIdxFromSymMat<ResidualWithPartials::nPars>(p,k);
591  hessian(p,k)+=contract(invCov, covRes, fitMeas.hessian[symMatIdx]);
592  }
593  }
594  }
595  ATH_MSG_VERBOSE("After derivative update --- chi2: "<<chi2<<"("<<covRes.dot(fitMeas.residual)<<"), gradient: "
596  <<toString(gradient)<<", Hessian:\n"<<hessian<<", measurement covariance\n"<<toString(invCov));
597  }
598 
599  template <unsigned int nDim>
601  SegmentFit::Covariance& covariance) const {
602 
603  covariance.setIdentity();
604  AmgSymMatrix(nDim) miniHessian = hessian.block<nDim, nDim>(0,0);
605  if (std::abs(miniHessian.determinant()) <= detCutOff) {
606  ATH_MSG_VERBOSE("Boeser mini hessian ("<<miniHessian.determinant()<<")\n"<<miniHessian<<"\n\n"<<hessian);
607  return;
608  }
609  ATH_MSG_VERBOSE("Hessian matrix: \n"<<hessian<<",\nblock Hessian:\n"<<miniHessian<<",\n determinant: "<<miniHessian.determinant());
610  covariance.block<nDim,nDim>(0,0) = miniHessian.inverse();
611  ATH_MSG_VERBOSE("covariance: \n"<<covariance);
612  }
613 
614  template <unsigned int nDim>
617  Parameters& currGrad, Parameters& prevGrad,
618  const AmgSymMatrix(5)& currentHessian) const {
619 
620  AmgSymMatrix(nDim) miniHessian = currentHessian.block<nDim, nDim>(0,0);
621  ATH_MSG_DEBUG("Parameter update -- \ncurrenPars: "<<toString(currPars)<<", \ngradient: "<<toString(currGrad)
622  <<", hessian ("<<miniHessian.determinant()<<")"<<std::endl<<miniHessian);
623 
624  double changeMag{0.};
625  if (std::abs(miniHessian.determinant()) > detCutOff) {
626  prevPars.block<nDim,1>(0,0) = currPars.block<nDim,1>(0,0);
627  // Update the parameters accrodingly to the hessian
628  const AmgVector(nDim) updateMe = miniHessian.inverse()* currGrad.block<nDim, 1>(0,0);
629  changeMag = std::sqrt(updateMe.dot(updateMe));
630  currPars.block<nDim,1>(0,0) -= updateMe;
631  prevGrad.block<nDim,1>(0,0) = currGrad.block<nDim,1>(0,0);
632  ATH_MSG_DEBUG("Hessian inverse:\n"<<miniHessian.inverse()<<"\n\nUpdate the parameters by -"
633  <<Amg::toString(updateMe));
634  } else {
635  const AmgVector(nDim) gradDiff = (currGrad - prevGrad).block<nDim,1>(0,0);
636  const double gradDiffMag = gradDiff.mag2();
637  double denom = (gradDiffMag > std::numeric_limits<float>::epsilon() ? gradDiffMag : 1.);
638  const double gamma = std::abs((currPars - prevPars).block<nDim,1>(0,0).dot(gradDiff))
639  / denom;
640  ATH_MSG_VERBOSE("Hessian determinant invalid. Try deepest descent - \nprev parameters: "
641  <<toString(prevPars)<<",\nprevious gradient: "<<toString(prevGrad)<<", gamma: "<<gamma);
642  prevPars.block<nDim, 1>(0,0) = currPars.block<nDim, 1>(0,0);
643  currPars.block<nDim, 1>(0,0) -= gamma* currGrad.block<nDim, 1>(0,0);
644  prevGrad.block<nDim, 1>(0,0) = currGrad.block<nDim,1>(0,0);
645  changeMag = std::abs(gamma) * currGrad.block<nDim, 1>(0,0).mag();
646  }
648  unsigned int nOutOfBound{0};
649  for (unsigned int p = 0; p< nDim; ++p) {
650  double& parValue{currPars[p]};
651  if constexpr(nDim == 3) {
653  if (p == 2) {
655  }
656  }
657  if (m_cfg.ranges[p][0] > parValue || m_cfg.ranges[p][1] < parValue) {
658  ATH_MSG_VERBOSE("The "<<p<<"-th parameter "<<toString(static_cast<ParamDefs>(p))<<" is out of range "<<parValue
659  <<" allowed ["<<m_cfg.ranges[p][0]<<"-"<<m_cfg.ranges[p][1]<<"]");
660  ++nOutOfBound;
661  parValue = std::clamp(parValue, m_cfg.ranges[p][0], m_cfg.ranges[p][1]);
662  }
663 
664  }
665  if (nOutOfBound > m_cfg.nParsOutOfBounds){
667  }
668  if (changeMag <= m_cfg.tolerance) {
669  return UpdateStatus::noChange;
670  }
671  return UpdateStatus::allOkay;
672  }
673 }
MuonR4::MdtSegmentFitter::ResidualWithPartials::residual
Amg::Vector3D residual
Vector carrying the residual.
Definition: MdtSegmentFitter.h:91
MuonR4::MdtSegmentFitter::ResidualAuxillaries::invProjLen
double invProjLen
inverse of the unormalized dir porjection
Definition: MdtSegmentFitter.h:83
MuonR4::MdtSegmentFitter::updateDriftSigns
void updateDriftSigns(const Amg::Vector3D &segPos, const Amg::Vector3D &segDir, SegmentFitResult &fitRes) const
Update the signs of the measurement.
Definition: MdtSegmentFitter.cxx:55
MuonR4::SegmentFit::ParamDefs
ParamDefs
This file defines the parameter enums in the Trk namespace.
Definition: MuonHoughDefs.h:29
checkFileSG.line
line
Definition: checkFileSG.py:75
MuonR4::MdtSegmentFitter::blockCovariance
void blockCovariance(const AmgSymMatrix(5)&hessian, SegmentFit::Covariance &covariance) const
Definition: MdtSegmentFitter.cxx:600
MuonR4::MdtSegmentFitter::updateHitSummary
bool updateHitSummary(SegmentFitResult &fitResult) const
Brief updates the hit summary from the contributing hits.
Definition: MdtSegmentFitter.cxx:89
MuonR4::MdtSegmentFitter::calculateStripResiduals
void calculateStripResiduals(const LineWithPartials &line, const CalibratedSpacePoint &spacePoint, ResidualWithPartials &residual) const
Calculates the residual together with hte correspdonding derivatives for strip measurements.
Definition: MdtSegmentFitter.cxx:291
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
MuonR4::MdtSegmentFitter::LineWithPartials::nPars
static constexpr unsigned nPars
Free parameters of the line (x0,y0,theta,phi)
Definition: MdtSegmentFitter.h:56
MuonR4::MdtSegmentFitter::ResidualWithPartials
Helper struct carrying the residual with its derivatives.
Definition: MdtSegmentFitter.h:87
MuonR4::MdtSegmentFitter::UpdateStatus
UpdateStatus
Definition: MdtSegmentFitter.h:172
MuonR4::MdtSegmentFitter::ResidualAuxillaries::partProjDir
std::array< Amg::Vector3D, nLinePars > partProjDir
Partial derivatives of the dir projection w.r.t.
Definition: MdtSegmentFitter.h:73
ClusterSeg::residual
@ residual
Definition: ClusterNtuple.h:20
MuonR4::multiply
Amg::Vector3D multiply(const CalibratedSpacePoint::Covariance_t &mat, const Amg::Vector3D &v)
Multiplies a 3D vector with the covariance matrix which can be either 2x2 or 3x3 matrix.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:40
MuonR4::MdtSegmentFitter::Parameters
SegmentFit::Parameters Parameters
Definition: MdtSegmentFitter.h:22
MuonR4::SegmentFitResult::calibMeasurements
HitVec calibMeasurements
Calibrated measurements used in the fit.
Definition: SegmentFitterEventData.h:64
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
MuonR4::MdtSegmentFitter::UpdateStatus::outOfBounds
@ outOfBounds
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::MdtSegmentFitter::ResidualAuxillaries::partWirePlaneProj
std::array< double, nLinePars > partWirePlaneProj
Partial derivatives of the dir projection lengths w.r.t line parameters.
Definition: MdtSegmentFitter.h:75
sincos.h
Helper to simultaneously calculate sin and cos of the same angle.
deg
#define deg
Definition: SbPolyhedron.cxx:17
MuonR4::HitVec
SpacePointPerLayerSorter::HitVec HitVec
Definition: SpacePointPerLayerSorter.cxx:9
ISpacePointCalibrator.h
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
MuonR4::ISpacePointCalibrator::calibrate
virtual CalibSpacePointPtr calibrate(const EventContext &ctx, const SpacePoint *spacePoint, const Amg::Vector3D &seedPosInChamb, const Amg::Vector3D &seedDirInChamb, const double timeDelay) const =0
Calibrates a single space point.
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MuonR4::ISpacePointCalibrator::driftVelocity
virtual double driftVelocity(const EventContext &ctx, const CalibratedSpacePoint &spacePoint) const =0
Returns the drift velocity for a given drift-circle space point.
xAOD::UncalibMeasType::sTgcStripType
@ sTgcStripType
MuonR4::MdtSegmentFitter::Config::noMoveIter
unsigned int noMoveIter
How many iterations with changes below tolerance.
Definition: MdtSegmentFitter.h:42
D3PDTest::rng
uint32_t rng()
Definition: FillerAlg.cxx:40
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
MuonR4::SegmentFit::makeLine
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
Definition: SegmentFitterEventData.cxx:26
ParamDefs.h
MuonR4::MdtSegmentFitter::Config::tolerance
double tolerance
Gradient cut off.
Definition: MdtSegmentFitter.h:30
MuonR4::toString
std::string toString(const CalibratedSpacePoint::Covariance_t &mat)
Returns the matrix in string.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:75
MuonR4::MdtSegmentFitter::fitSegment
SegmentFitResult fitSegment(const EventContext &ctx, HitVec &&calibHits, const Parameters &startPars, const Amg::Transform3D &localToGlobal) const
Definition: MdtSegmentFitter.cxx:365
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
MuonR4::SegmentFitResult::HitVec
std::vector< HitType > HitVec
Definition: SegmentFitterEventData.h:53
MuonR4::SegmentFit::ParamDefs::phi
@ phi
xAOD::UncalibMeasType::TgcStripType
@ TgcStripType
MuonR4::MdtSegmentFitter::Config::calibrator
const ISpacePointCalibrator * calibrator
Pointer to the calibrator tool.
Definition: MdtSegmentFitter.h:40
MuonR4::MdtSegmentFitter::ResidualAuxillaries::projDirLenSq
double projDirLenSq
Length squared of the projected direction.
Definition: MdtSegmentFitter.h:79
MuonR4::MdtSegmentFitter::ResidualWithPartials::gradient
std::array< Amg::Vector3D, nPars > gradient
First order derivatives.
Definition: MdtSegmentFitter.h:93
MuonR4::SegmentFitResult::nDoF
int nDoF
degrees of freedom
Definition: SegmentFitterEventData.h:68
MuonR4::MdtSegmentFitter::Config::ranges
RangeArray ranges
Definition: MdtSegmentFitter.h:48
MuonR4::SegmentFit::AxisDefs::phi
@ phi
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:235
MuonR4::SegmentFit::AxisDefs::t0
@ t0
MuonR4::MdtSegmentFitter::ResidualWithPartials::evalPhiPars
bool evalPhiPars
Flag whether the the residuals w.r.t phi shall be evaluated.
Definition: MdtSegmentFitter.h:97
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
MuonR4::MdtSegmentFitter::ResidualAuxillaries::invProjLenSq
double invProjLenSq
inverse squared of the unnormalized dir projection
Definition: MdtSegmentFitter.h:81
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
MuonR4::ISpacePointCalibrator::driftAcceleration
virtual double driftAcceleration(const EventContext &ctx, const CalibratedSpacePoint &spacePoint) const =0
Returns the drift acceleration for a given drift-circle space point.
MuonR4::MdtSegmentFitter::UpdateStatus::noChange
@ noChange
AthMessaging::msgLvl
bool msgLvl(const MSG::Level lvl) const
Test the output level.
Definition: AthMessaging.h:151
TrigVtx::gamma
@ gamma
Definition: TrigParticleTable.h:26
MuonR4::inverse
CalibratedSpacePoint::Covariance_t inverse(const CalibratedSpacePoint::Covariance_t &mat)
Inverts the parsed matrix.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:65
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
UtilFunctions.h
MuonR4::MdtSegmentFitter::MeasCov_t
CalibratedSpacePoint::Covariance_t MeasCov_t
Updates the chi2, its Gradient & Hessian from the measurement residual.
Definition: MdtSegmentFitter.h:163
SegmentFitHelperFunctions.h
AmgVector
AmgVector(4) T2BSTrackFilterTool
Definition: T2BSTrackFilterTool.cxx:114
Amg::x
@ x
Definition: GeoPrimitives.h:34
MuonR4::MdtSegmentFitter::HitType
std::unique_ptr< CalibratedSpacePoint > HitType
Definition: MdtSegmentFitter.h:23
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
MuonR4::SegmentFitResult::nTimeMeas
unsigned int nTimeMeas
How many measurements give time constaint.
Definition: SegmentFitterEventData.h:72
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:525
MuonR4::MdtSegmentFitter::Config
Definition: MdtSegmentFitter.h:26
MuonR4::CalibratedSpacePoint::State
State
State flag to distinguish different space point states.
Definition: CalibratedSpacePoint.h:24
MuonR4::MdtSegmentFitter::Config::useSecOrderDeriv
bool useSecOrderDeriv
Switch toggling whether the second order derivative shall be included.
Definition: MdtSegmentFitter.h:36
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
MuonR4::MdtSegmentFitter::Config::nParsOutOfBounds
unsigned int nParsOutOfBounds
Abort the fit as soon as more than n parameters leave the fit range.
Definition: MdtSegmentFitter.h:38
xAOD::Other
@ Other
MuonR4::SegmentFitResult::segmentPars
Parameters segmentPars
Final segment parameters.
Definition: SegmentFitterEventData.h:60
MuonR4::CalibratedSpacePoint::type
xAOD::UncalibMeasType type() const
Returns the space point type.
Definition: CalibratedSpacePoint.cxx:36
MuonR4::MdtSegmentFitter::ResidualAuxillaries::projIntoWirePlane
double projIntoWirePlane
projection of the segment direction along the wire
Definition: MdtSegmentFitter.h:77
MuonR4::SegmentFit::ParamDefs::x0
@ x0
MuonR4::MdtSegmentFitter::calculateWireResiduals
void calculateWireResiduals(const LineWithPartials &line, const CalibratedSpacePoint &spacePoint, ResidualWithPartials &residual) const
Calculates the residuals together with the corresponding derivatives for a drift-circle measurement.
Definition: MdtSegmentFitter.cxx:161
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
MuonR4::SegmentFit::AxisDefs::eta
@ eta
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
AthMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AthMessaging.h:164
compute_lumi.denom
denom
Definition: compute_lumi.py:76
MuonR4::SegmentFit::ParamDefs::time
@ time
MuonR4::CalibratedSpacePoint::State::Valid
@ Valid
MuonR4::MdtSegmentFitter::updateDerivatives
void updateDerivatives(const ResidualWithPartials &fitMeas, const MeasCov_t &measCovariance, AmgVector(5)&gradient, AmgSymMatrix(5)&hessian, double &chi2, int startPar) const
Definition: MdtSegmentFitter.cxx:578
lumiFormat.array
array
Definition: lumiFormat.py:91
MuonR4::MdtSegmentFitter::m_cfg
Config m_cfg
Definition: MdtSegmentFitter.h:111
MuonR4::SegmentFit::ParamDefs::y0
@ y0
MuonR4::MdtSegmentFitter::MdtSegmentFitter
MdtSegmentFitter(const std::string &name, Config &&config)
Standard constructor.
Definition: MdtSegmentFitter.cxx:51
MuonR4::MdtSegmentFitter::Config::nMaxCalls
unsigned int nMaxCalls
How many calls shall be executed.
Definition: MdtSegmentFitter.h:28
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
MuonR4::SegmentFit::toInt
constexpr int toInt(const ParamDefs p)
Definition: MuonHoughDefs.h:42
MuonR4::CalibratedSpacePoint::positionInChamber
const Amg::Vector3D & positionInChamber() const
The position of the calibrated space point inside the chamber.
Definition: CalibratedSpacePoint.cxx:21
MuonR4::MdtSegmentFitter::Config::reCalibrate
bool reCalibrate
Switch toggling whether the calibrator shall be called at each iteration.
Definition: MdtSegmentFitter.h:34
MuonR4::MdtSegmentFitter::UpdateStatus::allOkay
@ allOkay
MuonR4::SegmentFitResult::HitType
std::unique_ptr< CalibratedSpacePoint > HitType
Definition: SegmentFitterEventData.h:52
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:63
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonR4::MdtSegmentFitter::LineWithPartials
Store the partial derivative of the line w.r.t.
Definition: MdtSegmentFitter.h:54
Amg::dirFromAngles
Amg::Vector3D dirFromAngles(const double phi, const double theta)
Constructs a direction vector from the azimuthal & polar angles.
Definition: GeoPrimitivesHelpers.h:299
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
EventPrimitivesCovarianceHelpers.h
MuonR4::MdtSegmentFitter::Config::RangeArray
std::array< std::array< double, 2 >, SegmentFit::toInt(ParamDefs::nPars)> RangeArray
Allowed parameter ranges.
Definition: MdtSegmentFitter.h:44
MuonR4::SegmentFit::Covariance
AmgSymMatrix(toInt(ParamDefs::nPars)) Covariance
Definition: MuonHoughDefs.h:49
a
TList * a
Definition: liststreamerinfos.cxx:10
MdtSegmentFitter.h
MuonR4::CalibratedSpacePoint::dimension
unsigned dimension() const
Returns the local dimension of the measurement.
Definition: CalibratedSpacePoint.cxx:61
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MuonR4::MdtSegmentFitter::Config::doTimeFit
bool doTimeFit
Switch toggling whether the T0 shall be fitted or not.
Definition: MdtSegmentFitter.h:32
MuonR4::MdtSegmentFitter::HitVec
std::vector< HitType > HitVec
Definition: MdtSegmentFitter.h:24
MuonR4::SegmentFitResult::timeFit
bool timeFit
Was the time fitted.
Definition: SegmentFitterEventData.h:56
MuonR4::CalibratedSpacePoint
The calibrated Space point is created during the calibration process.
Definition: CalibratedSpacePoint.h:15
MuonR4::SegmentFitResult::nPhiMeas
unsigned int nPhiMeas
How many phi measurements.
Definition: SegmentFitterEventData.h:70
CxxUtils::sincos
Helper to simultaneously calculate sin and cos of the same angle.
Definition: sincos.h:39
Muon::IMuonIdHelperSvc
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
Definition: IMuonIdHelperSvc.h:27
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::MdtSegmentFitter::ResidualAuxillaries::projDir
Amg::Vector3D projDir
projection of the segment direction onto the wire planes
Definition: MdtSegmentFitter.h:71
python.SystemOfUnits.ns
int ns
Definition: SystemOfUnits.py:130
MuonR4::SegmentFitResult
Definition: SegmentFitterEventData.h:46
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
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::MdtSegmentFitter::Config::defaultRanges
static RangeArray defaultRanges()
Function that returns a set of predefined ranges for testing.
Definition: MdtSegmentFitter.cxx:40
MuonR4::AmgSymMatrix
const AmgSymMatrix(2) &SpacePoint
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:150
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
MuonR4::MdtSegmentFitter::recalibrate
bool recalibrate(const EventContext &ctx, SegmentFitResult &fitResult) const
Recalibrate the measurements participating in the fit & shift them into the centre-of gravity frame.
Definition: MdtSegmentFitter.cxx:62
MuonR4::MdtSegmentFitter::updateParameters
UpdateStatus updateParameters(Parameters &currentPars, Parameters &previousPars, Parameters &currGrad, Parameters &prevGrad, const AmgSymMatrix(5)&hessian) const
Update step of the segment parameters using the Hessian and the gradient.
Definition: MdtSegmentFitter.cxx:616
MuonR4::MdtSegmentFitter::ResidualWithPartials::hessian
std::array< Amg::Vector3D, sumUp(nPars)> hessian
Second order derivatives.
Definition: MdtSegmentFitter.h:95
MuonR4::CalibratedSpacePoint::directionInChamber
const Amg::Vector3D & directionInChamber() const
The direction of the calibrated space point inside the chamber.
Definition: CalibratedSpacePoint.cxx:24
MuonR4::SegmentFit::ParamDefs::nPars
@ nPars
xAOD::UncalibMeasType::RpcStripType
@ RpcStripType
MuonR4::HitType
SegmentFitResult::HitType HitType
Definition: MdtSegmentFitter.cxx:36
MuonR4::CalibratedSpacePoint::driftRadius
double driftRadius() const
The drift radius of the calibrated space point.
Definition: CalibratedSpacePoint.cxx:27
xAOD::UncalibMeasType::MdtDriftCircleType
@ MdtDriftCircleType
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:26
MuonR4::SegmentFit::ParamDefs::theta
@ theta
fitman.k
k
Definition: fitman.py:528
MuonR4::MdtSegmentFitter::updateLinePartials
static void updateLinePartials(const Parameters &fitPars, LineWithPartials &line)
Updates the line parameters together with its first & second order partial derivatives.
Definition: MdtSegmentFitter.cxx:119
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