10#include "GaudiKernel/MsgStream.h"
28 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
"fit() New seg:" <<
endmsg;
32 if (N < 2) {
return false; }
39 for (
int i = 0; i < N; ++i) {
43 log << MSG::WARNING <<
"fit() TO FEW HITS SELECTED" <<
endmsg;
50 double S(0), Sy(0), Sz(0), Zc{0}, Yc{0};
51 std::vector<double>
y(N),
x(N),
z(N);
52 std::vector<double>
r(N), sr(N), w(N), rw(N);
57 y[ii] =
getY(
h.localPosition());
58 z[ii] =
getZ(
h.localPosition());
59 r[ii] = std::abs(
h.driftRadius());
61 if (
h.sigma2DriftRadius() > 0) {
62 w[ii] = 1. / (
h.sigma2DriftRadius());
63 sr[ii] = std::sqrt(
h.sigma2DriftRadius());
68 if (log.level() <= MSG::DEBUG)
69 log << MSG::DEBUG <<
"fit() MuCCaFitter: (" <<
x[ii] <<
"," <<
y[ii] <<
") R = " <<
r[ii] <<
" W " << w[ii] <<
endmsg;
70 rw[ii] =
r[ii] * w[ii];
83 log << MSG::ERROR <<
"Divisor S is zero."<<
endmsg;
89 std::unique_ptr<MuCCaFitterImplementation> Fitter = std::make_unique<MuCCaFitterImplementation>();
90 if (log.level() <= MSG::DEBUG) {
91 for (
int i = 0; i != ii; i++) {
92 log << MSG::DEBUG <<
"fit() MuCCaFitter hits passed to computepam Z=" <<
x[i] <<
" phi=" <<
y[i] <<
" zzz=" <<
z[i]
93 <<
" drift=" <<
r[i] <<
" error=" << w[i] <<
endmsg;
96 Fitter->Computeparam3(ii,
z,
y,
r, sr);
97 if (log.level() <= MSG::DEBUG) {
98 log << MSG::DEBUG <<
"fit() MuCCaFitter computed track a=" << Fitter->get_a() <<
" da= " << Fitter->get_da()
99 <<
" b= " << Fitter->get_b() <<
" db= " << Fitter->get_db() <<
" corrab= " << Fitter->get_corrab()
100 <<
" chi2f= " << Fitter->get_chi2f() <<
endmsg;
103 double afit = Fitter->get_a();
104 double chi2f = Fitter->get_chi2f();
106 std::vector<double> dist(N), ddist(N);
108 double theta = std::atan(afit);
110 double sinus = std::sin(
theta);
111 double cosin = std::cos(
theta);
112 double d = -(
getZ(pos) - Zc) * sinus + (
getY(pos) - Yc) * cosin;
113 if (log.level() <= MSG::DEBUG) {
114 log << MSG::DEBUG <<
"fit() MuCCaFitter>>> theta= " <<
theta <<
" sinus= " << sinus <<
" cosin= " << cosin <<
endmsg;
115 log << MSG::DEBUG <<
"fit() MuCCaFitter>>> getZ( pos )= " <<
getZ(pos) <<
" getY( pos )= " <<
getY(pos) <<
" Zc= " << Zc
116 <<
" Yc= " << Yc <<
endmsg;
118 double Syy(0), Szy(0), Syyzz(0), Att(0);
120 for (
int i = 0; i < N; ++i) {
122 Syy += (
y[i] - Yc) * (
y[i] - Yc) * w[i];
123 Szy += (
y[i] - Yc) * (
z[i] - Zc) * w[i];
124 Syyzz += ((
y[i] - Yc) - (
z[i] - Zc)) * ((
y[i] - Yc) + (
z[i] - Zc)) * w[i];
125 dis = (
y[i] - Yc) * cosin - (
z[i] - Zc) * sinus;
132 Att = Syy + cosin * (2 * sinus * Szy - cosin * Syyzz);
134 if (log.level() <= MSG::DEBUG){
135 log << MSG::DEBUG <<
"fit() MuCCaFitter>>> d= " << d <<
" R= " << R <<
" S= " << S <<
" Att= " << Att <<
endmsg;
138 log << MSG::ERROR <<
"Divisor Att is zero."<<
endmsg;
141 for (
int i = 0; i < N; ++i) {
143 dist[i] = cosin * (
y[i] - Yc) - sinus * (
z[i] - Zc) - d;
144 double dth = -(sinus * (
y[i] - Yc) + cosin * (
z[i] - Zc)) * (std::sqrt(1. / Att));
145 ddist[i] = std::sqrt(dth * dth + (1. / S));
147 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
"fit() Transforming back to real world" <<
endmsg;
151 if (log.level() <= MSG::DEBUG)
152 log << MSG::DEBUG <<
"fit() New line: position " << npos <<
" direction " << ndir <<
" chi2f " << chi2f <<
endmsg;
154 seg.
set(chi2f / (N - 2), npos, ndir);
158 hit_ptr->setDistanceToTrack(dist[i], ddist[i]);
162 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
"fit() fit done" <<
endmsg;
166 const std::vector<double>& sr) {
170 double xout[100], yout[100];
171 double dist[100], rsub[100];
172 double chi2outn[4], chi2min;
173 double aref[4], bref[4];
174 int fhit, i, j, icouple = 0, lhit;
177 lhit = number_of_hits - 1;
179 for (
int ii = 0; ii < 4; ii++) {
184 for (i = 0; i < 4; i++) {
185 for (j = 0; j < number_of_hits; j++) {
187 d = std::abs(aref[i] *
x[j] + bref[i] -
y[j]);
188 dist[j] = d / std::sqrt(1. + aref[i] * aref[i]);
189 rsub[j] =
r[j] - dist[j];
192 for (
int ii = 1; ii < number_of_hits - 1; ii++) { chi2out += rsub[ii] * rsub[ii] / (sr[ii] * sr[ii]); }
193 chi2outn[i] = chi2out;
195 chi2min = 999999999.;
196 for (i = 0; i < 4; i++) {
197 if (chi2outn[i] < chi2min) {
198 chi2min = chi2outn[i];
204 for (i = 0; i < number_of_hits; i++) {
211 double aoutn, bout, sig2a, sig2b, corrab;
214 double W, WX, WX2, WY, WXY;
221 for (
int i = 0; i < number_of_hits; i++) {
222 temp = 1. / (sr[i] * sr[i]);
224 WX += xout[i] * temp;
225 WX2 += xout[i] * xout[i] * temp;
226 WY += yout[i] * temp;
227 WXY += xout[i] * yout[i] * temp;
229 det = W * WX2 - WX * WX;
230 aoutn = (W * WXY - WY * WX) / det;
231 bout = (WY * WX2 - WX * WXY) / det;
238 hesse[1][1] = hesse[0][0] / det;
239 hesse[0][0] = hesse[1][1] / det;
240 hesse[1][0] = -1. * (hesse[0][1] / det);
241 hesse[0][1] = -1. * (hesse[0][1] / det);
244 corrab = hesse[1][0];
245 double deno, btest, bs1, bs2, db1, db2;
249 for (
int i = 0; i < number_of_hits; i++) {
250 bs1 = (
y[i] - aoutn *
x[i] -
r[i] * std::sqrt(1 + aoutn * aoutn));
251 bs2 = (
y[i] - aoutn *
x[i] +
r[i] * std::sqrt(1 + aoutn * aoutn));
252 db1 = std::abs(bs1 - btest);
253 db2 = std::abs(bs2 - btest);
255 bout += bs1 / (sr[i] * sr[i]);
257 bout += bs2 / (sr[i] * sr[i]);
259 deno += 1 / (sr[i] * sr[i]);
265 for (
int i = 0; i < number_of_hits; i++) {
267 xi = (aoutn *
y[i] - aoutn * bout +
x[i]) / (1. + aoutn * aoutn);
268 yi = aoutn * xi + bout;
269 resd = (std::sqrt((xi -
x[i]) * (xi -
x[i]) + (yi -
y[i]) * (yi -
y[i])) -
r[i]) / sr[i];
270 chi2f += resd * resd;
293 double averagephi, dist, dphiin, dphiex;
295 std::array<double, 2> bfparn{};
299 int ncandid[4], ncand;
301 int segnob[] = {1, -1, 1, -1};
303 double angularcoefficient[4];
311 averagephi = std::atan2(dy, dx);
312 dist = std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
315 dphiin = std::asin(delta / dist);
318 dphiex = std::asin(delta / dist);
321 phi = averagephi + f * dphiex;
323 angularcoefficient[0] = std::tan(
phi);
326 phi = averagephi + f * dphiex;
328 angularcoefficient[1] = std::tan(
phi);
331 phi = averagephi + f * dphiin;
333 angularcoefficient[2] = std::tan(
phi);
336 phi = averagephi + f * dphiin;
338 angularcoefficient[3] = std::tan(
phi);
341 for (i = 0; i < 4; i++) {
342 bpar[0] = y1 - angularcoefficient[i] * x1 + segnob[0] * r1 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
343 bpar[1] = y1 - angularcoefficient[i] * x1 + segnob[1] * r1 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
344 bpar[2] = y2 - angularcoefficient[i] * x2 + segnob[2] * r2 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
345 bpar[3] = y2 - angularcoefficient[i] * x2 + segnob[3] * r2 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
346 double delta = 0.00001;
348 if (std::abs(bpar[0] - bpar[2]) < delta) {
349 bfparn.at(ncand) = bpar[0];
352 if (std::abs(bpar[0] - bpar[3]) < delta) {
353 bfparn.at(ncand) = bpar[0];
356 if (std::abs(bpar[1] - bpar[2]) < delta) {
357 bfparn.at(ncand) = bpar[1];
360 if (std::abs(bpar[1] - bpar[3]) < delta) {
361 bfparn.at(ncand) = bpar[1];
364 bcand[0][i] = bfparn[0];
365 bcand[1][i] = bfparn[1];
369 for (i = 0; i < 4; i++) {
370 if (ncandid[i] == 1) {
371 bfpar[i] = bcand[0][i];
373 bfpar[i] = bcand[firsttime][i];
378 for (i = 0; i < 4; i++) {
388 double delta{0}, averagephi{0}, dist{0}, dphiin{0}, dphiex{0};
389 double bpar[4],
phi{0};
390 std::array<double, 2> bfparn{};
392 int segnob[] = {1, -1, 1, -1};
393 int ncandid[4], ncand;
394 int i{0}, firsttime{0};
395 double angularcoefficient[4];
402 averagephi = std::atan2(dy, dx);
403 dist = std::hypot(dx, dy);
406 dphiin = std::asin(delta / dist);
409 dphiex = std::asin(delta / dist);
412 phi = averagephi + f * dphiex;
414 angularcoefficient[0] = std::tan(
phi);
417 phi = averagephi + f * dphiex;
419 angularcoefficient[1] = std::tan(
phi);
422 phi = averagephi + f * dphiin;
424 angularcoefficient[2] = std::tan(
phi);
427 phi = averagephi + f * dphiin;
429 angularcoefficient[3] = std::tan(
phi);
432 for (i = 0; i < 4; i++) {
433 bpar[0] = y1 - angularcoefficient[i] * x1 + segnob[0] * r1 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
434 bpar[1] = y1 - angularcoefficient[i] * x1 + segnob[1] * r1 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
435 bpar[2] = y2 - angularcoefficient[i] * x2 + segnob[2] * r2 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
436 bpar[3] = y2 - angularcoefficient[i] * x2 + segnob[3] * r2 * std::sqrt(1 + angularcoefficient[i] * angularcoefficient[i]);
437 double delta = 0.00001;
439 if (std::abs(bpar[0] - bpar[2]) < delta) {
440 bfparn.at(ncand) = bpar[0];
443 if (std::abs(bpar[0] - bpar[3]) < delta) {
444 bfparn.at(ncand) = bpar[0];
447 if (std::abs(bpar[1] - bpar[2]) < delta) {
448 bfparn.at(ncand) = bpar[1];
451 if (std::abs(bpar[1] - bpar[3]) < delta) {
452 bfparn.at(ncand) = bpar[1];
455 bcand[0][i] = bfparn[0];
456 bcand[1][i] = bfparn[1];
460 for (i = 0; i < 4; i++) {
461 if (ncandid[i] == 1) {
462 bfpar[i] = bcand[0][i];
464 bfpar[i] = bcand[firsttime][i];
469 for (
int i = 0; i < 4; i++) {
475 const std::vector<double>& rcirc,
double a,
double b) {
483 for (i = 0; i < nhitc; i++) {
485 computehitsfromcircles(xcirc[2 * i], ycirc[2 * i], rcirc[2 * i], xcirc[2 * i + 1], ycirc[2 * i + 1], rcirc[2 * i + 1],
a, b);
491 if (2 * nhitc != nhit) {
493 computehitsfromcircles(xcirc[nhit - 2], ycirc[nhit - 2], rcirc[nhit - 2], xcirc[nhit - 1], ycirc[nhit - 1], rcirc[nhit - 1],
a,
507 double ang[4], bpar[4];
509 double xout0 = 0, yout0 = 0;
510 double xout1 = 0, yout1 = 0;
511 double dist, dist1, xint, yint, xref, yref;
515 for (i = 0; i < 4; i++) {
522 for (i = 0; i < 4; i++) {
524 xint = (x0 + ang[i] * y0 - ang[i] * bpar[i]) / (1 + ang[i] * ang[i]);
525 yint = ang[i] * (xint) + bpar[i];
529 bprime = y0 + x0 /
a;
530 xref = (bprime - b) *
a / (
a *
a + 1);
531 yref = (b + bprime *
a *
a) / (
a *
a + 1);
537 dist1 = std::sqrt((xint - xref) * (xint - xref) + (yint - yref) * (yint - yref));
545 for (i = 0; i < 4; i++) {
547 xint = (x1 + ang[i] * y1 - ang[i] * bpar[i]) / (1 + ang[i] * ang[i]);
548 yint = ang[i] * (xint) + bpar[i];
552 bprime = y1 + x1 /
a;
553 xref = (bprime - b) *
a / (
a *
a + 1);
554 yref = (b + bprime *
a *
a) / (
a *
a + 1);
560 dist1 = std::sqrt((xint - xref) * (xint - xref) + (yint - yref) * (yint - yref));
Scalar phi() const
phi method
Scalar theta() const
theta method
Header file for AthHistogramAlgorithm.
std::vector< unsigned int > HitSelection
Athena-independent part of the MdtCalibHit.
void Computeparam3(int number_of_hits, const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &r, const std::vector< double > &sr)
void Computelinparnew(double x1, double y1, double r1, double x2, double y2, double r2)
double m_bout
track constant term
double m_angularcoefficient[4]
parameters of the 4 tangent lines from first and last hit
void computehitsfromcircles(double x0, double y0, double r0, double x1, double y1, double r1, double a, double b)
double m_xpoint[100]
track points
double m_xout0
track points from 2 circles
void Computelin(double x1, double y1, double r1, double x2, double y2, double r2)
double m_sig2b
error on track constant term
double m_sig2a
track slope's variance
double m_corrab
correlation term
void Computehitpsemes(int nhit, const std::vector< double > &xcirc, const std::vector< double > &ycirc, const std::vector< double > &rcirc, double a, double b)
bool fit(MuonCalibSegment &seg) const
fit using all hits
void printLevel(int level)
set print level
Amg::Vector3D getVec(double x, double y, double z) const
double getZ(const Amg::Vector3D &p) const
double getY(const Amg::Vector3D &p) const
these methods are needed to change the reference frame between the local one of the hit and one used ...
A MuonCalibSegment is a reconstructed three dimensional track segment in the MuonSpectrometer.
unsigned int mdtHitsOnTrack() const
retrieve the number of MdtCalibHitBase s assigned to this segment
std::shared_ptr< MdtCalibHitBase > MdtHitPtr
typedef for a collection of MdtCalibHitBase s
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)
holding In fact this class is here in order to allow STL container for all features This class is sho...
const std::string selection
singleton-like access to IMessageSvc via open function and helper
Eigen::Matrix< double, 3, 1 > Vector3D
IMessageSvc * getMessageSvc(bool quiet=false)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.