364{
365 double NSWCenterZ = 7526.329;
367
369 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
370 if ( hitIdByLayer[iLayer].size() > 0) {
371 side = std::abs(stgcHits.at(hitIdByLayer[iLayer].at(0)).z)/stgcHits.at(hitIdByLayer[iLayer].at(0)).z;
372 if ( stgcHits.at(hitIdByLayer[iLayer].at(0)).channelType == 1 ){
374 break;
375 }
376 }
377 }
378 NSWCenterZ = NSWCenterZ *
side;
379
380 std::array<std::vector<unsigned long int>,4> hitIdsInTwo;
381 std::array<std::vector<double>,4> slopeInTwo;
382 std::array<std::vector<double>,4> interceptInTwo;
383
384
385 for(unsigned int iPair = 0; iPair < 4; ++iPair){
386 unsigned int nHitsInInner = hitIdByLayer[iPair].size();
387 unsigned int nHitsInOuter = hitIdByLayer[iPair+4].size();
388 if ( nHitsInInner > 0xffff-1 || nHitsInOuter > 0xffff-1) {
389 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
390 <<", Number of Stgc hits in "<<iPair+4<<"th layer = "<<nHitsInOuter);
391 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.");
392 if (nHitsInInner > 0xffff-1) {nHitsInInner = 0xffff-1;}
393 if (nHitsInOuter > 0xffff-1) {nHitsInOuter = 0xffff-1;}
394 }
395
396 bool foundCounterparts[256] = {};
397
398 for(unsigned int iHit = 0; iHit < nHitsInInner; ++iHit){
399 bool foundCounterpart = 0;
400
403
404 int iHitId = hitIdByLayer[iPair].at(iHit);
405 if(isStrip){
406 r[0] = stgcHits.at(iHitId).r;
407 z[0] = stgcHits.at(iHitId).z;
408 } else {
409 double localPhiCenter;
410 if (stgcHits.at(iHitId).stationPhi<=5) {
411 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-1.);
412 } else {
413 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-9.);
414 }
415
416 if (stgcHits.at(iHitId).stationName == 57){
417 localPhiCenter +=
M_PI/8.;
418 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2. *
M_PI;
419 }
420
421 double phiProj = stgcHits.at(iHitId).phi - localPhiCenter;
422 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
423 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
424 r[0] = stgcHits.at(iHitId).r;
426 }
427
428
429 for(unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
430 int jHitId = hitIdByLayer[iPair+4].at(jHit);
431 double slope, intercept;
432 if(isStrip) {
433 r[1] = stgcHits.at(jHitId).r;
434 z[1] = stgcHits.at(jHitId).z;
435 slope = (
r[1] -
r[0]) / (
z[1] -
z[0]);
436 intercept = slope*(0. -
z[0]) +
r[0];
437
438 if(std::abs(slope) < 0.14 || std::abs(slope) > 0.6 || std::abs(intercept) > 300.) continue;
439 } else {
440 double localPhiCenter;
441 if (stgcHits.at(jHitId).stationPhi<=5) {
442 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-1.);
443 } else {
444 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-9.);
445 }
446
447 if (stgcHits.at(jHitId).stationName == 57){
448 localPhiCenter +=
M_PI/8.;
449 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
450 }
451
452 double phiProj = stgcHits.at(jHitId).phi - localPhiCenter;
453 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
454 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
455 r[1] = stgcHits.at(jHitId).r;
457 slope = (
z[0]+
z[1])/2.;
458 intercept = (
r[0]+
r[1])/2.;
459 if(std::abs(
r[0]*std::sin(
z[0]) -
r[1]*std::sin(
z[1])) > 300.)
continue;
460 }
461
462 unsigned int encodedIds = (iHitId<<16) + jHitId;
463 hitIdsInTwo[iPair].push_back(encodedIds);
464 slopeInTwo[iPair].push_back(slope);
465 interceptInTwo[iPair].push_back(intercept);
466
467 foundCounterpart = 1;
468 foundCounterparts[jHit] = 1;
469 }
470 if(!foundCounterpart){
471 unsigned int encodedIds = (iHitId<<16) + 0xffff;
472 hitIdsInTwo[iPair].push_back(encodedIds);
473 if(isStrip) {
474 slopeInTwo[iPair].push_back(
r[0]/
z[0]);
475 interceptInTwo[iPair].push_back(0.);
476 } else {
477 slopeInTwo[iPair].push_back(
z[0]);
478 interceptInTwo[iPair].push_back(
r[0]);
479 }
480 }
481 }
482
483 for(unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
484 if (!foundCounterparts[jHit]) {
485 int jHitId = hitIdByLayer[iPair+4].at(jHit);
486 unsigned int encodedIds = 0xffff0000 + jHitId;
487 hitIdsInTwo[iPair].push_back(encodedIds);
488 if(isStrip) {
489 slopeInTwo[iPair].push_back(stgcHits.at(jHitId).r/stgcHits.at(jHitId).z);
490 interceptInTwo[iPair].push_back(0.);
491 } else {
492 double localPhiCenter;
493 if (stgcHits.at(jHitId).stationPhi<=5) {
494 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-1.);
495 } else {
496 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(jHitId).stationPhi-9.);
497 }
498 if (stgcHits.at(jHitId).stationName == 57){
499 localPhiCenter +=
M_PI/8.;
500 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
501 }
502
503 double phiProj = stgcHits.at(jHitId).phi - localPhiCenter;
504 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
505 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
506 slopeInTwo[iPair].push_back(phiProj);
507 interceptInTwo[iPair].push_back(stgcHits.at(jHitId).r);
508 }
509 }
510 }
511 }
512
513 ATH_MSG_DEBUG(
"@@STGC@@ isStrip= " << isStrip <<
" Npairs " << hitIdsInTwo[0].size() <<
" " << hitIdsInTwo[1].size() <<
" " << hitIdsInTwo[2].size() <<
" " << hitIdsInTwo[3].size());
514 for (unsigned int iLayer = 0; iLayer < 4; ++ iLayer) {
515 for (unsigned int iPair = 0; iPair < slopeInTwo[iLayer].size(); ++iPair) {
516 ATH_MSG_DEBUG(
"@@STGC@@ pair fit isStrip= " << isStrip <<
" slope= " << slopeInTwo[iLayer].at(iPair) <<
" intercept= " << interceptInTwo[iLayer].at(iPair));
517 }
518 }
519
520 std::array<std::vector<unsigned long int>,2> hitIdsInFour;
521 std::array<std::vector<double>,2> slopeInFour;
522 std::array<std::vector<double>,2> interceptInFour;
523 for(unsigned int iQuad = 0; iQuad < 2; ++iQuad){
524 unsigned int nPairsInInner = hitIdsInTwo[iQuad].size();
525 unsigned int nPairsInOuter = hitIdsInTwo[iQuad+2].size();
526
527 bool foundCounterparts[0xffff] = {};
528 for(unsigned int iPair = 0; iPair < nPairsInInner; ++iPair){
529 bool foundCounterpart = 0;
530 double slope[2];
531 double intercept[2];
532 slope[0] = slopeInTwo[iQuad].at(iPair);
533 intercept[0] = interceptInTwo[iQuad].at(iPair);
534
535 for(unsigned int jPair = 0; jPair < nPairsInOuter; ++jPair){
536 unsigned int ihitIds = hitIdsInTwo[iQuad].at(iPair);
537 unsigned int jhitIds = hitIdsInTwo[iQuad+2].at(jPair);
538 if ( !(((ihitIds>>16 & 0xffff) != 0xffff || (ihitIds & 0xffff) != 0xffff) &&
539 ((jhitIds>>16 & 0xffff) != 0xffff || (jhitIds & 0xffff) != 0xffff )) ) continue;
540
541 slope[1] = slopeInTwo[iQuad+2].at(jPair);
542 intercept[1] = interceptInTwo[iQuad+2].at(jPair);
543
544 if (isStrip) {
545 double spR0 = slope[0] * NSWCenterZ + intercept[0];
546 double spR1 = slope[1] * NSWCenterZ + intercept[1];
547 if(std::abs(spR1 - spR0) > 50.) continue;
548 } else {
549 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100.) continue;
550 }
551
552 foundCounterpart = 1;
553 foundCounterparts[jPair] = 1;
554
555 unsigned long int encodedIds = (hitIdsInTwo[iQuad].at(iPair) << 32 ) + hitIdsInTwo[iQuad+2].at(jPair);
556 hitIdsInFour[iQuad].push_back(encodedIds);
557 slopeInFour[iQuad].push_back((slope[1] + slope[0])/2.);
558 interceptInFour[iQuad].push_back((intercept[1] + intercept[0])/2.);
559 }
560
561 if(foundCounterpart) continue;
562 if((hitIdsInTwo[iQuad].at(iPair)>>16 & 0xffff) == 0xffff || (hitIdsInTwo[iQuad].at(iPair) & 0xffff) == 0xffff) continue;
563
564 unsigned long int encodedIds = (hitIdsInTwo[iQuad].at(iPair) << 32 ) + 0xffffffff;
565 hitIdsInFour[iQuad].push_back(encodedIds);
566 slopeInFour[iQuad].push_back(slope[0]);
567 interceptInFour[iQuad].push_back(intercept[0]);
568 }
569 for (unsigned int jPair = 0; jPair < nPairsInOuter; ++jPair) {
570 if(foundCounterparts[jPair]) continue;
571 if((hitIdsInTwo[iQuad+2].at(jPair)>>16 & 0xffff) == 0xffff || (hitIdsInTwo[iQuad+2].at(jPair) & 0xffff) == 0xffff) continue;
572
573 unsigned long int encodedIds = (0xffffffff00000000 ) + hitIdsInTwo[iQuad+2].at(jPair);
574 hitIdsInFour[iQuad].push_back(encodedIds);
575 slopeInFour[iQuad].push_back(slopeInTwo[iQuad+2].at(jPair));
576 interceptInFour[iQuad].push_back(interceptInTwo[iQuad+2].at(jPair));
577 }
578 }
579
580 ATH_MSG_DEBUG(
"@@STGC@@ isStrip= " << isStrip <<
" Nquads " << hitIdsInFour[0].size() <<
" " << hitIdsInFour[1].size());
581 for (unsigned int iLayer = 0; iLayer < 2; ++ iLayer) {
582 for (unsigned int iQuad = 0; iQuad < slopeInFour[iLayer].size(); ++iQuad) {
583 ATH_MSG_DEBUG(
"@@STGC@@ quad fit isStrip= " << isStrip <<
" slope= " << slopeInFour[iLayer].at(iQuad) <<
" intercept= " << interceptInFour[iLayer].at(iQuad));
584 }
585 }
586
587 std::vector< std::array<int, 8> > hitIdsInEight;
588 std::vector<double> mseInEight;
589
590 unsigned int nQuadInInner = hitIdsInFour[0].size();
591 unsigned int nQuadInOuter = hitIdsInFour[1].size();
592
593 for(unsigned int iQuad = 0; iQuad < nQuadInInner; ++iQuad){
594 double slope[2];
595 double intercept[2];
596 slope[0] = slopeInFour[0].at(iQuad);
597 intercept[0] = interceptInFour[0].at(iQuad);
598
599 for(unsigned int jQuad = 0; jQuad < nQuadInOuter; ++jQuad){
600 unsigned long int ihitIds = hitIdsInFour[0].at(iQuad);
601 unsigned long int jhitIds = hitIdsInFour[1].at(jQuad);
602 int nOfLayersWithNoHit = 0;
603 for (unsigned int iLayer = 0; iLayer < 4; ++iLayer) {
604 if ( (ihitIds>>(3-iLayer)*16 & 0xffff) == 0xffff ) {++nOfLayersWithNoHit;}
605 if ( (jhitIds>>(3-iLayer)*16 & 0xffff) == 0xffff ) {++nOfLayersWithNoHit;}
606 }
607 if (nOfLayersWithNoHit > 4) continue;
608
609 slope[1] = slopeInFour[1].at(jQuad);
610 intercept[1] = interceptInFour[1].at(jQuad);
611
612 if(isStrip) {
613 double spR0 = slope[0] * NSWCenterZ + intercept[0];
614 double spR1 = slope[1] * NSWCenterZ + intercept[1];
615 if(std::abs(spR1 - spR0) > 10. ||
616 std::abs(intercept[1] + intercept[0]) / 2 > 100.) continue;
617 } else {
618 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100. ) continue;
619 }
620
621 std::array<int,8> setOfHitIds = {-1,-1,-1,-1,-1,-1,-1,-1};
622 std::vector<double>
r,
z;
623 for(
unsigned int i = 0;
i < 8; ++
i) {
624 unsigned int iHitId, iLayer = 0;
625 if (i <= 3) {
626 iHitId = (
unsigned int) ((ihitIds>>(3-i)*16) & 0xffff);
628 } else {
629 iHitId = (
unsigned int) ((jhitIds>>(3-i%4)*16) & 0xffff);
630 iLayer = (
i-4)+3*(i%2)+1;
631 }
632 if ( iHitId != 0xffff ) {
633 if (isStrip) {
634 r.push_back(stgcHits.at(iHitId).r);
635 z.push_back(stgcHits.at(iHitId).z);
636 }
637 else {
638 double localPhiCenter;
639 if (stgcHits.at(iHitId).stationPhi<=5) {
640 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-1.);
641 } else {
642 localPhiCenter = 0.25 *
M_PI * ((
double)stgcHits.at(iHitId).stationPhi-9.);
643 }
644 if (stgcHits.at(iHitId).stationName == 57){
645 localPhiCenter +=
M_PI/8.;
646 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2 *
M_PI;
647 }
648
649 double phiProj = stgcHits.at(iHitId).phi - localPhiCenter;
650 if (phiProj >
M_PI) phiProj -= 2.0*
M_PI;
651 if (phiProj < -1.*
M_PI) phiProj += 2.0*
M_PI;
652 r.push_back(phiProj);
653 z.push_back(stgcHits.at(iHitId).r);
654 }
655 setOfHitIds[iLayer] = iHitId;
656 ATH_MSG_DEBUG(
"@@STGC@@ strip_pos iHitId " << iLayer <<
" " << iHitId);
657 }
658 }
659 double slopefit=0., interceptfit=99999., mse =-1.;
660 if (isStrip) {
662 } else {
663 double phiavg = 0.;
664 for (
unsigned int iHit = 0; iHit <
r.size(); ++iHit){
665 phiavg +=
r.at(iHit);
666 }
668 mse = 0.;
669 for (
unsigned int iHit = 0; iHit <
r.size(); ++iHit){
670 mse += std::pow(
r.at(iHit) - phiavg,2);
671 }
672 }
673 hitIdsInEight.push_back(setOfHitIds);
674 mseInEight.push_back(mse);
675 }
676 }
677 if(!hitIdsInEight.size()){
679 return;
680 }
681
682 ATH_MSG_DEBUG(
"@@STGC@@ isStrip= " << isStrip <<
" Noctets " << hitIdsInEight.size());
683 std::vector<int> nOctetSegments;
684 std::vector<int> patternStationName;
685
686 for (unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet) {
687
688 bool isFirstHit = true;
689 int hitStationName = 0;
690
691 int nOctetSegment = 0;
692 ATH_MSG_DEBUG(
"@@STGC@@ octet fit isStrip= " << isStrip <<
" mse " << mseInEight.at(iOctet));
693 std::array<int, 8> tmpOctet = hitIdsInEight.at(iOctet);
694 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
695 if (tmpOctet[iLayer] != -1) {
696
697 if(isFirstHit){
698 hitStationName = stgcHits.at(tmpOctet[iLayer]).stationName;
699 isFirstHit = false;
700
701 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);
702 nOctetSegment++;
703 }
704 else if(stgcHits.at(tmpOctet[iLayer]).stationName == hitStationName){
705 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);
706 nOctetSegment++;
707 }
708 }
709 }
710 nOctetSegments.push_back(nOctetSegment);
711 patternStationName.push_back(hitStationName);
712 }
713 double nOcSegMax = 0;
714 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
715 if(nOctetSegments.at(iOctet) > nOcSegMax){
716 nOcSegMax = nOctetSegments.at(iOctet);
717 }
718 }
719
720 double msemin = 1000000.;
721 double mseminWireL = 1000000.;
722 double mseminWireS = 1000000.;
723
724 std::vector<int> octetIds(2,-1);
725
726 if(isStrip){
727 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
728 if(nOctetSegments.at(iOctet) != nOcSegMax){
729 continue;
730 }
731 if( mseInEight.at(iOctet) < msemin) {
732 msemin = mseInEight.at(iOctet);
733 }
734 }
735 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
736 if(nOctetSegments.at(iOctet) != nOcSegMax) continue;
737 if(mseInEight.at(iOctet) != msemin){
738 continue;
739 }
740 octetIds.push_back(iOctet);
741 }
742 } else {
743 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
744 if(patternStationName.at(iOctet) == 58){
745 if( mseInEight.at(iOctet) < mseminWireL) {
746 mseminWireL = mseInEight.at(iOctet);
747 }
748 }
749 else if(patternStationName.at(iOctet) == 57){
750 if( mseInEight.at(iOctet) < mseminWireS) {
751 mseminWireS = mseInEight.at(iOctet);
752 }
753 }
754 }
755 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
756 if(patternStationName.at(iOctet) == 58){
757 if(mseInEight.at(iOctet) != mseminWireL){
758 continue;
759 }
760 }
761 else if(patternStationName.at(iOctet) == 57){
762 if(mseInEight.at(iOctet) != mseminWireS){
763 continue;
764 }
765 }
766 octetIds.push_back(iOctet);
767 }
768 }
769 for(
unsigned int ids = 0;
ids < octetIds.size();
ids++){
770 if (octetIds.at(ids) != -1) {
771 hitIdsCandidate.push_back(hitIdsInEight.at(octetIds.at(ids)));
772 }
773 }
774}