51 const std::vector<const Trk::PrepRawData*>& unassociatedHits)
const
55 int time_start = std::clock() / 1000;
57 std::vector<std::unique_ptr<const Trk::MeasurementBase>> selectedHits{}, selectedClusters{};
61 int nhits = associatedHits.size() + unassociatedHits.size();
63 ATH_MSG_DEBUG(
"Executing MuonPhiHitSelectorTool nhits select_rio " << nhits);
65 std::vector<double> phiHitx(nhits);
66 std::vector<double> phiHity(nhits);
67 std::vector<double> phiHitz(nhits);
68 std::vector<double> phiError(nhits);
69 std::vector<Identifier> phiId(nhits);
70 std::vector<double> phiPull(nhits);
71 std::vector<int> phiSelect(nhits);
72 std::vector<int> phiMult(nhits);
73 std::vector<int> quality(nhits);
74 std::vector<const Trk::PrepRawData*> phiPrep(nhits);
76 std::map<Identifier, int> phiMapId;
90 phiHitx[nphi] = gHitPos.x();
91 phiHity[nphi] = gHitPos.y();
92 phiHitz[nphi] = gHitPos.z();
95 double error = cov(0, 0);
100 Er(0, 0) = cov(0, 0);
101 Er(0, 1) = cov(0, 1);
102 Er(1, 1) = cov(1, 1);
105 double chi = Er(0, 0) != Er(1, 1) ? std::atan(-2 * Er(0, 1) / (Er(0, 0) - Er(1, 1))) / 2. : 0.;
110 Rot(0, 0) = scchi.
cs;
111 Rot(1, 1) = Rot(0, 0);
112 Rot(0, 1) = scchi.
sn;
113 Rot(1, 0) = -Rot(0, 1);
114 AmgMatrix(2, 2) D = Rot.transpose() * Er * Rot;
116 error = std::min(D(0, 0),D(1, 1));
118 phiError[nphi] = std::sqrt(
error);
119 quality[nphi] = 1000;
121 phiPrep[nphi] = rot->prepRawData();
122 double phipos = std::atan2(phiHity[nphi], phiHitx[nphi]);
123 ATH_MSG_DEBUG(
"phi Segment Hit " << nphi <<
" det " << phiSelect[nphi] <<
" phi " << phipos);
132 if (phiMapId.count(
id))
continue;
142 phiHitx[nphi] = gHitPos.x();
143 phiHity[nphi] = gHitPos.y();
144 phiHitz[nphi] = gHitPos.z();
145 phiError[nphi] = prd->localCovariance()(
Trk::locX);
148 double phipos = std::atan2(phiHity[nphi], phiHitx[nphi]);
149 ATH_MSG_DEBUG(
"phi Pattern Hit " << nphi <<
" phi " << phipos);
156 std::vector<double> errorM(4);
158 fitRecPhi(pmom, phiId, phiHitx, phiHity, phiHitz, phiError, quality, nphi, phiPull, phiMult, phiSelect,
chi2, r0,
163 for (
int i = 0; i < nphi; ++i) {
164 if (phiSelect[i] > 0) {
165 if (phiSelect[i] == 1) {
167 const Amg::Vector3D globalpos(phiHitx[i], phiHity[i], phiHitz[i]);
168 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
169 if (rio) selectedHits.push_back(std::move(rio));
170 }
else if (phiSelect[i] == 2) {
172 const Amg::Vector3D globalpos(phiHitx[i], phiHity[i], phiHitz[i]);
173 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
174 if (rio) selectedHits.push_back(std::move(rio));
175 }
else if (phiSelect[i] == 3) {
177 const Amg::Vector3D globalpos(phiHitx[i], phiHity[i], phiHitz[i]);
178 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_cscRotCreator->createRIO_OnTrack(*prd, globalpos)};
179 if (rio) selectedHits.push_back(std::move(rio));
186 <<
" pattern hits " << nphi - nphiseg <<
" nfit " << nfit <<
" rio size "
187 << selectedHits.size());
190 std::vector<double> clusterX(nphi);
191 std::vector<double> clusterY(nphi);
192 std::vector<double> clusterZ(nphi);
193 std::vector<double> clusterError(nphi);
194 std::vector<Identifier> clusterId(nphi);
195 std::vector<int> clusterHits(nphi);
196 std::vector<double> clusterPull(nphi);
197 std::vector<int> clusterSelect(nphi);
199 std::vector<int> clusterInt(nphi);
202 double chi2cl, r0cl, phicl;
203 std::vector<double> errorMcl(4);
204 clusterPhi(phiId, phiHitx, phiHity, phiHitz, phiError, phiPull, phiSelect, nphi, clusterX, clusterY, clusterZ,
205 clusterError, clusterId, clusterHits, clusterSelect, clusterInt, ncl);
208 for (
int ic = 0; ic < ncl; ++ic) {
209 std::list<const Trk::PrepRawData*> prdList;
214 for (
int i = 0; i < nphi; ++i) {
215 if (clusterInt[i] == ic) {
217 prdList.push_back(phiPrep[i]);
218 avError += 1. / (phiError[i] * phiError[i]);
219 if (clusterId[ic] == phiId[i]) iic = i;
224 ATH_MSG_DEBUG(
"Phi cluster found np " << np <<
" ip " << ip);
227 const Amg::Vector3D globalpos(clusterX[ic], clusterY[ic], clusterZ[ic]);
228 if (phiSelect[ip] == 1) {
231 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
232 if (rio) selectedClusters.push_back(std::move(rio));
233 }
else if (phiSelect[ip] == 2) {
236 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
237 if (rio) selectedClusters.push_back(std::move(rio));
238 }
else if (phiSelect[ip] == 3) {
241 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_cscRotCreator->createRIO_OnTrack(*prd, globalpos)};
242 if (rio) selectedClusters.push_back(std::move(rio));
248 avError = std::sqrt(1. / avError);
249 double scaleFactor = clusterError[ic] / avError;
250 std::unique_ptr<const Trk::CompetingRIOsOnTrack> rio =
252 selectedClusters.push_back(std::move(rio));
255 <<
" scale factor " << scaleFactor <<
" number of rios " << prdList.size());
259 const Amg::Vector3D globalpos(clusterX[ic], clusterY[ic], clusterZ[ic]);
260 if (phiSelect[ip] == 1) {
263 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
264 if (rio) selectedClusters.push_back(std::move(rio));
265 }
else if (phiSelect[ip] == 2) {
268 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
269 if (rio) selectedClusters.push_back(std::move(rio));
270 }
else if (phiSelect[ip] == 3) {
273 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
274 if (rio) selectedClusters.push_back(std::move(rio));
283 fitPhiSL(pmom, clusterId, clusterX, clusterY, clusterZ, clusterError, clusterSelect, ncl, clusterPull,
imax, chi2cl,
284 r0cl, phicl, errorMcl,
false);
288 ATH_MSG_DEBUG(
"PhiHitSelector Time spent " << std::clock() / 1000 - time_start <<
" nhits " << nhits
289 <<
" segment hits " << associatedHits.size() <<
" nfit " << nfit
290 <<
" nclusters " << ncl);
291 ATH_MSG_DEBUG(
"Fit cluster results phi " << phicl <<
" chi2 " << chi2cl <<
" number of clusters " << ncl
292 <<
" size cluster Hits " << selectedClusters.size());
295 return selectedClusters;
303 const std::vector<double>& hity,
const std::vector<double>& hitz,
304 const std::vector<double>&
error,
const std::vector<double>& pull,
305 std::vector<int>& select,
const int n, std::vector<double>& clusterX,
306 std::vector<double>& clusterY, std::vector<double>& clusterZ,
307 std::vector<double>& clusterError, std::vector<Identifier>& clusterId,
308 std::vector<int>& clusterHits, std::vector<int>& clusterSelect,
309 std::vector<int>& clusterInt,
int& ncl)
const
340 std::vector<int> scode(n);
342 for (
int i = 0; i < n; ++i) {
348 code = 100000000 * (
m_idHelperSvc->rpcIdHelper().stationName(idi))
350 + 10000 * ((
m_idHelperSvc->rpcIdHelper().stationEta(idi)) + 1000);
351 code += 1000 * (doubZ - 1) + 100 * (doubPhi - 1);
352 code += 2 * ((
m_idHelperSvc->rpcIdHelper().doubletR(idi)) - 1)
355 code = 1000000 * (
m_idHelperSvc->tgcIdHelper().stationName(idi))
357 + 100 * ((
m_idHelperSvc->tgcIdHelper().stationEta(idi)) + 10);
360 code = 1000000 * (
m_idHelperSvc->cscIdHelper().stationName(idi))
362 + 100 * ((
m_idHelperSvc->cscIdHelper().stationEta(idi)) + 10);
370 for (
int i = 0; i < n; ++i) {
375 for (
int i = 0; i < n; ++i) {
376 if (
error[i] != 0 && select[i] > 0 && clusterInt[i] == -1) {
379 for (
int j = i + 1; j < n; ++j) {
380 if (clusterInt[j] == -1) {
381 if (
error[j] != 0 && select[j] > 0) {
382 if (scode[i] == scode[j]) clusterInt[j] = icl;
389 std::vector<double> clusterCommon2Error(icl + 1);
390 std::vector<int> clusterCode(icl + 1);
392 for (
int ic = 0; ic < icl + 1; ++ic) {
396 clusterError[ic] = 0.;
397 clusterCommon2Error[ic] = 0.;
400 clusterSelect[ic] = 0;
401 double pullMax = 10.;
402 for (
int i = 0; i < n; ++i) {
404 if (ic == clusterInt[i]) {
405 clusterSelect[ic] = select[i];
407 clusterX[ic] += hitx[i] * w;
408 clusterY[ic] += hity[i] * w;
409 clusterZ[ic] += hitz[i] * w;
410 clusterError[ic] += w;
411 if (std::abs(pull[i]) < std::abs(pullMax)) {
413 clusterId[ic] =
id[i];
414 clusterCode[ic] = scode[i];
415 clusterSelect[ic] = select[i];
418 if (clusterHits[ic] == 1) clusterCommon2Error[ic] = 0.;
422 clusterX[ic] = clusterX[ic] / clusterError[ic];
423 clusterY[ic] = clusterY[ic] / clusterError[ic];
424 clusterZ[ic] = clusterZ[ic] / clusterError[ic];
426 clusterError[ic] = std::sqrt(clusterHits[ic]) / std::sqrt(clusterError[ic]);
428 ATH_MSG_DEBUG(
"cluster phi " << ic <<
" x " << clusterX[ic] <<
" y " << clusterY[ic] <<
" z "
429 << clusterZ[ic] <<
" error " << clusterError[ic] <<
" hits " << clusterHits[ic]
430 <<
" select " << clusterSelect[ic] <<
" Code " << clusterCode[ic]);
436 const std::vector<double>& phiHitx,
const std::vector<double>& phiHity,
437 const std::vector<double>& phiHitz,
const std::vector<double>& phiError,
438 std::vector<int>& quality,
const int nphi, std::vector<double>& phiPull,
439 std::vector<int>& phiMult, std::vector<int>& phiSelect,
double&
chi2,
double& r0,
440 double&
phi, std::vector<double>& errorM,
int& nfit)
const
459 if (nphi == 0)
return;
461 std::vector<double> error0(nphi);
462 std::vector<double>
error(nphi);
463 std::vector<double> errorf(nphi);
464 std::vector<int> scode(nphi);
465 std::vector<int> srcode(nphi);
466 std::vector<int> phiSelectKeep(nphi);
467 std::map<int, int> clusters;
468 std::map<int, int> clustersr;
469 std::map<int, int> clusterspat;
471 for (
int i = 0; i < nphi; ++i) {
477 code = 1000000 * (
m_idHelperSvc->rpcIdHelper().stationName(idi))
479 + 100 * ((
m_idHelperSvc->rpcIdHelper().stationEta(idi)) + 10);
480 code = code + 2 * ((
m_idHelperSvc->rpcIdHelper().doubletR(idi)) - 1)
482 rcode = 1000000 * (
m_idHelperSvc->rpcIdHelper().stationName(idi))
485 rcode = rcode + 2 * ((
m_idHelperSvc->rpcIdHelper().doubletR(idi)) - 1)
488 code = 1000000 * (
m_idHelperSvc->tgcIdHelper().stationName(idi))
490 + 100 * ((
m_idHelperSvc->tgcIdHelper().stationEta(idi)) + 10);
492 rcode = 1000000 * (
m_idHelperSvc->tgcIdHelper().stationName(idi))
497 code = 1000000 * (
m_idHelperSvc->cscIdHelper().stationName(idi))
499 + 100 * ((
m_idHelperSvc->cscIdHelper().stationEta(idi)) + 10);
501 rcode = 1000000 * (
m_idHelperSvc->cscIdHelper().stationName(idi))
517 phiSelectKeep[i] = idet;
520 for (
int i = 0; i < nphi; ++i) {
521 if (phiError[i] != 0 && quality[i] > 100) {
522 clusters[scode[i]]++;
523 clustersr[srcode[i]]++;
529 for (
int i = 0; i < nphi; ++i) {
530 if (phiError[i] != 0 && quality[i] > 0 && quality[i] < 100) {
531 if (clustersr.count(srcode[i]) > 0) {
534 clusterspat[scode[i]]++;
541 ATH_MSG_DEBUG(
"phi hits " << nphi <<
" segment clusters " << clusters.size() <<
" pattern clusters "
542 << clusterspat.size());
544 for (
int i = 0; i < nphi; ++i) {
548 if (phiError[i] != 0 && quality[i] > 0) {
550 if (quality[i] > 100) {
551 n = clusters[scode[i]];
553 if (n > 10) quality[i] = 10;
554 }
else if (quality[i] < 100) {
555 n = clusterspat[scode[i]];
557 if (clusters.count(scode[i]) == 1 || n > 10) {
562 phiSelectKeep[i] = 0;
575 error0[i] = phiError[i] * std::sqrt(n) * fact;
576 error[i] = phiError[i] * std::sqrt(n) * fact;
577 double phiHit = std::atan2(phiHity[i], phiHitx[i]);
579 ATH_MSG_DEBUG(i <<
" Station " <<
int(scode[i] / 1000000) <<
" Hit x " << phiHitx[i] <<
" Hit y "
580 << phiHity[i] <<
" Hit z " << phiHitz[i] <<
" error " << phiError[i] <<
" phi Hit "
583 ATH_MSG_DEBUG(
"code " << scode[i] <<
" multiplicity " << n <<
" error " << error0[i] <<
" quality "
593 for (
int i = 0; i < nphi; ++i) {
594 if (phiError[i] != 0 && quality[i] > 0) {
599 int allLayerRecoHits = 0;
600 double pfit = 20000.;
602 for (
int iqua = 0; iqua < 3; ++iqua) {
607 else if (iqua == 2) {
612 ATH_MSG_DEBUG(
"Quality loop " << iqua <<
" quality cut " << quacut);
615 for (
int i = 0; i < nphi; ++i) {
617 if (iqua == 1) phiSelect[i] = phiSelectKeep[i];
619 if (phiError[i] != 0 && quality[i] > quacut) {
621 if (quality[i] > 100) nselseg++;
622 if (quality[i] == 10 && iqua == 1) quality[i] = 11;
627 ATH_MSG_DEBUG(
"index i " << i <<
" phiSelect " << phiSelect[i] <<
" Quality " << quality[i] <<
" error "
632 if (iqua == 1 && nselseg > 0) {
634 double errorScaleFactor = 25.;
635 std::vector<int> phiPatSelect(nphi, 0);
636 for (
int i = 0; i < nphi; ++i) {
638 if (phiSelect[i] > 0 && quality[i] > 0 && quality[i] < 100) {
643 ATH_MSG_DEBUG(
"select " << phiSelect[i] <<
" quality " << quality[i] <<
" error " <<
error[i]);
645 ATH_MSG_DEBUG(
"performing outlier removal for pattern hits ");
646 fitPhiSL(pfit, phiId, phiHitx, phiHity, phiHitz,
error, phiSelect, nphi, phiPull,
imax,
chi2, r0,
phi,
648 for (
int i = 0; i < nphi; ++i) {
649 if (phiPatSelect[i] == 1) {
651 double rescaledPull = phiPull[i] * errorScaleFactor;
653 if (std::abs(rescaledPull) < 3.) {
654 phiSelect[i] = phiSelectKeep[i];
657 phiSelectKeep[i] = 0;
660 << i <<
" quality " << quality[i] <<
" Pull " << rescaledPull <<
" phiSelect "
667 const double pfitc = pfit;
672 std::vector<int> phiReSelect(nphi);
673 for (
int i = 0; i < nphi; ++i) {
674 ATH_MSG_DEBUG(
"select " << phiSelect[i] <<
" quality " << quality[i]);
676 if (phiSelect[i] == 0 && quality[i] > 99) {
678 phiSelect[i] = phiSelectKeep[i];
682 fitPhiSL(pfitc, phiId, phiHitx, phiHity, phiHitz,
error, phiSelect, nphi, phiPull,
imax,
chi2, r0,
phi,
684 for (
int i = 0; i < nphi; ++i) {
685 if (phiReSelect[i] == 1) {
688 if (std::abs(phiPull[i]) < 1) {
689 phiSelect[i] = phiSelectKeep[i];
695 << i <<
" quality " << quality[i] <<
" Pull " << phiPull[i] <<
" phiSelect "
702 for (
int i = 0; i < nphi; ++i) {
703 errorf[i] =
error[i];
704 if (iqua == 1) phiSelect[i] = phiSelectKeep[i];
706 if (phiError[i] != 0 && quality[i] > quacut) {
708 if (quality[i] == 10 && iqua == 1) quality[i] = 11;
714 ATH_MSG_DEBUG(
"Selected PHI hits in fit " << nsel <<
" iqua " << iqua);
715 if (nsel == 0)
continue;
720 for (
int iter = 0; iter < 100; ++iter) {
722 double power = (iter - 10) / 20.;
723 if (power < 0.) power = 0.;
728 for (
int i = 0; i < nphi; ++i) {
729 errorf[i] =
error[i] * std::pow(phiMult[i], power);
732 fitPhiSL(pfitc, phiId, phiHitx, phiHity, phiHitz, errorf, phiSelect, nphi, phiPull,
imax,
chi2, r0,
phi,
741 std::map<int, int> layersRecoHit;
743 for (
int i = 0; i < nphi; ++i) {
745 if (
error[i] == 0 || quality[i] < quacut) phiSelect[i] = 0;
746 if (
error[i] != 0 && quality[i] > quacut) {
747 layersRecoHit[srcode[i]]++;
759 allLayerRecoHits = layersRecoHit.size();
760 double frac = allLayerRecoHits / (allLayerHits + 0.0001);
762 if (nfit == 1)
break;
769 if (
chi2 < 5 * (nfit + 1) || std::abs(phiPull[
imax]) < 3.0) {
779 <<
" chi2 " <<
chi2);
785 ATH_MSG_DEBUG(
"Reco RPC " << nrpc <<
" TGC " << ntgc <<
" CSC " << ncsc);
791 for (
int i = 0; i < nphi; ++i) {
792 double power = (niter - 10) / 20.;
793 if (power < 0.) power = 0.;
794 double pull = phiPull[i] * std::pow(phiMult[i], power);
795 if (niter > 10 && std::abs(pull) > 3.0 && phiSelect[i] > 0) {
800 ATH_MSG_DEBUG(
"Drop shower hit i " << i <<
" with pull " << pull <<
" iterations " << niter
801 <<
" power " << power);
803 if (phiSelect[i] != 0) nacc++;
806 ATH_MSG_DEBUG(
"phi hits " << nphi <<
" selected for fit " << nfit <<
" iqua " << iqua <<
" iterations "
807 << niter <<
" accepted hits " << nacc <<
" nshower drop " << nshowerdrop);
813 const std::vector<double>& hity,
const std::vector<double>& hitz,
814 const std::vector<double>&
error, std::vector<int>& select,
const int n,
815 std::vector<double>& pull,
int&
imax,
double&
chi2,
double& r0,
double&
phi,
816 std::vector<double>& errorM,
bool fast)
const
841 if (pest > 20000.) pest = 20000.;
853 for (
int i = 0; i < n; ++i) {
854 if (
error[i] != 0 && select[i] > 0) {
856 xm += hitx[i] * inver2;
857 ym += hity[i] * inver2;
858 dtot += std::sqrt(hitx[i] * hitx[i] + hity[i] * hity[i] + hitz[i] * hitz[i]) * inver2;
873 double ebs2 = ebs * ebs;
874 double invebs2 = 1. / ebs2;
875 double xmc = xm / (em + invebs2);
876 double ymc = ym / (em + invebs2);
882 double len2 = xmc * xmc + ymc * ymc;
883 double xcc = len2 * xmc * invebs2;
884 double ycc = len2 * ymc * invebs2;
886 for (
int i = 0; i < n; ++i) {
887 if (
error[i] != 0 && select[i] > 0) {
889 double xdiff = hitx[i] - xmc;
890 double ydiff = hity[i] - ymc;
891 double xdiff2 = xdiff * xdiff;
892 double ydiff2 = ydiff * ydiff;
893 len2 = xdiff2 + ydiff2;
896 if (xdiff * hitx[i] + ydiff * hity[i] < 0 && !
m_cosmics)
sign = -1;
899 xcc += len2 *
sign * xdiff * inver2;
900 ycc += len2 *
sign * ydiff * inver2;
904 if (em > 0)
phi = std::atan2(ycc, xcc);
907 r0 = xmc * scphi.
sn - ymc * scphi.
cs;
908 double x0 = r0 * scphi.
sn;
909 double y0 = -r0 * scphi.
cs;
912 ATH_MSG_DEBUG(
"Constraint r0 " << r0 <<
" xpos " << xmc <<
" ypos " << ymc <<
" phi " <<
phi);
914 std::vector<double> d(n);
915 std::vector<double> dist(n);
916 std::map<double, int> distanceSort;
918 for (
int i = 0; i < n; ++i) {
919 if (
error[i] != 0 && select[i] > 0) {
920 double xdiff = hitx[i] - x0;
921 double ydiff = hity[i] - y0;
922 double xdiff2 = xdiff * xdiff;
923 double ydiff2 = ydiff * ydiff;
924 d[i] = std::sqrt(xdiff2 + ydiff2);
925 dist[i] = std::sqrt(xdiff2 + ydiff2 + hitz[i] * hitz[i]);
926 distanceSort[dist[i]] = i;
927 pull[i] = hitx[i] * scphi.
sn - hity[i] * scphi.
cs - r0;
928 if (std::abs(pull[i]) > std::abs(pullmax)) {
937 std::map<double, int>::iterator it = distanceSort.begin();
938 std::map<double, int>::iterator it_end = distanceSort.end();
941 std::vector<double> xf(2 * n);
942 std::vector<double> lf(2 * n);
943 std::vector<double> yf(2 * n);
944 std::vector<double> ef(2 * n);
945 std::vector<int> indexf(n);
951 for (; it != it_end; ++it) {
952 int index = it->second;
954 lf[nfit] = dist[
index];
955 yf[nfit] = (hitx[
index] - xmc) * scphi.
sn - (hity[
index] - ymc) * scphi.
cs;
957 indexf[nfit] =
index;
963 double erang = 0.030 * 5000. / (pest + 1000.);
964 for (
int i = 1; i < nfit; ++i) {
965 xf[nfit + i - 1] = xf[i - 1];
966 yf[nfit + i - 1] = 0.;
970 else if (select[i] == 3)
972 else if (select[i] == 2)
974 ef[nfit + i - 1] = scale * erang;
977 yf[2 * nfit - 1] = 0.;
978 xf[2 * nfit - 1] = 0.;
979 ef[2 * nfit - 1] = ebs;
986 <<
" nfit " << nfit);
988 for (
int i = 0; i < nfit + 1; ++i) {
990 for (
int j = 0; j < nfit; ++j) {
991 double inver2 = 1. / (ef[j] * ef[j]);
993 v(i, 0) += yf[j] * inver2;
995 v(i, 0) += yf[j] * xf[j] * inver2;
996 else if (i > 1 && j > i - 2) {
997 v(i, 0) += yf[j] * (lf[j] - lf[i - 2]) * inver2;
1005 model.setIdentity();
1008 for (
int i = 0; i < nfit + 1; ++i) {
1009 for (
int j = 0; j < nfit; ++j) {
1014 model(i, j) = xf[j];
1016 else if (i > 1 && j > i - 2)
1017 model(i, j) = lf[j] - lf[i - 2];
1023 for (
int i = 0; i < nfit + 1; ++i) {
1024 for (
int j = nfit; j < 2 * nfit; ++j) {
1027 if (i == j - nfit + 2) model(i, j) = 1.;
1029 if (i == 0 && j == 2 * nfit - 1) model(i, j) = 1.;
1036 for (
int i = 0; i < nfit + 1; ++i) {
1037 for (
int j = 0; j < nfit + 1; ++j) {
1039 for (
int k = 0; k < 2 * nfit; ++k) {
1040 double er2 = ef[k] * ef[k];
1041 covT(i, j) += model(i, k) * model(j, k) / er2;
1053 if (
msgLvl(MSG::DEBUG) && std::abs(t(1, 0)) > 0.2) {
1054 ATH_MSG_DEBUG(
"Don't trust fit result " << t(1, 0) <<
" Keep Old result");
1056 if (std::abs(t(1, 0)) > 0.2)
return;
1059 std::vector<double> resi(2 * nfit);
1060 std::vector<double> pulli(2 * nfit);
1061 std::vector<double> errf(2 * nfit);
1062 std::vector<double> pullf(2 * nfit);
1063 std::vector<double> resiOut(2 * nfit);
1064 std::vector<double> pullOut(2 * nfit);
1068 errorM[0] = covTI(0, 0);
1069 errorM[1] = covTI(0, 1);
1070 errorM[2] = covTI(1, 1);
1073 double invlt = 1. / (lf[nfit - 1] - lf[1]);
1074 for (
int i = 1; i < nfit - 1; ++i) {
1075 double w = (lf[nfit - 1] - lf[i]) * invlt;
1076 errorM[3] += covTI(i + 1, i + 1) * w * w;
1087 for (
int i = 0; i < 2 * nfit; ++i) {
1093 for (
int j = 0; j < nfit + 1; ++j) {
1094 if (
msgLvl(MSG::DEBUG) && i == 0)
ATH_MSG_DEBUG(
"Parameter j " << j <<
" t(j,0) " << t(j, 0));
1095 if (
msgLvl(MSG::DEBUG) && model(j, i) != 0)
ATH_MSG_DEBUG(
"i " << i <<
" model ij " << model(j, i));
1096 ypred += model(j, i) * t(j, 0);
1097 for (
int k = 0; k < nfit + 1; ++k) {
1098 error2 += model(j, i) * covTI(j, k) * model(k, i);
1101 double ef_i2 = ef[i] * ef[i];
1102 double inv_ef_i2 = 1. / ef_i2;
1104 resi[i] = ypred - yf[i];
1105 pulli[i] = resi[i] / ef[i];
1108 errf[i] = std::sqrt(error2);
1109 pullf[i] = resi[i] / errf[i];
1113 double err2invOut = 1. / error2 - inv_ef_i2;
1114 if (err2invOut > 0) {
1115 resiOut[i] = (ypred / error2 - yf[i] * inv_ef_i2) / err2invOut - yf[i];
1116 pullOut[i] = resiOut[i] / std::sqrt(1. / err2invOut + ef_i2);
1119 if ((i < nfit) and (std::abs(pullOut[i]) > std::abs(pullmax)) ) {
1122 pullmax = pullOut[i];
1124 chi2 += resi[i] * resi[i] * inv_ef_i2;
1127 pull[indexf[i]] = pullOut[i];
1129 if (
msgLvl(MSG::DEBUG) && i < nfit)
1130 ATH_MSG_DEBUG(
"i " << i <<
" index " << indexf[i] <<
" det " << select[indexf[i]] <<
" ypred " << ypred
1131 <<
" mst " << yf[i] <<
" residual " << resi[i] <<
" error " << ef[i] <<
" dist "
1132 << dist[i] <<
" hitz " << hitz[i] <<
" Pull " << pulli[i] <<
" Pullf " << pullf[i]
1133 <<
" resi out " << resiOut[i] <<
" pull out " << pullOut[i]);
1134 if (
msgLvl(MSG::DEBUG) && i > nfit)
1135 ATH_MSG_DEBUG(
"i " << i <<
" ypred " << ypred <<
" mst " << yf[i] <<
" residual " << resi[i] <<
" error "
1142 if (
msgLvl(MSG::DEBUG) && std::abs(t(1, 0)) > 0.1)
ATH_MSG_DEBUG(
"ALARM delta phi " << t(1, 0));
1145 ATH_MSG_DEBUG(
"Track parameters r0 " << r0 <<
" phi " <<
phi <<
" chi2 " <<
chi2 <<
" jmax " << jmax <<
" imax "
1146 <<
imax <<
" pullmax " << pullmax);