42 else if (station == 2)
45 return "UNKNOWN_STATION";
48 std::string measphi_name(
const bool measphi) {
55 double alignConst(
const bool measphi,
const int wlay) {
56 if (measphi)
return 0.;
57 const double aConst[4] = {0, -0.2289, -0.620181, -0.6534445};
58 return aConst[wlay - 1];
62 int nHitLayer_eta = 0;
63 int nHitLayer_phi = 0;
64 for (
int i = 0;
i < 4; ++
i) {
65 if (!eta_clus[
i].
empty()) ++nHitLayer_eta;
66 if (!phi_clus[
i].
empty()) ++nHitLayer_phi;
68 return nHitLayer_eta >= 2 || nHitLayer_phi >= 2;
80 declareInterface<ICscSegmentUtilTool>(
this);
110 return StatusCode::SUCCESS;
118 const Amg::Vector3D& lpos000,
const EventContext& ctx)
const {
119 if (!enoughHitLayers(eta_clus, phi_clus)) {
120 ATH_MSG_DEBUG(
" Could not find at least two individual layer hits! ");
121 std::unique_ptr<std::vector<std::unique_ptr<MuonSegment> > > segments;
125 for (
int i = 0;
i < 4; ++
i)
126 ATH_MSG_DEBUG(
"getMuonSegments2: No of clusters in layer " <<
i <<
" " << eta_clus[
i].
size() <<
" " << phi_clus[
i].
size());
128 ATH_MSG_DEBUG(
"getMuonSegments called get2dMuonSegmentCombination");
129 std::unique_ptr<MuonSegmentCombination> Muon2dSegComb(
get2dMuonSegmentCombination(eta_id, phi_id, eta_clus, phi_clus, lpos000, ctx));
131 ATH_MSG_DEBUG(
"getMuonSegments called get4dMuonSegmentCombination");
134 std::unique_ptr<std::vector<std::unique_ptr<MuonSegment> > > segments_clone(
new std::vector<std::unique_ptr<MuonSegment> >);
137 std::vector<std::unique_ptr<MuonSegment> >* segments = Muon4dSegComb->
stationSegments(0);
139 if (!segments->empty()) {
140 for (
unsigned int i = 0;
i < segments->size(); ++
i) { segments_clone->push_back(std::move(segments->at(
i))); }
144 return segments_clone;
151 const Amg::Vector3D& lpos000,
const EventContext& ctx,
int etaStat,
153 int nGoodEta = 0, nGoodPhi = 0;
154 for (
int i = 0;
i < 4; ++
i) {
155 ATH_MSG_DEBUG(
"get2dMuonSegmentCombination2: No of clusters in layer " <<
i <<
" " << eta_clus[
i].
size() <<
" "
156 << phi_clus[
i].
size());
161 if (nGoodEta < 2 && nGoodPhi < 2) {
162 ATH_MSG_DEBUG(
" Not enough hits in either eta or phi to form a segment");
174 get2dSegments(eta_id, phi_id, eta_clus, phi_clus, eta_segs, phi_segs, lpos000, ctx, etaStat, phiStat);
176 for (ICscSegmentFinder::Segments::const_iterator iseg = eta_segs.begin(); iseg != eta_segs.end(); ++iseg) {
177 std::unique_ptr<MuonSegment> pseg(
build_segment(*iseg,
false, eta_id, nGoodEta == 2, ctx));
179 ATH_MSG_DEBUG(
" =============================> get2dMuonSegmentCombination:: MuonSegment time (eta) from build_segment is "
181 psegs->push_back(std::move(pseg));
189 for (ICscSegmentFinder::Segments::const_iterator iseg = phi_segs.begin(); iseg != phi_segs.end(); ++iseg) {
190 std::unique_ptr<MuonSegment> pseg(
build_segment(*iseg,
true, phi_id, nGoodPhi == 2, ctx));
192 ATH_MSG_DEBUG(
" get2dMuonSegmentCombination:: MuonSegment time (phi) from build_segment is " << pseg->
time());
193 phisegs->push_back(std::move(pseg));
196 ATH_MSG_DEBUG(
"added " << phisegs->size() <<
" phi segments");
200 ATH_MSG_DEBUG(
"Added " << eta_segs.size() <<
" r-segments and " << phi_segs.size() <<
" phi-segments.");
210 double&
d0,
double&
d1,
double& d01,
double& chsq,
double&
time,
double& dtime,
double& zshift,
211 const EventContext& ctx,
int outlierHitLayer)
const {
214 bool measphi =
false;
215 fit_detailCalcPart1(clus, lpos000, s0,
s1,
d0,
d1, d01, chsq, measphi,
time, dtime, zshift,
false, outlierHitLayer,
219 fit_detailCalcPart1(clus, lpos000, s0,
s1,
d0,
d1, d01, chsq, measphi,
time, dtime, zshift,
true, outlierHitLayer,
227 double&
s1,
double&
d0,
double&
d1,
double& d01,
double& chsq,
bool& measphi,
double&
time,
228 double& dtime,
double& zshift,
bool IsSlopeGiven,
int outlierHitLayer,
229 const EventContext& ctx)
const {
235 for (ICscSegmentFinder::TrkClusters::const_iterator iclu = clus.begin(); iclu != clus.end(); ++iclu) {
243 double y =
cl.locY();
245 double x =
cl.locX();
254 if (IsSlopeGiven && outlierHitLayer != (iclu - clus.begin()))
259 double w = 1.0 / (
d *
d);
264 if (q0 > 0.) zshift = q1 / q0;
277 double x = lpos000.z();
278 double y = measphi ? lpos000.x() : lpos000.y();
283 double w = 1.0 / (
d *
d);
285 q1 +=
w * (
x - zshift);
286 q2 +=
w * (
x - zshift) * (
x - zshift);
288 q11 +=
w * (
x - zshift) *
y;
292 int cntSuccessHit = 0;
293 double sumHitTimes = 0.;
294 double sumHitTimeSquares = 0.;
298 float latestEarlyTime = -9999;
299 float earliestLateTime = 9999;
300 for (ICscSegmentFinder::TrkClusters::const_iterator iclu = clus.begin(); iclu != clus.end(); ++iclu) {
308 double y =
cl.locY();
310 double x =
cl.locX();
319 if (IsSlopeGiven)
d =
m_rotCreator->GetICscClusterFitter()->getCorrectedError(prd,
s1);
320 if (outlierHitLayer == (iclu - clus.begin()))
d =
getDefaultError(
id, measphi, prd, ctx);
325 double w = 1.0 / (
d *
d);
327 q1 +=
w * (
x - zshift);
328 q2 +=
w * (
x - zshift) * (
x - zshift);
330 q11 +=
w * (
x - zshift) *
y;
335 sumHitTimes += prd->
time();
341 if (latestEarlyTime < prd->
time()) latestEarlyTime = prd->
time();
346 if (earliestLateTime > prd->
time()) earliestLateTime = prd->
time();
350 ATH_MSG_DEBUG(
" Time Calculation!!! " << cntSuccessHit <<
" " << cntEarlyHit <<
" " << cntLateHit <<
" " << sumHitTimes <<
" "
351 << latestEarlyTime <<
" " << earliestLateTime);
353 if (cntSuccessHit > 0) {
354 time = sumHitTimes /
float(cntSuccessHit);
355 float timeSquare = sumHitTimeSquares /
float(cntSuccessHit);
360 dtime = std::sqrt(dtime);
362 if (cntEarlyHit > 0 && cntLateHit > 0) {
365 ATH_MSG_DEBUG(
"Segment has nonzero earlyHits and nonzero lateHits. This should be backgrounds!!");
366 }
else if (cntEarlyHit > 0) {
367 time = latestEarlyTime;
368 dtime = std::abs(latestEarlyTime);
369 }
else if (cntLateHit > 0) {
370 time = earliestLateTime;
371 dtime = earliestLateTime;
375 ATH_MSG_DEBUG(
"Every Hit is CscTimeUnavailable or CscTimeStatusUndefined!!! Should be investigated");
383 if (IsSlopeGiven && q2 * q0 - q1 * q1 == 0.0)
return;
385 fit_detailCalcPart2(q0, q1, q2, q01, q11, q02, s0,
s1,
d0,
d1, d01, chsq);
391 double& returned_chsq,
const EventContext& ctx)
const {
394 double chsq_reference = 10000;
399 for (
unsigned int ire = 0; ire < clus.size(); ire++) {
402 if (isunspoiled) ++nunspoil;
404 for (
unsigned int itr = 0; itr < clus.size(); itr++)
405 if (ire != itr) fitclus.push_back(clus[itr]);
407 ATH_MSG_VERBOSE(
" find_outlier_cluster drop ire " << ire <<
" fitclus size " << fitclus.size());
409 double s0,
s1,
d0,
d1, d01, chsq,
time, dtime, zshift;
410 fit_segment(fitclus, lpos000, s0,
s1,
d0,
d1, d01, chsq,
time, dtime, zshift, ctx);
411 if (chsq < chsq_reference && isunspoiled) {
412 chsq_reference = chsq;
416 if (remclu_ind >= 0)
ATH_MSG_VERBOSE(
" new chsq " << ire <<
" " << chsq <<
" @" << remclu_ind);
422 ATH_MSG_VERBOSE(
" Number of unspoiled cluster is " << nunspoil <<
" which is not enough!! At least 3 unspoiled hits required!! ");
426 returned_chsq = 99999;
427 if (remclu_ind >= 0) {
430 for (
unsigned int ire = 0; ire < clus.size(); ire++) fitclus.push_back(clus[ire]);
432 ATH_MSG_VERBOSE(
" final fit outlier_cluster drop cluster index " << remclu_ind <<
" fitclus.size " << fitclus.size());
434 double s0,
s1,
d0,
d1, d01, chsq,
time, dtime, zshift;
435 fit_segment(fitclus, lpos000, s0,
s1,
d0,
d1, d01, chsq,
time, dtime, zshift, ctx, remclu_ind);
436 returned_chsq = chsq;
451 double&
res,
double& dres,
const EventContext& ctx)
const {
455 for (
unsigned int iclu = 0; iclu < clus.size(); ++iclu) {
456 if (iclu != irclu) fitclus.push_back(clus[iclu]);
459 double s0,
s1,
d0,
d1, d01, chsq,
time, dtime, zshift;
460 fit_segment(fitclus, lpos000, s0,
s1,
d0,
d1, d01, chsq,
time, dtime, zshift, ctx);
466 double y = clus[irclu].locY();
471 double x = clus[irclu].locX();
476 if (
d0 < 0 ||
d1 < 0) {
481 double seg_y = s0 +
s1 *
x;
482 double seg_dsquare =
d0 *
d0 + 2.0 *
x * d01 +
d1 *
d1 *
x *
x;
485 dres =
d *
d + seg_dsquare;
487 ATH_MSG_VERBOSE(
" fit_residual d0:d01:d1 :: seg_dsquare:dres " <<
d0 <<
" " << d01 <<
" " <<
d1 <<
" :: " << seg_dsquare <<
" "
491 dres = -1.0 * std::sqrt(-1.0 * dres);
493 dres = std::sqrt(dres);
505 double&
s1,
double&
d0,
double&
d1,
double& d01,
double& chsq,
double& zshift)
const {
506 ATH_MSG_DEBUG(
"CscSegmentUtilTool::fit_rio_segment called: ");
512 for (ICscSegmentFinder::RioList::const_iterator irio = rios.begin(); irio != rios.end(); ++irio) {
517 double y = msmt[iloc];
532 ATH_MSG_VERBOSE(
" RIO global pos: " << gpos.x() <<
" " << gpos.y() <<
" " << gpos.z());
533 ATH_MSG_VERBOSE(
" RIO local pos: " << lpos.x() <<
" " << lpos.y() <<
" " << lpos.z());
538 double w = 1.0 / (
d *
d);
544 if (q0 > 0) zshift = q1 / q0;
555 for (ICscSegmentFinder::RioList::const_iterator irio = rios.begin(); irio != rios.end(); ++irio) {
560 double y = msmt[iloc];
576 ATH_MSG_VERBOSE(
" RIO global pos: " << gpos.x() <<
" " << gpos.y() <<
" " << gpos.z());
577 ATH_MSG_VERBOSE(
" RIO local pos: " << lpos.x() <<
" " << lpos.y() <<
" " << lpos.z());
582 double w = 1.0 / (
d *
d);
584 q1 +=
w * (
x - zshift);
585 q2 +=
w * (
x - zshift) * (
x - zshift);
587 q11 +=
w * (
x - zshift) *
y;
592 fit_detailCalcPart2(q0, q1, q2, q01, q11, q02, s0,
s1,
d0,
d1, d01, chsq);
604 unsigned int irrio,
double&
res,
double& dres,
double& rs,
double& drs)
const {
605 ATH_MSG_DEBUG(
"CscSegmentUtilTool::fit_rio_segment called ");
609 for (
unsigned int irio = 0; irio < rios.size(); ++irio) {
610 if (irio != irrio) fitrios.push_back(rios[irio]);
612 if ((irrio == 1) && (irio == 0 || irio == 2)) fitrios3pt.push_back(rios[irio]);
613 if ((irrio == 2) && (irio == 1 || irio == 3)) fitrios3pt.push_back(rios[irio]);
616 double s0,
s1,
d0,
d1, d01, chsq, zshift;
623 double y = msmt[iloc];
638 double seg_y = s0 +
s1 *
x;
639 double seg_dsquare =
d0 *
d0 + 2.0 *
x * d01 +
d1 *
d1 *
x *
x;
642 dres =
d *
d + seg_dsquare;
644 ATH_MSG_VERBOSE(
" fit_residual d0:d01:d1 :: seg_dsquare:dres " <<
d0 <<
" " << d01 <<
" " <<
d1 <<
" :: " << seg_dsquare <<
" "
648 dres = -1.0 * std::sqrt(-1.0 * dres);
650 dres = std::sqrt(dres);
656 if (irrio == 1 || irrio == 2) {
658 double s0_3pt, s1_3pt, d0_3pt, d1_3pt, d01_3pt, chsq_3pt, zshift_3pt;
659 fit_rio_segment(ssrf,
dump, fitrios3pt, s0_3pt, s1_3pt, d0_3pt, d1_3pt, d01_3pt, chsq_3pt, zshift_3pt);
661 if (d0_3pt < 0 || d1_3pt < 0) {
665 seg_y = s0_3pt + s1_3pt *
x;
666 seg_dsquare = d0_3pt * d0_3pt + 2.0 *
x * d01_3pt + d1_3pt * d1_3pt *
x *
x;
669 drs =
d *
d + seg_dsquare;
671 ATH_MSG_VERBOSE(
" fit_rio_residual d0:d01:d1 :: seg_dsquare:dres " << d0_3pt <<
" " << d01_3pt <<
" " << d1_3pt
672 <<
" :: " << seg_dsquare <<
" " << drs);
675 drs = -1.0 * std::sqrt(-1.0 * drs);
677 drs = std::sqrt(drs);
697 for (ICscSegmentFinder::RioList::const_iterator irio = rios.begin(); irio != rios.end(); ++irio) {
715 for (ICscSegmentFinder::RioList::const_iterator irio = rios.begin(); irio != rios.end(); ++irio) {
735 for (ICscSegmentFinder::RioList::const_iterator irio = rios.begin(); irio != rios.end(); ++irio) {
763 const EventContext& ctx)
const {
770 if (MuonDetMgr ==
nullptr) {
771 ATH_MSG_ERROR(
"Null pointer to the read MuonDetectorManager conditions object");
789 xf.pretranslate(glop);
800 }
else if (pbnd_rtrap) {
810 double lx = measphi ? seg.
s0 : 0.;
811 double ly = measphi ? 0. : seg.
s0;
813 double dlx = measphi ? seg.
s1 : 0.;
814 double dly = measphi ? 0. : seg.
s1;
822 Amg::Vector3D lposRefShift = lposRef - ldirRef * lposRef.z();
825 double s0 = lposRefShift.x();
831 getRios(seg, &prios, measphi, ctx);
834 int ndof =
int(prios.size()) - 2;
836 if (use2Lay)
ndof = 1;
842 double ameas = std::atan2(1.0, seg.
s1);
845 double dfac = -1.0 / (1 + seg.
s1 * seg.
s1);
846 double e_pos_pos = seg.
d0 * seg.
d0;
847 double e_pos_dir = seg.
d01 * dfac;
848 const double e_dir_dir = seg.
d1 * seg.
d1 * dfac * dfac;
851 cov(0, 0) = e_pos_pos;
852 cov(0, 2) = e_pos_dir;
854 cov(2, 2) = e_dir_dir;
855 cov(1, 1) = 1000000.0;
877 tantheta =
d.x() /
d.z();
882 ATH_MSG_VERBOSE(
" d.x : d.z : tantheta " <<
d.x() <<
" " <<
d.z() <<
" " << tantheta);
888 const double initialDiffTanTheta = 99;
889 double diff_tantheta = initialDiffTanTheta;
890 const unsigned int nTrials = 10;
891 unsigned int n_update = 0;
900 for (ICscSegmentFinder::RioList::size_type irio = 0; irio < pseg_ref->
numberOfContainedROTs(); ++irio) {
916 prios_new.push_back(cot);
931 fitclus.emplace_back(lpos, pcl, measphi);
940 ATH_MSG_DEBUG(
"build_segments:: " << seg_new.
time <<
" " << seg_new.
dtime <<
" fitclus size " << fitclus.size());
946 double lx = measphi ? seg_new.
s0 : 0.;
947 double ly = measphi ? 0. : seg_new.
s0;
948 double lz = seg_new.
zshift;
949 double dlx = measphi ? seg_new.
s1 : 0.;
950 double dly = measphi ? 0. : seg_new.
s1;
958 Amg::Vector3D lposRefShift = lposRef - ldirRef * lposRef.z();
959 double s0 = lposRefShift.x();
963 double ameas_new = atan2(1.0, seg_new.
s1);
966 double dfac_new = -1.0 / (1 + seg_new.
s1 * seg_new.
s1);
967 double e_pos_pos_new = seg_new.
d0 * seg_new.
d0;
968 double e_pos_dir_new = seg_new.
d01 * dfac_new;
969 const double e_dir_dir_new = seg_new.
d1 * seg_new.
d1 * dfac_new * dfac_new;
972 cov(0, 0) = e_pos_pos_new;
973 cov(0, 2) = e_pos_dir_new;
974 cov(2, 2) = e_dir_dir_new;
975 cov(1, 1) = 1000000.0;
984 std::move(prios_new),
991 double tanthetanew = 0;
993 ATH_MSG_WARNING(
"build_segment() - new segment z is 0, staying with old segment and continue loop");
997 diff_tantheta = initialDiffTanTheta;
999 if (n_update == (nTrials - 1))
break;
1002 tanthetanew = dnew.x() / dnew.z();
1007 ATH_MSG_DEBUG(
" build_segment:: right after new assigning and resetting * " << pseg->
time());
1009 if (tantheta == 0) {
1010 ATH_MSG_WARNING(
"build_segment() - tantheta=0 but tanthetanew=" << tanthetanew <<
", set diff_tantheta=tanthetanew");
1011 diff_tantheta = tanthetanew;
1014 diff_tantheta = std::abs(tanthetanew - tantheta) / tantheta;
1017 ATH_MSG_VERBOSE(
" tantheta change in segment: " << tantheta <<
" ==> " << tanthetanew <<
" -ratio- " << diff_tantheta);
1019 tantheta = tanthetanew;
1041 ATH_MSG_DEBUG(
" build_segment:: right just before returning * " << pseg->
time());
1048 const EventContext& ctx)
const {
1050 ATH_MSG_DEBUG(
"find_2dsegments called!! ID: " << measphi_name(measphi) <<
" " << std::showpos <<
eta <<
" "
1064 for (ICscSegmentFinder::TrkClusters::const_iterator icl1 = clus1.begin(); icl1 != clus1.end(); ++icl1) {
1065 for (ICscSegmentFinder::TrkClusters::const_iterator icl2 = clus2.begin(); icl2 != clus2.end(); ++icl2) {
1066 for (ICscSegmentFinder::TrkClusters::const_iterator icl3 = clus3.begin(); icl3 != clus3.end(); ++icl3) {
1067 for (ICscSegmentFinder::TrkClusters::const_iterator icl4 = clus4.begin(); icl4 != clus4.end(); ++icl4) {
1068 fitclus = {*icl1, *icl2, *icl3, *icl4};
1072 <<
Amg::error((*icl2).cl->localCovariance(), ierr) <<
" "
1073 <<
Amg::error((*icl3).cl->localCovariance(), ierr) <<
" "
1074 <<
Amg::error((*icl4).cl->localCovariance(), ierr) <<
" ");
1078 fit_segment(fitclus, lpos000, seg.
s0, seg.
s1, seg.
d0, seg.
d1, seg.
d01, seg.
chsq, seg.
time, seg.
dtime, seg.
zshift, ctx);
1079 seg.
clus[0] = *icl1;
1080 seg.
clus[1] = *icl2;
1081 seg.
clus[2] = *icl3;
1082 seg.
clus[3] = *icl4;
1085 for (
int i = 0;
i < 4; ++
i) {
1094 double local_max_chi = 0.;
1103 ATH_MSG_VERBOSE(
" find_2dsegments:: nunspoil and local_max_chi " << nunspoil <<
" " << local_max_chi <<
" " <<
keep
1108 double outlierRemoved_chsq;
1112 seg.
chsq = outlierRemoved_chsq;
1127 if (
keep) segs.push_back(seg);
1129 ATH_MSG_VERBOSE(
" nunspoil and local_max_chi " << nunspoil <<
" " << local_max_chi <<
" " <<
keep <<
" " << seg.
s1
1132 ATH_MSG_VERBOSE(
" Segment measphi? " << measphi <<
" chsq:" << seg.
chsq <<
" abs(seg.s1) " << std::abs(seg.
s1)
1134 <<
" keep? " <<
keep);
1149 if (segs4.empty() and segs3.empty())
return;
1151 ATH_MSG_DEBUG(
" Total Input seg4 segment size " << segs4.size());
1152 ATH_MSG_DEBUG(
" Total Input seg3 segment size " << segs3.size());
1154 std::vector<int> isegs4OK(segs4.size(), 1);
1155 std::vector<int> isegs3OK(segs3.size(), 1);
1158 ICscSegmentFinder::Segments::const_iterator iseg;
1159 ICscSegmentFinder::Segments::const_iterator iseg2;
1166 for (iseg = segs4All.begin(); iseg != segs4All.end(); ++iseg) {
1169 for (iseg2 = iseg + 1; iseg2 != segs4All.end(); ++iseg2) {
1170 int nhits_common = 0;
1172 for (
int iclus = 0; iclus < iseg->nclus; iclus++) {
1174 for (
int iclus2 = 0; iclus2 < iseg2->nclus; iclus2++) {
1180 isegs4OK[iiseg2] = 0;
1181 ATH_MSG_DEBUG(
" seg4 segment nr " << iiseg2 <<
" dropped with nhits_common " << nhits_common);
1187 for (iseg = segs4All.begin(); iseg != segs4All.end(); ++iseg) {
1192 ATH_MSG_DEBUG(
" seg4 eta segment rejected with nclusters too few unspoiled hits " << iseg->nclus <<
" chi2 " << iseg->chsq
1193 <<
" unspoiled " << iseg->nunspoil);
1194 isegs4OK[iiseg] = 0;
1197 segs4.push_back(*iseg);
1198 ATH_MSG_DEBUG(
" seg4 segment accepted with nclusters " << iseg->nclus <<
" chi2 " << iseg->chsq <<
" unspoiled "
1199 << iseg->nunspoil <<
" measuresPhi "
1202 ATH_MSG_DEBUG(
" seg4 segment rejected with nclusters " << iseg->nclus <<
" chi2 " << iseg->chsq <<
" unspoiled "
1203 << iseg->nunspoil <<
" measuresPhi "
1207 int segs4Size = segs4.size();
1208 ATH_MSG_DEBUG(
" Total seg4 segment accepted size " << segs4Size);
1212 for (iseg = segs4.begin(); iseg != segs4.end(); ++iseg) {
1214 for (iseg2 = segs3.begin(); iseg2 != segs3.end(); ++iseg2) {
1216 int nhits_common = 0;
1217 for (
int iclus = 0; iclus < iseg->nclus; iclus++) {
1219 for (
int iclus2 = 0; iclus2 < iseg2->nclus; iclus2++) {
1225 isegs3OK[iiseg2] = 0;
1226 ATH_MSG_DEBUG(
" seg3 segment nr " << iiseg2 <<
" dropped with nhits_common " << nhits_common);
1232 for (iseg = segs3.begin(); iseg != segs3.end(); ++iseg) {
1235 for (iseg2 = iseg + 1; iseg2 != segs3.end(); ++iseg2) {
1237 int nhits_common = 0;
1238 for (
int iclus = 0; iclus < iseg->nclus; iclus++) {
1240 for (
int iclus2 = 0; iclus2 < iseg2->nclus; iclus2++) {
1246 isegs3OK[iiseg2] = 0;
1247 ATH_MSG_DEBUG(
" seg3 segment nr " << iiseg2 <<
" dropped with nhits_common " << nhits_common);
1254 for (iseg = segs3.begin(); iseg != segs3.end(); ++iseg) {
1259 ATH_MSG_DEBUG(
" seg3 eta segment rejected with nclusters too few unspoiled hits " << iseg->nclus <<
" chi2 " << iseg->chsq
1260 <<
" unspoiled " << iseg->nunspoil);
1261 isegs3OK[iiseg] = 0;
1264 segs4.push_back(*iseg);
1265 ATH_MSG_DEBUG(
" seg3 segment accepted with nclusters " << iseg->nclus <<
" chi2 " << iseg->chsq <<
" unspoiled "
1266 << iseg->nunspoil <<
" measuresPhi "
1269 ATH_MSG_DEBUG(
" seg3 segment rejected with nclusters " << iseg->nclus <<
" chi2 " << iseg->chsq <<
" unspoiled "
1270 << iseg->nunspoil <<
" measuresPhi "
1274 ATH_MSG_DEBUG(
" Total seg3 segment size " << segs4.size() - segs4Size);
1280 if (segs2.empty())
return;
1281 ATH_MSG_DEBUG(
" Total Input 2-layer segment size " << segs2.size());
1283 int lay0 = -1, lay1 = -1;
1284 for (
int i = 0;
i < 4;
i++) {
1288 else if (lay1 == -1)
1292 bool checkCrossTalk =
false;
1293 if (std::abs(lay0 - lay1) == 1 && lay0 + lay1 != 3)
1294 checkCrossTalk =
true;
1296 std::vector<int> isegs2OK(segs2.size(), 1);
1297 ICscSegmentFinder::Segments::const_iterator iseg;
1298 ICscSegmentFinder::Segments::const_iterator iseg2;
1304 for (iseg = segs2.begin(); iseg != segs2.end(); ++iseg) {
1306 if (!isegs2OK[iiseg])
continue;
1308 for (iseg2 = iseg + 1; iseg2 != segs2.end(); ++iseg2) {
1309 int nhits_common = 0;
1311 if (!isegs2OK[iiseg2])
continue;
1312 double charges[2] = {0, 0};
1313 for (
int iclus = 0; iclus < iseg->nclus; iclus++) {
1315 if (checkCrossTalk) {
1317 std::vector<const Muon::CscStripPrepData*> strips =
m_rotCreator->GetICscClusterUtilTool()->getStrips(prep);
1318 std::vector<double> stripCharges;
1319 for (
unsigned int s = 0;
s < strips.size(); ++
s) {
1322 stripCharges.push_back(sfit.
charge);
1324 double maxCharge = 0, centCharge = 0;
1325 for (
unsigned int s = 0;
s < stripCharges.size();
s++) {
1326 if (stripCharges[
s] > maxCharge) {
1327 maxCharge = stripCharges[
s];
1328 centCharge = stripCharges[
s];
1329 if (
s > 0) centCharge += stripCharges[
s - 1];
1330 if (
s < stripCharges.size() - 1) centCharge += stripCharges[
s + 1];
1333 charges[iclus] = centCharge;
1335 float chargeRatio = charges[0] / charges[1];
1336 if (charges[0] > charges[1]) chargeRatio = charges[1] / charges[0];
1337 if (chargeRatio < .01) {
1343 for (
int iclus2 = 0; iclus2 < iseg2->nclus; iclus2++) {
1348 if (nhits_common != 0) {
1349 isegs2OK[iiseg2] = 0;
1350 ATH_MSG_DEBUG(
" seg2 segment nr " << iiseg2 <<
" dropped with nhits_common " << nhits_common);
1355 for (iseg = segsAll.begin(); iseg != segsAll.end(); ++iseg) {
1358 for (iseg2 = segs2.begin(); iseg2 != segs2.end(); ++iseg2) {
1359 int nhits_common = 0;
1361 if (isegs2OK[iiseg2] == 0)
continue;
1362 for (
int iclus = 0; iclus < iseg->nclus; iclus++) {
1370 for (
int iclus2 = 0; iclus2 < iseg2->nclus; iclus2++) {
1375 if (nhits_common > 0) {
1376 isegs2OK[iiseg2] = 0;
1377 ATH_MSG_DEBUG(
" seg2 segment nr " << iiseg2 <<
" dropped with nhits_common " << nhits_common);
1378 if (iseg2 == segs2.begin()) segs.push_back(*iseg);
1379 }
else if (nhits_common == 0) {
1380 if (iseg2 == segs2.begin()) segs.push_back(*iseg);
1381 }
else if (nhits_common == -1)
1386 for (iseg = segs2.begin(); iseg != segs2.end(); ++iseg) {
1391 segs.push_back(*iseg);
1392 ATH_MSG_DEBUG(
" seg2 accepted, nclusters " << iseg->nclus <<
" chi2 " << iseg->chsq <<
" unspoiled " << iseg->nunspoil
1393 <<
" mPhi " <<
m_idHelperSvc->cscIdHelper().measuresPhi(
id));
1395 ATH_MSG_DEBUG(
" seg2 rejected, nclusters " << iseg->nclus <<
" chi2 " << iseg->chsq <<
" unspoiled " << iseg->nunspoil
1396 <<
" mPhi " <<
m_idHelperSvc->cscIdHelper().measuresPhi(
id));
1409 constexpr
int maxcomb = 4;
1410 constexpr std::array<int, maxcomb> layAcomb{1, 2, 3, 0};
1411 constexpr std::array<int, maxcomb> layBcomb{2, 3, 0, 1};
1412 constexpr std::array<int, maxcomb> layCcomb{3, 0, 1, 2};
1417 constexpr
int maxhits = 3;
1423 for (
int icomb = 0; icomb < maxcomb; icomb++) {
1425 ICscSegmentFinder::TrkClusters::const_iterator icl[maxhits];
1426 auto & pCluster1 = icl[0];
1427 auto & pCluster2 = icl[1];
1428 auto & pCluster3 = icl[2];
1431 for (pCluster1 = clus1.begin(); pCluster1 != clus1.end(); ++pCluster1) {
1434 for (pCluster2 = clus2.begin(); pCluster2 != clus2.end(); ++pCluster2) {
1437 for (pCluster3 = clus3.begin(); pCluster3 != clus3.end(); ++pCluster3) {
1439 fitclus = {*pCluster1, *pCluster2, *pCluster3};
1449 fit_segment(fitclus, lpos000, seg.
s0, seg.
s1, seg.
d0, seg.
d1, seg.
d01, seg.
chsq, seg.
time, seg.
dtime, seg.
zshift, ctx);
1453 for (
int i = 0;
i < maxhits;
i++) {
1463 double local_max_chi = 0.;
1473 if (seg.
chsq > local_max_chi)
keep =
false;
1475 ATH_MSG_VERBOSE(
" nunspoil and local_max_chi " << nunspoil <<
" " << local_max_chi <<
" " <<
keep);
1480 double outlierRemoved_chsq;
1484 seg.
chsq = outlierRemoved_chsq;
1492 if (
keep) segs.push_back(seg);
1494 ATH_MSG_VERBOSE(
" Segment measphi? " << measphi <<
" chsq:" << seg.
chsq <<
" abs(seg.s1) " << std::abs(seg.
s1)
1495 <<
" keep? " <<
keep);
1512 int lay0 = -1, lay1 = -1;
1513 for (
int i = 0;
i < 4;
i++) {
1517 else if (lay1 == -1)
1520 ATH_MSG_WARNING(
"can't do 2-layer segment finding, more than 2 layers marked as good");
1525 if (lay0 == -1 || lay1 == -1) {
1526 ATH_MSG_WARNING(
"can't do 2-layer segment finding, fewer than 2 layers marked as good");
1530 const int maxhits = 2;
1533 ICscSegmentFinder::TrkClusters::const_iterator icl[maxhits] {};
1537 for (icl[0] = clus1.begin(); icl[0] != clus1.end(); ++icl[0]) {
1540 for (icl[1] = clus2.begin(); icl[1] != clus2.end(); ++icl[1]) {
1545 for (
int i = 0;
i < maxhits;
i++) { fitclus.push_back(*(icl[
i])); }
1551 fit_segment(fitclus, lpos000, seg.
s0, seg.
s1, seg.
d0, seg.
d1, seg.
d01, seg.
chsq, seg.
time, seg.
dtime, seg.
zshift, ctx);
1555 for (
int i = 0;
i < maxhits;
i++) {
1564 double local_max_chi = 0.;
1573 if (seg.
chsq > local_max_chi)
keep =
false;
1574 ATH_MSG_VERBOSE(
" nunspoil, chi2, and local_max_chi " << nunspoil <<
" " << seg.
chsq <<
" " << local_max_chi <<
" " <<
keep);
1583 segs.push_back(seg);
1587 ATH_MSG_VERBOSE(
" Segment measphi? " << measphi <<
" chsq:" << seg.
chsq <<
" abs(seg.s1) " << std::abs(seg.
s1)
1589 <<
" keep? " <<
keep);
1598 double&
d0,
double&
d1,
double& d01,
double& chsq)
const {
1601 if (q2 * q0 - q1 * q1 == 0.0) {
1611 double r00 = q2 / (q2 * q0 - q1 * q1);
1612 double r01 = q1 / (q1 * q1 - q2 * q0);
1613 double r10 = q1 / (q1 * q1 - q0 * q2);
1614 double r11 = q0 / (q0 * q2 - q1 * q1);
1615 s0 = r01 * q11 + r00 * q01;
1616 s1 = r11 * q11 + r10 * q01;
1617 d0 = r01 * r01 * q2 + 2.0 * r00 * r01 * q1 + r00 * r00 * q0;
1619 d0 = -1.0 * std::sqrt(-1.0 *
d0);
1623 d1 = r11 * r11 * q2 + 2.0 * r10 * r11 * q1 + r10 * r10 * q0;
1625 d1 = -1.0 * std::sqrt(-1.0 *
d1);
1628 d01 = r01 * r11 * q2 + (r01 * r10 + r00 * r11) * q1 + r00 * r10 * q0;
1629 chsq = q02 +
s1 *
s1 * q2 + 2 * s0 *
s1 * q1 + s0 * s0 * q0 - 2 * s0 * q01 - 2 *
s1 * q11;
1632 ATH_MSG_VERBOSE(
" details s1 = " <<
s1 <<
" " <<
d1 <<
" " << d01 <<
" => " << r11 <<
" " << r10 <<
"chsq = " << chsq);
1636 const EventContext& ctx)
const {
1643 ATH_MSG_DEBUG(
" Combination has r/phi segments " << rsegs.size() <<
" / " << phisegs.size());
1645 <<
" good phi layers");
1648 ATH_MSG_DEBUG(
" Station does not have a r/phi segment, cannot make 4d segment ");
1656 for (ICscSegmentFinder::SegmentVec::const_iterator irsg = rsegs.begin(); irsg != rsegs.end(); ++irsg) {
1657 for (ICscSegmentFinder::SegmentVec::const_iterator ipsg = phisegs.begin(); ipsg != phisegs.end(); ++ipsg) {
1684 ATH_MSG_DEBUG(
"Segment rejected too low likelihood: " << xylike);
1692 pnewsegs->push_back(std::move(pseg));
1697 for (ICscSegmentFinder::SegmentVec::const_iterator irsg = rsegs.begin(); irsg != rsegs.end(); ++irsg) {
1699 unsigned int nMinRIOs = 3;
1703 <<
", RIO's, insufficient to build the 4d segment from a single eta segment");
1706 std::unique_ptr<MuonSegment> pseg(
new MuonSegment(rsg));
1708 pnewsegs->push_back(std::move(pseg));
1711 for (ICscSegmentFinder::SegmentVec::const_iterator ipsg = phisegs.begin(); ipsg != phisegs.end(); ++ipsg) {
1713 unsigned int nMinRIOs = 3;
1717 <<
", RIO's, insufficient to build the 4d segment from a single phi segment");
1720 std::unique_ptr<MuonSegment> pseg(
new MuonSegment(psg));
1722 pnewsegs->push_back(std::move(pseg));
1726 if (pnewsegs->empty()) {
1729 ATH_MSG_DEBUG(
"created " << pnewsegs->size() <<
" new 4d segments");
1741 const Amg::Vector3D& lpos000,
const EventContext& ctx)
const {
1748 delete Muon2dSegComb;
1750 return Muon4dSegComb;
1755 bool use2LaySegsPhi)
const {
1785 cov(0, 0) = phicov(0, 0);
1786 cov(2, 2) = phicov(2, 2);
1787 cov(0, 2) = phicov(0, 2);
1789 cov(1, 1) = rcov(0, 0);
1790 cov(3, 3) = rcov(2, 2);
1791 cov(1, 3) = rcov(0, 2);
1792 cov(3, 1) = rcov(1, 3);
1806 xf.pretranslate(glop);
1810 }
else if (bnd_rtrap) {
1813 ATH_MSG_WARNING(
" no SurfaceBounds bounds for 4D segment found keep old bound ");
1822 ATH_MSG_VERBOSE(
" positions in NEW Eta frame for phi measurement x " << phietalpos.x() <<
" y " << phietalpos.y() <<
" z shift "
1823 << phietalpos.z() <<
" angleXZ " << phidir);
1824 double phiposNew = phietalpos.x() - phidir * phietalpos.z();
1826 ATH_MSG_VERBOSE(
" positions old z " << phipos <<
" New frame " << phietalpos.x() <<
" corrected " << phiposNew);
1836 unsigned int nMinRIOsEta = 3, nMinRIOsPhi = 3;
1837 if (use2LaySegsEta) nMinRIOsEta = 2;
1838 if (use2LaySegsPhi) nMinRIOsPhi = 2;
1839 if (etarios.size() >= nMinRIOsEta && phirios.size() >= nMinRIOsPhi) {
1841 ATH_MSG_DEBUG(
" eta/phi segment sizes: " << etarios.size() <<
" " << phirios.size());
1844 int maxeta = etarios.size();
1845 int maxphi = phirios.size();
1848 int eta_matchcode = 6;
1849 int phi_matchcode = 6;
1850 if (maxeta == 3) eta_matchcode = 3;
1851 if (maxphi == 3) phi_matchcode = 3;
1852 int eta_match = 0, phi_match = 0;
1856 for (
int ieta = 0; ieta < maxeta; ieta++) {
1857 for (
int iphi = 0; iphi < maxphi; iphi++) {
1864 int iw_eta =
m_idHelperSvc->cscIdHelper().wireLayer(id_eta);
1865 int iw_phi =
m_idHelperSvc->cscIdHelper().wireLayer(id_phi);
1868 if (iw_eta != iw_phi) {
continue; }
1886 << std::setprecision(9) <<
" etapos: r " << etapold->
globalPosition().perp() <<
" z "
1888 << surf << std::endl
1892 <<
" locpos " << locPos.x() <<
" " << locPos.y() <<
" " << locPos.z() <<
" locposS " << locPosS.x()
1893 <<
" " << locPosS.y() <<
" " << locPosS.z() <<
" inbounds " << surf.
insideBounds(lpn) <<
" normals "
1895 << locNorm.x() <<
" " << locNorm.y() <<
" " << locNorm.z());
1902 eta_matchcode -= ieta;
1903 phi_matchcode -= iphi;
1913 rios.push_back(etaRot);
1916 rios.push_back(phiRot);
1929 int eta_single = maxeta - eta_match;
1930 int phi_single = maxphi - phi_match;
1932 ATH_MSG_DEBUG(
" eta_single, phi_single: " << eta_single <<
" " << phi_single <<
" eta_matchcode, phi_matchcode: " << eta_matchcode
1933 <<
" " << phi_matchcode);
1937 if (eta_single == 1) {
1938 if (eta_matchcode >= 0 && eta_matchcode < 4) {
1941 rios.push_back(pnew);
1945 else if (eta_single > 1) {
1949 if (eta_single != 0) {
1950 ATH_MSG_DEBUG(
"eta hit in a 2-layer segment not matched, bailing");
1958 if (phi_single == 1) {
1959 if (phi_matchcode >= 0 && phi_matchcode < 4) {
1962 rios.push_back(pnew);
1966 else if (phi_single > 1) {
1970 if (phi_single != 0) {
1971 ATH_MSG_DEBUG(
"phi hit in a 2-layer segment not matched, bailing");
1977 ATH_MSG_WARNING(
"Unexpected input RIO counts: " << etarios.size() <<
" " << phirios.size());
1978 for (ICscSegmentFinder::RioList::const_iterator irio = etarios.begin(); irio != etarios.end(); ++irio) {
1981 rios.push_back(pnew);
1983 for (ICscSegmentFinder::RioList::const_iterator irio = phirios.begin(); irio != phirios.end(); ++irio) {
1986 rios.push_back(pnew);
1990 unsigned int nMinRIOsTot = 5;
1991 if (use2LaySegsEta || use2LaySegsPhi) nMinRIOsTot = 4;
1992 if (rios.size() < nMinRIOsTot) {
1993 ATH_MSG_WARNING(
"too few CSC hits collected, not making segment: rios " << rios.size());
2018 int etaStat,
int phiStat)
const {
2025 int col_station =
m_idHelperSvc->cscIdHelper().stationName(chId) - 49;
2026 int col_eta =
m_idHelperSvc->cscIdHelper().stationEta(chId);
2027 int col_phisec =
m_idHelperSvc->cscIdHelper().stationPhi(chId);
2029 ATH_MSG_DEBUG(
"get2dSegments called " << eta_id <<
" " << phi_id <<
" " << col_station <<
" " << col_eta <<
" " << col_phisec
2030 <<
" " << etaStat <<
" " << phiStat <<
" "
2031 <<
" Counts: " << eta_clus[0].
size() <<
" " << eta_clus[1].
size() <<
" " << eta_clus[2].
size()
2032 <<
" " << eta_clus[3].
size());
2036 double pos_eta = -999;
2037 double slope_eta = -999;
2038 double pos_phi = -999;
2039 double slope_phi = -999;
2042 find_2dsegments(
false, col_station, col_eta, col_phisec, eta_clus, lpos000, eta_segs, pos_eta, slope_eta, ctx);
2043 find_2dsegments(
true, col_station, col_eta, col_phisec, phi_clus, lpos000, phi_segs, pos_phi, slope_phi, ctx);
2046 find_2dseg3hit(
false, col_station, col_eta, col_phisec, eta_clus, lpos000, eta_segs3hit, eta_segs, pos_eta, slope_eta, ctx);
2047 find_2dseg3hit(
true, col_station, col_eta, col_phisec, phi_clus, lpos000, phi_segs3hit, phi_segs, pos_phi, slope_phi, ctx);
2053 int nGoodEta = 0, nGoodPhi = 0;
2054 for (
int i = 0;
i < 4; ++
i) {
2058 if (nGoodEta == 2) {
2063 find_2dseg2hit(
false, col_station, col_eta, col_phisec, etaStat, eta_clus, lpos000, eta_segs2hit, pos_eta, slope_eta, ctx);
2069 if (nGoodPhi == 2) {
2073 find_2dseg2hit(
true, col_station, col_eta, col_phisec, phiStat, phi_clus, lpos000, phi_segs2hit, pos_phi, slope_phi, ctx);
2085 int nclus = fitclus.size();
2086 ATH_MSG_VERBOSE(
" unique_hits nclus " << nclus <<
" segs size " << segs.size());
2088 ICscSegmentFinder::Segments::const_iterator iseg;
2089 for (iseg = segs.begin(); iseg != segs.end(); ++iseg) {
2090 int nhits_common = 0;
2092 for (
int iclus = 0; iclus < iseg->nclus; iclus++) {
2094 ICscSegmentFinder::TrkClusters::const_iterator ihit;
2095 for (ihit = fitclus.begin(); ihit != fitclus.end(); ++ihit) {
2112 const EventContext& ctx)
const {
2114 for (
int iclu = 0; iclu < seg.
nclus; ++iclu) {
2117 if (pclu !=
nullptr) {
2148 const std::vector<Identifier>& strip_ids = prd->
rdoList();
2149 unsigned int nstrip = strip_ids.size();
2152 if (MuonDetMgr ==
nullptr) {
2153 ATH_MSG_ERROR(
"Null pointer to the read MuonDetectorManager conditions object");
2159 double wmeas = pitch * nstrip;
2160 double weff = wmeas - 20;
2161 double weffmin = 0.5 * wmeas;
2162 if (weff < weffmin) weff = weffmin;
2163 double err = weff / std::sqrt(12.0);
2174 int maxeta = etarios.size();
2175 int maxphi = phirios.size();
2177 double prob_real = 1, prob_ghost = 1;
2179 for (
int ieta = 0; ieta < maxeta; ieta++) {
2180 for (
int iphi = 0; iphi < maxphi; iphi++) {
2204 int eta_wlay =
m_idHelperSvc->cscIdHelper().wireLayer(eta_sid);
2205 int phi_wlay =
m_idHelperSvc->cscIdHelper().wireLayer(phi_sid);
2208 if (eta_wlay == phi_wlay) {
2210 double eta_chg = eta_prd->
charge();
2211 double phi_chg = phi_prd->
charge();
2213 if (eta_chg > 0 && phi_chg > 0) {
2214 qratio = eta_chg / phi_chg;
2216 prob_ghost *=
pdf_bkg(qratio);
2228 if (
match)
return 0.5;
2229 if (!
match)
return 0.;
2237 double par[6] = {1.25049, 1.02934, 0.0517436, 0.0229711, 0.900799, 0.374422};
2240 if (
x > 10)
return 0.015619;
2255 double par[8] = {0.0394188, 0.0486057, 0.0869231, 1.16153, -0.109998, 0.009729, 0.36183, 0.228344};
2258 if (
x > 10)
return 0.0895146;
2287 bool is_good = !((
status & 0x1) || ((
status >> 1) & 0x1));
2296 if (!readCdo->readChannelStatus(stripHashId,
status).isSuccess())
2297 ATH_MSG_WARNING(
" failed to access CSC conditions database - status - "
2298 <<
"strip hash id = " << stripHashId);