365{
366 double NSWCenterZ = 7526.329;
368
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 ){
375 break;
376 }
377 }
378 }
379 NSWCenterZ = NSWCenterZ *
side;
380
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;
384
385
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;}
395 }
396
397 std::array<bool, 256> foundCounterparts{};
398
399 for(unsigned int iHit = 0; iHit < nHitsInInner; ++iHit){
400 bool foundCounterpart = 0;
401
404
405 int iHitId = hitIdByLayer[iPair].at(iHit);
406 if(isStrip){
407 r[0] = stgcHits.at(iHitId).r;
408 z[0] = stgcHits.at(iHitId).z;
409 } else {
410 double localPhiCenter;
411 if (stgcHits.at(iHitId).stationPhi<=5) {
412 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-1.);
413 } else {
414 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-9.);
415 }
416
417 if (stgcHits.at(iHitId).stationName == 57){
418 localPhiCenter +=
M_PI/8.;
419 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2. *
M_PI;
420 }
421
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;
427 }
428
429
430 for(unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
431 int jHitId = hitIdByLayer[iPair+4].at(jHit);
432 double slope, intercept;
433 if(isStrip) {
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];
438
439 if(std::abs(slope) < 0.14 || std::abs(slope) > 0.6 || std::abs(intercept) > 300.) continue;
440 } else {
441 double localPhiCenter;
442 if (stgcHits.at(jHitId).stationPhi<=5) {
443 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-1.);
444 } else {
445 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-9.);
446 }
447
448 if (stgcHits.at(jHitId).stationName == 57){
449 localPhiCenter +=
M_PI/8.;
450 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
451 }
452
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;
461 }
462
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);
467
468 foundCounterpart = 1;
469 foundCounterparts.at(jHit) = 1;
470 }
471 if(!foundCounterpart){
472 unsigned int encodedIds = (iHitId<<16) + 0xffff;
473 hitIdsInTwo[iPair].push_back(encodedIds);
474 if(isStrip) {
475 slopeInTwo[iPair].push_back(
r[0]/
z[0]);
476 interceptInTwo[iPair].push_back(0.);
477 } else {
478 slopeInTwo[iPair].push_back(
z[0]);
479 interceptInTwo[iPair].push_back(
r[0]);
480 }
481 }
482 }
483
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);
489 if(isStrip) {
490 slopeInTwo[iPair].push_back(stgcHits.at(jHitId).r/stgcHits.at(jHitId).z);
491 interceptInTwo[iPair].push_back(0.);
492 } else {
493 double localPhiCenter;
494 if (stgcHits.at(jHitId).stationPhi<=5) {
495 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-1.);
496 } else {
497 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-9.);
498 }
499 if (stgcHits.at(jHitId).stationName == 57){
500 localPhiCenter +=
M_PI/8.;
501 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
502 }
503
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);
509 }
510 }
511 }
512 }
513
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));
518 }
519 }
520
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();
527
528 std::array<bool, 0xffff> foundCounterparts{};
529 for(unsigned int iPair = 0; iPair < nPairsInInner; ++iPair){
530 bool foundCounterpart = 0;
531 double slope[2];
532 double intercept[2];
533 slope[0] = slopeInTwo[iQuad].at(iPair);
534 intercept[0] = interceptInTwo[iQuad].at(iPair);
535
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;
541
542 slope[1] = slopeInTwo[iQuad+2].at(jPair);
543 intercept[1] = interceptInTwo[iQuad+2].at(jPair);
544
545 if (isStrip) {
546 double spR0 = slope[0] * NSWCenterZ + intercept[0];
547 double spR1 = slope[1] * NSWCenterZ + intercept[1];
548 if(std::abs(spR1 - spR0) > 50.) continue;
549 } else {
550 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100.) continue;
551 }
552
553 foundCounterpart = 1;
554 foundCounterparts[jPair] = 1;
555
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.);
560 }
561
562 if(foundCounterpart) continue;
563 if((hitIdsInTwo[iQuad].
at(iPair)>>16 & 0xffff) == 0xffff || (hitIdsInTwo[iQuad].
at(iPair) & 0xffff) == 0xffff)
continue;
564
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]);
569 }
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;
573
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));
578 }
579 }
580
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));
585 }
586 }
587
588 std::vector< std::array<int, 8> > hitIdsInEight;
589 std::vector<double> mseInEight;
590
591 unsigned int nQuadInInner = hitIdsInFour[0].size();
592 unsigned int nQuadInOuter = hitIdsInFour[1].size();
593
594 for(unsigned int iQuad = 0; iQuad < nQuadInInner; ++iQuad){
595 double slope[2];
596 double intercept[2];
597 slope[0] = slopeInFour[0].at(iQuad);
598 intercept[0] = interceptInFour[0].at(iQuad);
599
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;}
607 }
608 if (nOfLayersWithNoHit > 4) continue;
609
610 slope[1] = slopeInFour[1].at(jQuad);
611 intercept[1] = interceptInFour[1].at(jQuad);
612
613 if(isStrip) {
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;
618 } else {
619 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100. ) continue;
620 }
621
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;
626 if (i <= 3) {
627 iHitId = (
unsigned int) ((ihitIds>>(3-i)*16) & 0xffff);
629 } else {
630 iHitId = (
unsigned int) ((jhitIds>>(3-i%4)*16) & 0xffff);
631 iLayer = (
i-4)+3*(i%2)+1;
632 }
633 if ( iHitId != 0xffff ) {
634 if (isStrip) {
635 r.push_back(stgcHits.at(iHitId).r);
636 z.push_back(stgcHits.at(iHitId).z);
637 }
638 else {
639 double localPhiCenter;
640 if (stgcHits.at(iHitId).stationPhi<=5) {
641 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-1.);
642 } else {
643 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-9.);
644 }
645 if (stgcHits.at(iHitId).stationName == 57){
646 localPhiCenter +=
M_PI/8.;
647 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
648 }
649
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);
655 }
656 setOfHitIds[iLayer] = iHitId;
657 ATH_MSG_DEBUG(
"@@STGC@@ strip_pos iHitId " << iLayer <<
" " << iHitId);
658 }
659 }
660 double slopefit=0., interceptfit=99999., mse =-1.;
661 if (isStrip) {
663 } else {
664 double phiavg = 0.;
665 for (
unsigned int iHit = 0; iHit <
r.size(); ++iHit){
666 phiavg +=
r.at(iHit);
667 }
669 mse = 0.;
670 for (
unsigned int iHit = 0; iHit <
r.size(); ++iHit){
671 mse += std::pow(
r.at(iHit) - phiavg,2);
672 }
673 }
674 hitIdsInEight.push_back(setOfHitIds);
675 mseInEight.push_back(mse);
676 }
677 }
678 if(!hitIdsInEight.size()){
680 return;
681 }
682
683 ATH_MSG_DEBUG(
"@@STGC@@ isStrip= " << isStrip <<
" Noctets " << hitIdsInEight.size());
684 std::vector<int> nOctetSegments;
685 std::vector<int> patternStationName;
686
687 for (unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet) {
688
689 bool isFirstHit = true;
690 int hitStationName = 0;
691
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) {
697
698 if(isFirstHit){
699 hitStationName = stgcHits.at(tmpOctet[iLayer]).stationName;
700 isFirstHit = false;
701
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);
703 nOctetSegment++;
704 }
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);
707 nOctetSegment++;
708 }
709 }
710 }
711 nOctetSegments.push_back(nOctetSegment);
712 patternStationName.push_back(hitStationName);
713 }
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);
718 }
719 }
720
721 double msemin = 1000000.;
722 double mseminWireL = 1000000.;
723 double mseminWireS = 1000000.;
724
725 std::vector<int> octetIds(2,-1);
726
727 if(isStrip){
728 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
729 if(nOctetSegments.at(iOctet) != nOcSegMax){
730 continue;
731 }
732 if( mseInEight.at(iOctet) < msemin) {
733 msemin = mseInEight.at(iOctet);
734 }
735 }
736 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
737 if(nOctetSegments.at(iOctet) != nOcSegMax) continue;
738 if(mseInEight.at(iOctet) != msemin){
739 continue;
740 }
741 octetIds.push_back(iOctet);
742 }
743 } else {
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);
748 }
749 }
750 else if(patternStationName.at(iOctet) == 57){
751 if( mseInEight.at(iOctet) < mseminWireS) {
752 mseminWireS = mseInEight.at(iOctet);
753 }
754 }
755 }
756 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
757 if(patternStationName.at(iOctet) == 58){
758 if(mseInEight.at(iOctet) != mseminWireL){
759 continue;
760 }
761 }
762 else if(patternStationName.at(iOctet) == 57){
763 if(mseInEight.at(iOctet) != mseminWireS){
764 continue;
765 }
766 }
767 octetIds.push_back(iOctet);
768 }
769 }
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)));
773 }
774 }
775}