363 const std::array<std::vector<int>,8> & hitIdByLayer,
364 std::vector<std::array<int, 8>>& hitIdsCandidate)
const
366 double NSWCenterZ = 7526.329;
370 for (
unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
371 if ( hitIdByLayer[iLayer].
size() > 0) {
372 side = std::abs(stgcHits.at(hitIdByLayer[iLayer].at(0)).z)/stgcHits.at(hitIdByLayer[iLayer].at(0)).z;
373 if ( stgcHits.at(hitIdByLayer[iLayer].at(0)).channelType == 1 ){
379 NSWCenterZ = NSWCenterZ * side;
381 std::array<std::vector<unsigned long int>,4> hitIdsInTwo;
382 std::array<std::vector<double>,4> slopeInTwo;
383 std::array<std::vector<double>,4> interceptInTwo;
386 for(
unsigned int iPair = 0; iPair < 4; ++iPair){
387 unsigned int nHitsInInner = hitIdByLayer[iPair].size();
388 unsigned int nHitsInOuter = hitIdByLayer[iPair+4].size();
389 if ( nHitsInInner > 0xffff-1 || nHitsInOuter > 0xffff-1) {
390 ATH_MSG_WARNING(
"Number of Stgc hits in layers exceeds the limit of (2^16 - 1) : Number of Stgc hits in "<<iPair<<
"th layer = "<< nHitsInInner
391 <<
", Number of Stgc hits in "<<iPair+4<<
"th layer = "<<nHitsInOuter);
392 ATH_MSG_WARNING(
"Number of Stgc hits is limitted to (2^16 - 1) and hits with id more than (2^16 -1) will be trancated.");
393 if (nHitsInInner > 0xffff-1) {nHitsInInner = 0xffff-1;}
394 if (nHitsInOuter > 0xffff-1) {nHitsInOuter = 0xffff-1;}
397 std::array<bool, 256> foundCounterparts{};
399 for(
unsigned int iHit = 0; iHit < nHitsInInner; ++iHit){
400 bool foundCounterpart = 0;
405 int iHitId = hitIdByLayer[iPair].at(iHit);
407 r[0] = stgcHits.at(iHitId).r;
408 z[0] = stgcHits.at(iHitId).z;
410 double localPhiCenter;
411 if (stgcHits.at(iHitId).stationPhi<=5) {
412 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHitId).stationPhi-1.);
414 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHitId).stationPhi-9.);
417 if (stgcHits.at(iHitId).stationName == 57){
418 localPhiCenter +=
M_PI/8.;
419 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2. *
M_PI;
422 double phiProj = stgcHits.at(iHitId).phi - localPhiCenter;
423 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
424 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
425 r[0] = stgcHits.at(iHitId).r;
430 for(
unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
431 int jHitId = hitIdByLayer[iPair+4].at(jHit);
432 double slope, intercept;
434 r[1] = stgcHits.at(jHitId).r;
435 z[1] = stgcHits.at(jHitId).z;
436 slope = (
r[1] -
r[0]) / (
z[1] -
z[0]);
437 intercept = slope*(0. -
z[0]) +
r[0];
439 if(std::abs(slope) < 0.14 || std::abs(slope) > 0.6 || std::abs(intercept) > 300.)
continue;
441 double localPhiCenter;
442 if (stgcHits.at(jHitId).stationPhi<=5) {
443 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(jHitId).stationPhi-1.);
445 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(jHitId).stationPhi-9.);
448 if (stgcHits.at(jHitId).stationName == 57){
449 localPhiCenter +=
M_PI/8.;
450 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
453 double phiProj = stgcHits.at(jHitId).phi - localPhiCenter;
454 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
455 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
456 r[1] = stgcHits.at(jHitId).r;
458 slope = (
z[0]+
z[1])/2.;
459 intercept = (
r[0]+
r[1])/2.;
460 if(std::abs(
r[0]*std::sin(
z[0]) -
r[1]*std::sin(
z[1])) > 300.)
continue;
463 unsigned int encodedIds = (iHitId<<16) + jHitId;
464 hitIdsInTwo[iPair].push_back(encodedIds);
465 slopeInTwo[iPair].push_back(slope);
466 interceptInTwo[iPair].push_back(intercept);
468 foundCounterpart = 1;
469 foundCounterparts.at(jHit) = 1;
471 if(!foundCounterpart){
472 unsigned int encodedIds = (iHitId<<16) + 0xffff;
473 hitIdsInTwo[iPair].push_back(encodedIds);
475 slopeInTwo[iPair].push_back(
r[0]/
z[0]);
476 interceptInTwo[iPair].push_back(0.);
478 slopeInTwo[iPair].push_back(
z[0]);
479 interceptInTwo[iPair].push_back(
r[0]);
484 for(
unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
485 if (!foundCounterparts.at(jHit)) {
486 int jHitId = hitIdByLayer[iPair+4].at(jHit);
487 unsigned int encodedIds = 0xffff0000 + jHitId;
488 hitIdsInTwo[iPair].push_back(encodedIds);
490 slopeInTwo[iPair].push_back(stgcHits.at(jHitId).r/stgcHits.at(jHitId).z);
491 interceptInTwo[iPair].push_back(0.);
493 double localPhiCenter;
494 if (stgcHits.at(jHitId).stationPhi<=5) {
495 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(jHitId).stationPhi-1.);
497 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(jHitId).stationPhi-9.);
499 if (stgcHits.at(jHitId).stationName == 57){
500 localPhiCenter +=
M_PI/8.;
501 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
504 double phiProj = stgcHits.at(jHitId).phi - localPhiCenter;
505 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
506 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
507 slopeInTwo[iPair].push_back(phiProj);
508 interceptInTwo[iPair].push_back(stgcHits.at(jHitId).r);
514 ATH_MSG_DEBUG(
"@@STGC@@ isStrip= " << isStrip <<
" Npairs " << hitIdsInTwo[0].
size() <<
" " << hitIdsInTwo[1].
size() <<
" " << hitIdsInTwo[2].
size() <<
" " << hitIdsInTwo[3].
size());
515 for (
unsigned int iLayer = 0; iLayer < 4; ++ iLayer) {
516 for (
unsigned int iPair = 0; iPair < slopeInTwo[iLayer].size(); ++iPair) {
517 ATH_MSG_DEBUG(
"@@STGC@@ pair fit isStrip= " << isStrip <<
" slope= " << slopeInTwo[iLayer].at(iPair) <<
" intercept= " << interceptInTwo[iLayer].at(iPair));
521 std::array<std::vector<unsigned long int>,2> hitIdsInFour;
522 std::array<std::vector<double>,2> slopeInFour;
523 std::array<std::vector<double>,2> interceptInFour;
524 for(
unsigned int iQuad = 0; iQuad < 2; ++iQuad){
525 unsigned int nPairsInInner = hitIdsInTwo[iQuad].size();
526 unsigned int nPairsInOuter = hitIdsInTwo[iQuad+2].size();
528 std::array<bool, 0xffff> foundCounterparts{};
529 for(
unsigned int iPair = 0; iPair < nPairsInInner; ++iPair){
530 bool foundCounterpart = 0;
533 slope[0] = slopeInTwo[iQuad].at(iPair);
534 intercept[0] = interceptInTwo[iQuad].at(iPair);
536 for(
unsigned int jPair = 0; jPair < nPairsInOuter; ++jPair){
537 unsigned int ihitIds = hitIdsInTwo[iQuad].at(iPair);
538 unsigned int jhitIds = hitIdsInTwo[iQuad+2].at(jPair);
539 if ( !(((ihitIds>>16 & 0xffff) != 0xffff || (ihitIds & 0xffff) != 0xffff) &&
540 ((jhitIds>>16 & 0xffff) != 0xffff || (jhitIds & 0xffff) != 0xffff )) )
continue;
542 slope[1] = slopeInTwo[iQuad+2].at(jPair);
543 intercept[1] = interceptInTwo[iQuad+2].at(jPair);
546 double spR0 = slope[0] * NSWCenterZ + intercept[0];
547 double spR1 = slope[1] * NSWCenterZ + intercept[1];
548 if(std::abs(spR1 - spR0) > 50.)
continue;
550 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100.)
continue;
553 foundCounterpart = 1;
554 foundCounterparts[jPair] = 1;
556 unsigned long int encodedIds = (hitIdsInTwo[iQuad].at(iPair) << 32 ) + hitIdsInTwo[iQuad+2].at(jPair);
557 hitIdsInFour[iQuad].push_back(encodedIds);
558 slopeInFour[iQuad].push_back((slope[1] + slope[0])/2.);
559 interceptInFour[iQuad].push_back((intercept[1] + intercept[0])/2.);
562 if(foundCounterpart)
continue;
563 if((hitIdsInTwo[iQuad].at(iPair)>>16 & 0xffff) == 0xffff || (hitIdsInTwo[iQuad].at(iPair) & 0xffff) == 0xffff)
continue;
565 unsigned long int encodedIds = (hitIdsInTwo[iQuad].at(iPair) << 32 ) + 0xffffffff;
566 hitIdsInFour[iQuad].push_back(encodedIds);
567 slopeInFour[iQuad].push_back(slope[0]);
568 interceptInFour[iQuad].push_back(intercept[0]);
570 for (
unsigned int jPair = 0; jPair < nPairsInOuter; ++jPair) {
571 if(foundCounterparts[jPair])
continue;
572 if((hitIdsInTwo[iQuad+2].at(jPair)>>16 & 0xffff) == 0xffff || (hitIdsInTwo[iQuad+2].at(jPair) & 0xffff) == 0xffff)
continue;
574 unsigned long int encodedIds = (0xffffffff00000000 ) + hitIdsInTwo[iQuad+2].at(jPair);
575 hitIdsInFour[iQuad].push_back(encodedIds);
576 slopeInFour[iQuad].push_back(slopeInTwo[iQuad+2].at(jPair));
577 interceptInFour[iQuad].push_back(interceptInTwo[iQuad+2].at(jPair));
581 ATH_MSG_DEBUG(
"@@STGC@@ isStrip= " << isStrip <<
" Nquads " << hitIdsInFour[0].
size() <<
" " << hitIdsInFour[1].
size());
582 for (
unsigned int iLayer = 0; iLayer < 2; ++ iLayer) {
583 for (
unsigned int iQuad = 0; iQuad < slopeInFour[iLayer].size(); ++iQuad) {
584 ATH_MSG_DEBUG(
"@@STGC@@ quad fit isStrip= " << isStrip <<
" slope= " << slopeInFour[iLayer].at(iQuad) <<
" intercept= " << interceptInFour[iLayer].at(iQuad));
588 std::vector< std::array<int, 8> > hitIdsInEight;
589 std::vector<double> mseInEight;
591 unsigned int nQuadInInner = hitIdsInFour[0].size();
592 unsigned int nQuadInOuter = hitIdsInFour[1].size();
594 for(
unsigned int iQuad = 0; iQuad < nQuadInInner; ++iQuad){
597 slope[0] = slopeInFour[0].at(iQuad);
598 intercept[0] = interceptInFour[0].at(iQuad);
600 for(
unsigned int jQuad = 0; jQuad < nQuadInOuter; ++jQuad){
601 unsigned long int ihitIds = hitIdsInFour[0].at(iQuad);
602 unsigned long int jhitIds = hitIdsInFour[1].at(jQuad);
603 int nOfLayersWithNoHit = 0;
604 for (
unsigned int iLayer = 0; iLayer < 4; ++iLayer) {
605 if ( (ihitIds>>(3-iLayer)*16 & 0xffff) == 0xffff ) {++nOfLayersWithNoHit;}
606 if ( (jhitIds>>(3-iLayer)*16 & 0xffff) == 0xffff ) {++nOfLayersWithNoHit;}
608 if (nOfLayersWithNoHit > 4)
continue;
610 slope[1] = slopeInFour[1].at(jQuad);
611 intercept[1] = interceptInFour[1].at(jQuad);
614 double spR0 = slope[0] * NSWCenterZ + intercept[0];
615 double spR1 = slope[1] * NSWCenterZ + intercept[1];
616 if(std::abs(spR1 - spR0) > 10. ||
617 std::abs(intercept[1] + intercept[0]) / 2 > 100.)
continue;
619 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100. )
continue;
622 std::array<int,8> setOfHitIds = {-1,-1,-1,-1,-1,-1,-1,-1};
623 std::vector<double>
r,
z;
624 for(
unsigned int i = 0; i < 8; ++i) {
625 unsigned int iHitId, iLayer = 0;
627 iHitId = (
unsigned int) ((ihitIds>>(3-i)*16) & 0xffff);
630 iHitId = (
unsigned int) ((jhitIds>>(3-i%4)*16) & 0xffff);
631 iLayer = (i-4)+3*(i%2)+1;
633 if ( iHitId != 0xffff ) {
635 r.push_back(stgcHits.at(iHitId).r);
636 z.push_back(stgcHits.at(iHitId).z);
639 double localPhiCenter;
640 if (stgcHits.at(iHitId).stationPhi<=5) {
641 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHitId).stationPhi-1.);
643 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHitId).stationPhi-9.);
645 if (stgcHits.at(iHitId).stationName == 57){
646 localPhiCenter +=
M_PI/8.;
647 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
650 double phiProj = stgcHits.at(iHitId).phi - localPhiCenter;
651 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
652 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
653 r.push_back(phiProj);
654 z.push_back(stgcHits.at(iHitId).r);
656 setOfHitIds[iLayer] = iHitId;
657 ATH_MSG_DEBUG(
"@@STGC@@ strip_pos iHitId " << iLayer <<
" " << iHitId);
660 double slopefit=0., interceptfit=99999., mse =-1.;
665 for (
unsigned int iHit = 0; iHit <
r.size(); ++iHit){
666 phiavg +=
r.at(iHit);
670 for (
unsigned int iHit = 0; iHit <
r.size(); ++iHit){
671 mse += std::pow(
r.at(iHit) - phiavg,2);
674 hitIdsInEight.push_back(setOfHitIds);
675 mseInEight.push_back(mse);
678 if(!hitIdsInEight.size()){
683 ATH_MSG_DEBUG(
"@@STGC@@ isStrip= " << isStrip <<
" Noctets " << hitIdsInEight.size());
684 std::vector<int> nOctetSegments;
685 std::vector<int> patternStationName;
687 for (
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet) {
689 bool isFirstHit =
true;
690 int hitStationName = 0;
692 int nOctetSegment = 0;
693 ATH_MSG_DEBUG(
"@@STGC@@ octet fit isStrip= " << isStrip <<
" mse " << mseInEight.at(iOctet));
694 std::array<int, 8> tmpOctet = hitIdsInEight.at(iOctet);
695 for (
unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
696 if (tmpOctet[iLayer] != -1) {
699 hitStationName = stgcHits.at(tmpOctet[iLayer]).stationName;
702 ATH_MSG_DEBUG(
"@@STGC@@ octet pos isStrip= " << isStrip <<
" r= " << stgcHits.at(tmpOctet[iLayer]).r <<
" phi= " << stgcHits.at(tmpOctet[iLayer]).phi <<
" z= " << stgcHits.at(tmpOctet[iLayer]).z);
705 else if(stgcHits.at(tmpOctet[iLayer]).stationName == hitStationName){
706 ATH_MSG_DEBUG(
"@@STGC@@ octet pos isStrip= " << isStrip <<
" r= " << stgcHits.at(tmpOctet[iLayer]).r <<
" phi= " << stgcHits.at(tmpOctet[iLayer]).phi <<
" z= " << stgcHits.at(tmpOctet[iLayer]).z);
711 nOctetSegments.push_back(nOctetSegment);
712 patternStationName.push_back(hitStationName);
714 double nOcSegMax = 0;
715 for(
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
716 if(nOctetSegments.at(iOctet) > nOcSegMax){
717 nOcSegMax = nOctetSegments.at(iOctet);
721 double msemin = 1000000.;
722 double mseminWireL = 1000000.;
723 double mseminWireS = 1000000.;
725 std::vector<int> octetIds(2,-1);
728 for(
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
729 if(nOctetSegments.at(iOctet) != nOcSegMax){
732 if( mseInEight.at(iOctet) < msemin) {
733 msemin = mseInEight.at(iOctet);
736 for(
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
737 if(nOctetSegments.at(iOctet) != nOcSegMax)
continue;
738 if(mseInEight.at(iOctet) != msemin){
741 octetIds.push_back(iOctet);
744 for(
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
745 if(patternStationName.at(iOctet) == 58){
746 if( mseInEight.at(iOctet) < mseminWireL) {
747 mseminWireL = mseInEight.at(iOctet);
750 else if(patternStationName.at(iOctet) == 57){
751 if( mseInEight.at(iOctet) < mseminWireS) {
752 mseminWireS = mseInEight.at(iOctet);
756 for(
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
757 if(patternStationName.at(iOctet) == 58){
758 if(mseInEight.at(iOctet) != mseminWireL){
762 else if(patternStationName.at(iOctet) == 57){
763 if(mseInEight.at(iOctet) != mseminWireS){
767 octetIds.push_back(iOctet);
770 for(
unsigned int ids = 0; ids < octetIds.size(); ids++){
771 if (octetIds.at(ids) != -1) {
772 hitIdsCandidate.push_back(hitIdsInEight.at(octetIds.at(ids)));
937 std::vector<double>
r,
z;
938 std::vector<bool> isStgc;
939 for(
unsigned int iHit = 0; iHit < stgcHits.size(); ++iHit) {
940 if (stgcHits.at(iHit).channelType == 1) {
941 r.push_back(stgcHits.at(iHit).r);
942 z.push_back(stgcHits.at(iHit).z);
943 isStgc.push_back(
true);
946 for(
unsigned int iHit = 0; iHit < mmHits.size(); ++iHit) {
947 if (mmHits.at(iHit).layerNumber < 2 || mmHits.at(iHit).layerNumber > 5) {
948 r.push_back(mmHits.at(iHit).r);
949 z.push_back(mmHits.at(iHit).z);
950 isStgc.push_back(
false);
951 side_mm = std::abs(mmHits.at(iHit).z)/mmHits.at(iHit).z;
954 double slopefit=0., interceptfit=99999., mse=-1.;
957 ATH_MSG_DEBUG(
"@@Merge@@ stgc_mmX_fit intercept= " << interceptfit);
960 std::vector<double> phiLocal;
961 double localPhiCenter = 3.*
M_PI;
962 for (
unsigned int iHit = 0; iHit < stgcHits.size(); ++iHit) {
963 if (stgcHits.at(iHit).channelType != 2) {
continue;}
964 if (stgcHits.at(iHit).stationPhi<=5) {
965 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHit).stationPhi-1.);
967 localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHit).stationPhi-9.);
970 if (stgcHits.at(iHit).stationName == 57){
971 localPhiCenter +=
M_PI/8.;
972 if (stgcHits.at(iHit).stationPhi == 5) localPhiCenter -= 2. *
M_PI;
975 double phiProj = stgcHits.at(iHit).phi - localPhiCenter;
976 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
977 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
978 double rInterpolate = slopefit * stgcHits.at(iHit).z + interceptfit;
979 double rProj = stgcHits.at(iHit).r;
980 phiLocal.push_back( std::atan(rProj/rInterpolate*std::tan(phiProj)) );
981 ATH_MSG_DEBUG(
"@@Merge@@ philocalwire " << stgcHits.at(iHit).stationPhi <<
" " << stgcHits.at(iHit).stationName <<
" "
982 << localPhiCenter <<
" " << stgcHits.at(iHit).phi <<
" " << stgcHits.at(iHit).r <<
" " << stgcHits.at(iHit).z);
983 ATH_MSG_DEBUG(
"@@Merge@@ philocalwire " << rProj <<
" " << rInterpolate <<
" " << std::tan(phiProj) );
984 ATH_MSG_DEBUG(
"@@Merge@@ philocalwire " << std::atan(rProj/rInterpolate*std::tan(phiProj)) );
986 double tanTiltAngleU = 0,
988 double cosTiltAngleU = 0,
990 double sinTiltAngleU = 0,
1007 ATH_MSG_DEBUG(
"@@Merge@@ no U, V layer hits -> not consider tilt of U/V layers");
1009 for (
unsigned int iHit = 0; iHit < mmHits.size(); ++iHit) {
1010 if (localPhiCenter > 2.*
M_PI) {
1011 if (mmHits.at(iHit).stationPhi<=5) {
1012 localPhiCenter = 0.25 *
M_PI * ((double)mmHits.at(iHit).stationPhi-1.);
1014 localPhiCenter = 0.25 *
M_PI * ((double)mmHits.at(iHit).stationPhi-9.);
1016 if (mmHits.at(iHit).stationName == 55){
1017 localPhiCenter +=
M_PI/8.;
1018 if (mmHits.at(iHit).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
1021 if (mmHits.at(iHit).layerNumber >1 && mmHits.at(iHit).layerNumber < 6){
1022 double rInterpolate = slopefit * mmHits.at(iHit).z + interceptfit;
1023 if (rInterpolate == 0. or tanTiltAngleU == 0.)[[
unlikely]]{
1024 throw std::runtime_error(
"NswStationFitter::calcMergedHit: divisor is zero.");
1026 double rProj = mmHits.at(iHit).r;
1028 phiLocal.push_back(0);
1031 else if ((mmHits.at(iHit).layerNumber)%2 == 0) {
1032 phiLocal.push_back( std::atan((rProj-rInterpolate)/tanTiltAngleU/rInterpolate));
1033 ATH_MSG_DEBUG(
"@@Merge@@ philocalmmU " << std::atan((rProj-rInterpolate)/tanTiltAngleU/rInterpolate));
1035 phiLocal.push_back( std::atan((rProj-rInterpolate)/tanTiltAngleV/rInterpolate));
1036 ATH_MSG_DEBUG(
"@@Merge@@ philocalmmV " << std::atan((rProj-rInterpolate)/tanTiltAngleV/rInterpolate));
1040 double sumPhiLocal = 0;
1041 for (
unsigned int iHit = 0; iHit < phiLocal.size(); ++iHit ) {
1042 sumPhiLocal += phiLocal.at(iHit);
1044 double phiLocalAvg = sumPhiLocal/phiLocal.size();
1050 std::vector<double> r_stgc, z_stgc, r_mm, z_mm;
1051 std::vector<bool> isStgc_stgc, isStgc_mm;
1052 double side_stgc = 0;
1053 for(
unsigned int iHit = 0; iHit < stgcHits.size(); ++iHit) {
1054 if (stgcHits.at(iHit).stationPhi<=5) localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHit).stationPhi-1.);
1055 if (stgcHits.at(iHit).stationPhi> 5) localPhiCenter = 0.25 *
M_PI * ((double)stgcHits.at(iHit).stationPhi-9.);
1056 if (stgcHits.at(iHit).channelType == 1) {
1057 r_stgc.push_back(stgcHits.at(iHit).r/std::cos(phiLocalAvg));
1058 z_stgc.push_back(stgcHits.at(iHit).z);
1059 isStgc_stgc.push_back(
true);
1060 side_stgc = std::abs(stgcHits.at(iHit).z)/stgcHits.at(iHit).z;
1062 ATH_MSG_DEBUG(
"@@Merge@@ stgc strip_r " << phiLocalAvg <<
" " << stgcHits.at(iHit).z <<
" " << stgcHits.at(iHit).r/std::cos(phiLocalAvg));
1066 double slopefit_stgc=0., interceptfit_stgc=99999., mse_stgc=1.e20;
1067 if(r_stgc.size() == 0) {
1070 LinearFit(z_stgc,r_stgc,&slopefit_stgc,&interceptfit_stgc,&mse_stgc);
1073 for(
unsigned int iHit = 0; iHit < mmHits.size(); ++iHit) {
1074 if (mmHits.at(iHit).layerNumber < 2 || mmHits.at(iHit).layerNumber > 5) {
1075 r_mm.push_back(mmHits.at(iHit).r/std::cos(phiLocalAvg));
1076 z_mm.push_back(mmHits.at(iHit).z);
1077 isStgc_mm.push_back(
false);
1079 z_mm.push_back(mmHits.at(iHit).z);
1080 isStgc_mm.push_back(
false);
1082 double rProj = mmHits.at(iHit).r;
1084 r_mm.push_back(rProj);
1086 else if ((mmHits.at(iHit).layerNumber)%2 == 0) {
1087 double rPrime = (rProj * cosTiltAngleU)/(cos(phiLocalAvg)*cosTiltAngleU + sin(phiLocalAvg)*sinTiltAngleU);
1088 r_mm.push_back(rPrime);
1090 double rPrime = (rProj * cosTiltAngleV)/(cos(phiLocalAvg)*cosTiltAngleV + sin(phiLocalAvg)*sinTiltAngleV);
1091 r_mm.push_back(rPrime);
1095 double slopefit_mm=0., interceptfit_mm=99999., mse_mm=1.e20;
1096 if(r_mm.size() == 0) {
1099 LinearFit(z_mm,r_mm,&slopefit_mm,&interceptfit_mm,&mse_mm);
1102 unsigned int fmerge = 0;
1103 slopefit=0., interceptfit=99999., mse=1.e20;
1105 double StgcSegZ = 7526.329;
1106 double StgcSegR = 0;
1107 double MmSegZ = 7526.329;
1109 if (mse_stgc < 1.e7 && mse_mm < 1.e7) {
1111 copy(r_mm.begin(), r_mm.end(), back_inserter(
r));
1113 copy(z_mm.begin(), z_mm.end(), back_inserter(
z));
1114 isStgc = isStgc_stgc;
1115 copy(isStgc_mm.begin(), isStgc_mm.end(), back_inserter(isStgc));
1118 StgcSegZ = -7526.329;
1120 StgcSegR = slopefit_stgc * StgcSegZ + interceptfit_stgc;
1121 double StgcSegOriginTheta = std::atan(StgcSegR / StgcSegZ);
1122 double StgcSegEta = side_stgc * (- std::log(std::abs(std::tan(StgcSegOriginTheta / 2))));
1126 MmSegR = slopefit_mm * MmSegZ + interceptfit_mm;
1127 double MmSegOriginTheta = std::atan(MmSegR / MmSegZ);
1128 double MmSegEta = side_stgc * (- std::log(std::abs(std::tan(MmSegOriginTheta / 2))));
1130 double SegEtaAve = 0;
1132 if(side_stgc*side_mm > 0){
1134 SegEtaAve = (StgcSegEta + MmSegEta)/2;
1135 }
else if(std::abs(side_stgc) <
ZERO_LIMIT) {
1137 SegEtaAve = MmSegEta;
1140 SegEtaAve = StgcSegEta;
1148 if (mse_stgc < mse_mm) {
1149 slopefit = slopefit_stgc;
1150 interceptfit = interceptfit_stgc;
1152 z = std::move(z_stgc);
1156 slopefit = slopefit_mm;
1157 interceptfit = interceptfit_mm;
1159 z = std::move(z_mm);
1166 return StatusCode::SUCCESS;
1172 double NSWCenterZ = 7526.329;
1174 NSWCenterZ = -7526.329;
1176 superPoint->
R = slopefit * NSWCenterZ + interceptfit;
1177 superPoint->
Phim = phiLocalAvg+localPhiCenter;
1178 superPoint->
Z = NSWCenterZ;
1179 superPoint->
Npoint =
z.size();
1181 if (NSWCenterZ != 0) superPoint->
Alin = slopefit;
1182 superPoint->
Blin = interceptfit;
1184 ATH_MSG_DEBUG(
"Nsw Super Point r/phi/z/slope = "<<superPoint->
R<<
"/"<<superPoint->
Phim<<
"/"<<superPoint->
Z<<
"/"<<superPoint->
Alin);
1186 ATH_MSG_DEBUG(
"@@Merge@@ Nsw Super Point r/phi/z/slope = "<<superPoint->
R<<
"/"<<superPoint->
Phim<<
"/"<<superPoint->
Z<<
"/"<<superPoint->
Alin);
1187 ATH_MSG_DEBUG(
"@@Merge@@ fit slope= " << slopefit <<
" " << slopefit_stgc <<
" " << slopefit_mm);
1188 ATH_MSG_DEBUG(
"@@Merge@@ fit intercept= " << interceptfit <<
" " << interceptfit_stgc <<
" " << interceptfit_mm);
1189 ATH_MSG_DEBUG(
"@@Merge@@ fit mse= " << mse <<
" " << mse_stgc <<
" " << mse_mm);
1193 return StatusCode::SUCCESS;
1250 const std::array<std::vector<int>,8> & hitIdByLayer,
1251 std::vector<std::array<int, 8>>& hitIdsCandidate)
const
1254 double NSWCenterZ = 7526.329;
1256 for (
unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
1257 if ( hitIdByLayer[iLayer].
size() > 0) {
1258 side = std::abs(mmHits.at(hitIdByLayer[iLayer].at(0)).z)/mmHits.at(hitIdByLayer[iLayer].at(0)).z;
1262 NSWCenterZ = NSWCenterZ * side;
1264 std::array<std::vector<unsigned long int>,4> hitIdsInTwo;
1265 std::array<std::vector<double>,4> slopeInTwo;
1266 std::array<std::vector<double>,4> interceptInTwo;
1268 for(
unsigned int iPair = 0; iPair < 4; ++iPair){
1270 unsigned int nHitsInInner = hitIdByLayer[iPair].size();
1271 unsigned int nHitsInOuter;
1273 nHitsInOuter = hitIdByLayer[iPair+6].size();
1275 nHitsInOuter = hitIdByLayer[iPair+2].size();
1278 if ( nHitsInInner > 0xffff-1 || nHitsInOuter > 0xffff-1) {
1279 ATH_MSG_WARNING(
"Number of Mm hits in layers exceeds the limit of (2^16 - 1) : Number of Mm hits in "<<iPair<<
"th layer = "<< nHitsInInner
1280 <<
", Number of Mm hits in "<<iPair+4<<
"th layer = "<<nHitsInOuter);
1281 ATH_MSG_WARNING(
"Number of Mm hits is limitted to (2^16 - 1) and hits with id more than (2^16 -1) will be trancated.");
1282 if (nHitsInInner > 0xffff-1) {nHitsInInner = 0xffff-1;}
1283 if (nHitsInOuter > 0xffff-1) {nHitsInOuter = 0xffff-1;}
1286 std::array<bool, 0xffff> foundCounterparts{};
1288 for(
unsigned int iHit = 0; iHit < nHitsInInner; ++iHit){
1290 bool foundCounterpart = 0;
1295 int iHitId = hitIdByLayer[iPair].at(iHit);
1296 r[0] = mmHits.at(iHitId).r;
1297 z[0] = mmHits.at(iHitId).z;
1300 for(
unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
1304 jHitId = hitIdByLayer[iPair+6].at(jHit);
1306 jHitId = hitIdByLayer[iPair+2].at(jHit);
1308 r[1] = mmHits.at(jHitId).r;
1309 z[1] = mmHits.at(jHitId).z;
1311 double slope = (
r[1] -
r[0]) / (
z[1] -
z[0]);
1312 double intercept = slope*(0. -
z[0]) +
r[0];
1314 if(std::abs(slope) < 0.1 || std::abs(slope) > 0.7 || std::abs(intercept) > 500.)
continue;
1316 int encodedIds = (iHitId<<16) + jHitId;
1317 hitIdsInTwo[iPair].push_back(encodedIds);
1318 slopeInTwo[iPair].push_back(slope);
1319 interceptInTwo[iPair].push_back(intercept);
1321 foundCounterpart = 1;
1322 foundCounterparts[jHit] = 1;
1324 if(!foundCounterpart){
1325 int encodedIds = (iHitId<<16) + 0xffff;
1326 hitIdsInTwo[iPair].push_back(encodedIds);
1327 slopeInTwo[iPair].push_back(
r[0]/
z[0]);
1328 interceptInTwo[iPair].push_back(0.);
1332 for(
unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
1333 if (!foundCounterparts[jHit]) {
1336 jHitId = hitIdByLayer[iPair+6].at(jHit);
1338 jHitId = hitIdByLayer[iPair+2].at(jHit);
1340 int encodedIds = (0xFFFFu<<16) + jHitId;
1341 hitIdsInTwo[iPair].push_back(encodedIds);
1342 slopeInTwo[iPair].push_back(mmHits.at(jHitId).r/mmHits.at(jHitId).z);
1343 interceptInTwo[iPair].push_back(0.);
1347 ATH_MSG_DEBUG(
"@@MM@@ Npairs " << hitIdsInTwo[0].
size() <<
" " << hitIdsInTwo[1].
size() <<
" " << hitIdsInTwo[2].
size() <<
" " << hitIdsInTwo[3].
size());
1348 for (
unsigned int iLayer = 0; iLayer < 4; ++ iLayer) {
1349 for (
unsigned int iPair = 0; iPair < slopeInTwo[iLayer].size(); ++iPair) {
1350 ATH_MSG_DEBUG(
"@@MM@@ pair fit slope= " << slopeInTwo[iLayer].at(iPair) <<
" intercept= " << interceptInTwo[iLayer].at(iPair));
1354 std::vector<std::array<int, 4>> hitIdsInFourX;
1355 std::vector<double> slopeInFourX;
1356 std::vector<double> interceptInFourX;
1357 std::vector<double> mseInFourX;
1359 unsigned int nPairsInInnerX = hitIdsInTwo[0].size();
1360 unsigned int nPairsInOuterX = hitIdsInTwo[1].size();
1362 for(
unsigned int iPairX = 0; iPairX < nPairsInInnerX; ++iPairX){
1365 double intercept[2];
1368 slope[0] = slopeInTwo[0].at(iPairX);
1369 intercept[0] = interceptInTwo[0].at(iPairX);
1370 spR[0] = slope[0] * NSWCenterZ + intercept[0];
1371 for(
unsigned int jPairX = 0; jPairX < nPairsInOuterX; ++jPairX){
1372 int ihitIds = hitIdsInTwo[0].at(iPairX);
1373 int jhitIds = hitIdsInTwo[1].at(jPairX);
1374 if ( ((ihitIds>>16 & 0xffff) == 0xffff || (ihitIds & 0xffff) == 0xffff) &&
1375 ((jhitIds>>16 & 0xffff) == 0xffff || (jhitIds & 0xffff) == 0xffff ))
continue;
1377 slope[1] = slopeInTwo[1].at(jPairX);
1378 intercept[1] = interceptInTwo[1].at(jPairX);
1379 spR[1] = slope[1] * NSWCenterZ + intercept[1];
1381 if(std::abs(spR[1] - spR[0]) > 50. ||
1382 std::abs((intercept[1] + intercept[0]) / 2) > 200.)
continue;
1384 std::array<int, 4> setOfHitIds{};
1385 setOfHitIds[0] = (ihitIds>>16 & 0xffff);
1386 setOfHitIds[1] = (ihitIds & 0xffff);
1387 setOfHitIds[2] = (jhitIds>>16 & 0xffff);
1388 setOfHitIds[3] = (jhitIds & 0xffff);
1389 std::vector<double>
r;
1390 std::vector<double>
z;
1391 for(
unsigned int iLayer = 0; iLayer < 4; ++iLayer){
1392 if(setOfHitIds[iLayer] == 0xffff) {
1395 double rhit = mmHits.at(setOfHitIds[iLayer]).r;
1396 double zhit = mmHits.at(setOfHitIds[iLayer]).z;
1400 double slopefit=0., interceptfit=99999., mse=-1.;
1403 hitIdsInFourX.push_back(setOfHitIds);
1404 slopeInFourX.push_back(slopefit);
1405 interceptInFourX.push_back(interceptfit);
1406 mseInFourX.push_back(mse);
1411 for (
unsigned int iQuad = 0; iQuad < slopeInFourX.size(); ++iQuad) {
1412 ATH_MSG_DEBUG(
"@@MM@@ X quad fit slope= " << slopeInFourX.at(iQuad) <<
" intercept= " << interceptInFourX.at(iQuad) <<
" mse= " << mseInFourX.at(iQuad));
1415 if(!hitIdsInFourX.size()){
1420 double tanTiltAngleU = 0,
1423 tanTiltAngleU = tan( 1.5/360.*2.*
M_PI),
1424 tanTiltAngleV = tan(-1.5/360.*2.*
M_PI);
1426 tanTiltAngleU = tan(-1.5/360.*2.*
M_PI),
1427 tanTiltAngleV = tan(1.5/360.*2.*
M_PI);
1430 std::vector< std::array<int, 8> > hitIdsInEight;
1431 std::vector<double> mseInEight;
1433 for(
unsigned int iQuadX = 0; iQuadX < hitIdsInFourX.size(); ++iQuadX){
1434 if(mseInFourX.at(iQuadX) > 10)
continue;
1436 double slopeX = slopeInFourX.at(iQuadX);
1437 double interceptX = interceptInFourX.at(iQuadX);
1438 std::array<int,4> hitIdsX{};
1439 hitIdsX = hitIdsInFourX.at(iQuadX);
1441 for (
unsigned int iPairU = 0; iPairU < hitIdsInTwo[2].size(); ++iPairU) {
1444 hitIdsU[0] = hitIdsInTwo[2].at(iPairU)>>16 & 0xffff;
1445 hitIdsU[1] = hitIdsInTwo[2].at(iPairU) & 0xffff;
1446 double phiLocalU[2]={-99999,-99999};
1447 for(
unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1448 if (hitIdsU[iLayer] == 0xffff)
continue;
1449 if (hitIdsU[iLayer] < 0) {
1450 ATH_MSG_DEBUG(
"@@MM@@ hitIdsU[iLayer] iLayer= " << iLayer <<
" hitIdsU[iLayer]= " << hitIdsU[iLayer]);
1452 double rInterpolate = slopeX * mmHits.at(hitIdsU[iLayer]).z + interceptX;
1453 double rProj = mmHits.at(hitIdsU[iLayer]).r;
1455 phiLocalU[iLayer] = 0;
1457 phiLocalU[iLayer] = std::atan((rProj-rInterpolate)/tanTiltAngleU/rInterpolate);
1460 for(
unsigned int iPairV = 0; iPairV < hitIdsInTwo[3].size(); ++iPairV) {
1463 hitIdsV[0] = hitIdsInTwo[3].at(iPairV)>>16 & 0xffff;
1464 hitIdsV[1] = hitIdsInTwo[3].at(iPairV) & 0xffff;
1466 if( (hitIdsU[0] == 0xffff || hitIdsU[1] == 0xffff) &&
1467 (hitIdsV[0] == 0xffff || hitIdsV[1] == 0xffff) )
continue;
1469 double phiLocalV[2]={-99999,-99999};
1470 for(
unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1471 if (hitIdsV[iLayer] == 0xffff)
continue;
1472 if (hitIdsV[iLayer] < 0) {
1473 ATH_MSG_DEBUG(
"@@MM@@ hitIdsV[iLayer] iLayer= " << iLayer <<
" hitIdsV[iLayer]= " << hitIdsV[iLayer]);
1475 double rInterpolate = slopeX * mmHits.at(hitIdsV[iLayer]).z + interceptX;
1476 double rProj = mmHits.at(hitIdsV[iLayer]).r;
1478 phiLocalV[iLayer] = 0;
1480 phiLocalV[iLayer] = std::atan((rProj-rInterpolate)/tanTiltAngleV/rInterpolate);
1483 if ( std::abs(phiLocalU[0]-phiLocalV[0]) > 0.05 &&
1484 std::abs(phiLocalU[1]-phiLocalV[1]) > 0.05)
continue;
1487 double phiLocalUV = 0;
1489 for(
unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1490 if(phiLocalU[iLayer] > -99999.) {
1491 phiLocalUV += phiLocalU[iLayer];
1494 if(phiLocalV[iLayer] > -99999.) {
1495 phiLocalUV += phiLocalV[iLayer];
1501 std::array<int, 8> setOfHitIds = {-1,-1,-1,-1,-1,-1,-1,-1};
1502 std::vector<double>
r,
z;
1503 for (
unsigned int iLayer = 0; iLayer < 4; ++iLayer) {
1504 if ( hitIdsX[iLayer] != 0xffff) {
1505 if (hitIdsX[iLayer] < 0) {
1506 ATH_MSG_DEBUG(
"@@MM@@ hitIdsX[iLayer] iLayer= " << iLayer <<
" hitIdsX[iLayer]= " << hitIdsX[iLayer]);
1508 z.push_back(mmHits.at(hitIdsX[iLayer]).z);
1509 r.push_back(mmHits.at(hitIdsX[iLayer]).r / std::cos(phiLocalUV));
1510 setOfHitIds[iLayer] = hitIdsX[iLayer];
1513 for (
unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1514 if ( hitIdsU[iLayer] != 0xffff) {
1515 if (hitIdsU[iLayer] < 0) {
1516 ATH_MSG_DEBUG(
"@@MM@@ 2 hitIdsU[iLayer] iLayer= " << iLayer <<
" hitIdsU[iLayer]= " << hitIdsU[iLayer]);
1518 z.push_back(mmHits.at(hitIdsU[iLayer]).z);
1519 r.push_back(mmHits.at(hitIdsU[iLayer]).r*(std::cos(phiLocalUV) + 1/std::cos(phiLocalUV))/2.);
1520 setOfHitIds[iLayer+4] = hitIdsU[iLayer];
1522 if ( hitIdsV[iLayer] != 0xffff) {
1523 if (hitIdsV[iLayer] < 0) {
1524 ATH_MSG_DEBUG(
"@@MM@@ 2 hitIdsV[iLayer] iLayer= " << iLayer <<
" hitIdsV[iLayer]= " << hitIdsV[iLayer]);
1526 z.push_back(mmHits.at(hitIdsV[iLayer]).z);
1527 r.push_back(mmHits.at(hitIdsV[iLayer]).r*(std::cos(phiLocalUV) + 1/std::cos(phiLocalUV))/2.);
1528 setOfHitIds[iLayer+6] = hitIdsV[iLayer];
1531 double slopefit=0., interceptfit=99999., mse=-1.;
1534 hitIdsInEight.push_back(setOfHitIds);
1535 mseInEight.push_back(mse);
1541 std::vector<int> nOctetSegments;
1542 std::vector<int> patternStationName;
1543 for (
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet) {
1544 bool isFirstHit =
true;
1545 int hitStationName = 0;
1546 int nOctetSegment = 0;
1547 ATH_MSG_DEBUG(
"@@MM@@ octet fit mse " << mseInEight.at(iOctet));
1548 std::array<int, 8> tmpOctet = hitIdsInEight.at(iOctet);
1549 for (
unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
1550 if (tmpOctet[iLayer] != -1) {
1553 hitStationName = mmHits.at(tmpOctet[iLayer]).stationName;
1556 ATH_MSG_DEBUG(
"@@MM@@ octet pos r= " << mmHits.at(tmpOctet[iLayer]).r <<
" phi= " << mmHits.at(tmpOctet[iLayer]).phi <<
" z= " << mmHits.at(tmpOctet[iLayer]).z);
1559 else if(mmHits.at(tmpOctet[iLayer]).stationName == hitStationName){
1560 ATH_MSG_DEBUG(
"@@MM@@ octet pos r= " << mmHits.at(tmpOctet[iLayer]).r <<
" phi= " << mmHits.at(tmpOctet[iLayer]).phi <<
" z= " << mmHits.at(tmpOctet[iLayer]).z);
1566 nOctetSegments.push_back(nOctetSegment);
1567 patternStationName.push_back(hitStationName);
1570 double mseminL = 100000.;
1571 double mseminS = 100000.;
1572 std::vector<int> octetIds(2,-1);
1573 for(
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
1574 if(patternStationName.at(iOctet) == 56){
1575 if( mseInEight.at(iOctet) < mseminL) {
1576 mseminL = mseInEight.at(iOctet);
1579 else if(patternStationName.at(iOctet) == 55){
1580 if( mseInEight.at(iOctet) < mseminS) {
1581 mseminS = mseInEight.at(iOctet);
1586 for(
unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
1587 if(patternStationName.at(iOctet) == 56){
1588 if( mseInEight.at(iOctet) != mseminL) {
1592 else if(patternStationName.at(iOctet) == 55){
1593 if( mseInEight.at(iOctet) != mseminS) {
1597 octetIds.push_back(iOctet);
1600 for(
unsigned int ids = 0; ids < octetIds.size(); ids++){
1601 if (octetIds.at(ids) != -1) {
1602 hitIdsCandidate.push_back(hitIdsInEight.at(octetIds.at(ids)));