9 #include "GaudiKernel/ConcurrencyFlags.h"
24 declareInterface<IMuonHoughPatternFinderTool>(
this);
99 return StatusCode::SUCCESS;
103 const std::vector<const MdtPrepDataCollection*>& mdtCols,
const std::vector<const CscPrepDataCollection*>& cscCols,
104 const std::vector<const TgcPrepDataCollection*>& tgcCols,
const std::vector<const RpcPrepDataCollection*>& rpcCols,
116 auto getHashes = [
this](
const Identifier&
id) {
120 return std::make_pair(regionIndex, sectorLayerHash);
127 auto hashes = getHashes(
id);
135 auto hashes = getHashes(
id);
143 auto hashes = getHashes(
id);
147 auto hashInSector = [
this](
IdentifierHash hash,
int sector,
unsigned int sectorLayerHash) {
148 const std::vector<IdentifierHash>&
hashes =
157 auto hashes = getHashes(
id);
164 int neighbourSectorDown = sector == 1 ? 16 : sector - 1;
165 if (hashInSector(
col->identifyHash(), neighbourSectorDown,
hashes.second))
170 int neighbourSectorUp = sector == 16 ? 1 : sector + 1;
171 if (hashInSector(
col->identifyHash(), neighbourSectorUp,
hashes.second))
183 const EventContext& ctx)
const {
192 ATH_MSG_DEBUG(
"analyse: Filling hits sector " << sit.sector);
195 houghData.
sector = sit.sector;
198 fillHitsPerSector(ctx, state, sit.sector, sit, mdtCont, cscCont, tgcCont, rpcCont, stgcCont, mmCont);
204 State& state)
const {
205 auto patternCombis = std::make_unique<MuonPatternCombinationCollection>();
209 ATH_MSG_DEBUG(
"analyse: Filling Hough sector " << houghData.sector);
215 if (
hits.empty())
continue;
233 houghData.maxVec[layerHash].empty())
236 ++houghData.nlayersWithMaxima[region];
237 houghData.nmaxHitsInRegion[region] += houghData.maxVec[layerHash].front()->max;
242 <<
" hash: " << layerHash <<
" nMaxima: " << houghData.maxVec[layerHash].size());
247 std::vector<Road> roads;
252 ATH_MSG_DEBUG(
"analyse: Building pattern combinations using roads " << roads.size());
253 for (
auto& road : roads) {
254 std::map<MuonHough::MuonPhiLayerHough::Maximum*, MuonLayerHoughTool::MaximumVec> phiEtaAssMap;
257 int sector = road.seed->hough->m_descriptor.sector;
262 << road.maxima.size() <<
" phi " << road.phiMaxima.size() <<
" seed : sector " << sector <<
" "
264 <<
" maximum " << road.seed->max <<
" position " << road.seed->pos <<
" angle " << road.seed->theta);
266 if (road.phiMaxima.empty())
267 unassociatedEtaMaxima.push_back(road.maxima);
269 for (
auto&
max : road.mergedPhiMaxima) { phiEtaAssMap[&
max] = road.maxima; }
283 for (; spit != spit_end; ++spit) {
307 std::map<MuonHough::MuonPhiLayerHough::Maximum*, MaximumVec> phiEtaAssociations;
319 ATH_MSG_DEBUG(
"Found " << patternCombis->size() <<
" pattern combinations " << std::endl <<
m_printer->print(*patternCombis));
332 std::unique_ptr<HoughDataPerSectorVec>& houghDataPerSectorVec,
333 std::vector<MuonLayerHoughTool::Road>& roads)
const {
335 std::stable_sort(seedMaxima.begin(), seedMaxima.end(),
336 [](
const std::shared_ptr<MuonHough::MuonLayerHough::Maximum>&
m1,
337 const std::shared_ptr<MuonHough::MuonLayerHough::Maximum>&
m2) { return m1->max > m2->max; });
339 std::set<std::shared_ptr<MuonHough::MuonLayerHough::Maximum>> associatedMaxima;
340 for (
const auto& seed : seedMaxima) {
342 if (associatedMaxima.count(seed))
continue;
347 int sector = seed->hough->m_descriptor.sector;
356 <<
" position " << seed->pos <<
" angle " << seed->theta <<
" ptr " << seed.get());
361 MuonHough::HitVec::const_iterator ref_itr = std::find_if(
362 seed->hits.begin(), seed->hits.end(), [](
const std::shared_ptr<MuonHough::Hit>& hit) ->
bool { return hit->prd; });
364 const bool isNSW = ref_itr != seed->hits.end() &&
369 extendSeed(detectorHoughTransforms, road, houghDataPerSectorVec->
vec[sector - 1]);
372 int sectorN = sector - 1;
373 if (sectorN < 1) sectorN = 16;
374 int sectorP = sector + 1;
375 if (sectorP > 16) sectorP = 1;
381 extendSeed(detectorHoughTransforms, road, houghDataPerSectorVec->
vec[sectorN - 1]);
383 extendSeed(detectorHoughTransforms, road, houghDataPerSectorVec->
vec[sectorP - 1]);
407 associatedMaxima.insert(road.
maxima.begin(), road.
maxima.end());
417 <<
max->pos <<
" angle " <<
max->theta <<
" ptr " <<
max);
421 for (
auto& oldRoad : roads) {
422 std::vector<std::shared_ptr<MuonHough::MuonLayerHough::Maximum>>
intersection;
426 unsigned int oldRoadSize = oldRoad.maximumSet.size();
427 unsigned int roadSize = road.
maximumSet.size();
428 ATH_MSG_VERBOSE(
" Overlap check " << intersectionSize <<
" old " << oldRoadSize <<
" new " << roadSize <<
" old ptr "
430 if (intersectionSize == 0)
continue;
431 if (intersectionSize == roadSize) {
434 }
else if (intersectionSize == oldRoadSize) {
442 if (insert) roads.push_back(road);
450 auto maximaSortingLambda = [road](
const std::shared_ptr<MuonHough::MuonPhiLayerHough::Maximum>&
m1,
451 const std::shared_ptr<MuonHough::MuonPhiLayerHough::Maximum>&
m2) {
452 if (
m1->max !=
m2->max)
return m1->max >
m2->max;
454 if (
m1->sector !=
m2->sector)
return m1->sector == road.
seed->hough->m_descriptor.sector;
456 if (
m1->hits.size() !=
m2->hits.size())
return m1->hits.size() <
m2->hits.size();
458 if (
m1->pos !=
m2->pos)
return m1->pos <
m2->pos;
460 if (std::abs(
m1->binposmax -
m1->binposmin) == std::abs(
m2->binposmax -
m2->binposmin)) {
461 return (
m1->binposmin) < (
m2->binposmin);
463 return std::abs(
m1->binposmax -
m1->binposmin) < std::abs(
m2->binposmax -
m2->binposmin);
469 std::set<MuonHough::MuonPhiLayerHough::Maximum*> associatedPhiMaxima;
471 if (associatedPhiMaxima.count((*pit).get()))
continue;
472 associatedPhiMaxima.insert((*pit).get());
476 bool wasExtended =
false;
477 for (
auto pit1 = pit + 1; pit1 != road.
phiMaxima.end(); ++pit1) {
478 if ((*pit1)->binposmax >= phiMaximum.
binposmin && (*pit1)->binposmin <= phiMaximum.
binposmax) {
479 ATH_MSG_VERBOSE(
" merging maxima " << phiMaximum.
pos <<
" val " << phiMaximum.
max <<
" " << (*pit1)->pos <<
" val "
481 phiMaximum.
hits.insert(phiMaximum.
hits.end(), (*pit1)->hits.begin(), (*pit1)->hits.end());
482 associatedPhiMaxima.insert((*pit1).get());
497 std::stable_sort(
hits.begin(),
hits.end(),
498 [](
const std::shared_ptr<MuonHough::PhiHit>&
h1,
const std::shared_ptr<MuonHough::PhiHit>& h2) {
499 if (h1->layer != h2->layer) return h1->layer < h2->layer;
500 if (h1->w != h2->w) return h1->w > h2->w;
501 if (h1->r != h2->r) return h1->r < h2->r;
503 const double dPhi1 = std::abs(h1->phimax - h1->phimin);
504 const double dPhi2 = std::abs(h2->phimax - h2->phimin);
505 if (dPhi1 != dPhi2) return dPhi1 < dPhi2;
506 if (h1->phimin == h2->phimin) return h1->phimax < h2->phimax;
507 return h1->phimin < h2->phimin;
511 <<
" number of hits " <<
hits.size());
517 <<
" number of hits " << phiMaximum.
hits.size());
518 phiMaximum.
hough = (*pit)->hough;
533 if (!road.
seed)
return;
545 if (
layer == seedLayer && seed.hough->m_descriptor.sector == sectorData.
sector)
continue;
555 if (maxima.empty())
continue;
558 <<
" size " << maxima.size());
560 for (
const auto& candMaximum : maxima) {
565 ATH_MSG_VERBOSE(
" Adding maximum position " << candMaximum->pos <<
" intersect diff" << yloc_diff);
566 road.
add(candMaximum);
569 << candMaximum->pos <<
" x " << candMaximum->hough->m_descriptor.referencePosition <<
" seed y "
570 << seed.hough->m_descriptor.referencePosition <<
" x " << seed.pos <<
" intersect diff " << yloc_diff);
578 ATH_MSG_DEBUG(
"Checking Barrel/Endcap overlaps: min dist edge "
579 << seed.pos - seed.hough->m_descriptor.yMinRange <<
" max dist edge " << seed.pos - seed.hough->m_descriptor.yMaxRange
580 <<
" pos " << seed.pos <<
" range " << seed.hough->m_descriptor.yMinRange <<
" "
581 << seed.hough->m_descriptor.yMaxRange);
583 if (std::abs(seed.pos - seed.hough->m_descriptor.yMinRange) < 4000. ||
584 std::abs(seed.pos - seed.hough->m_descriptor.yMaxRange) < 4000.) {
601 double distanceCut = 1000.;
606 if (maxima.empty())
continue;
609 <<
" size " << maxima.size());
612 for (
const auto& candMaximum : maxima) {
616 << candMaximum->pos <<
" x " << candMaximum->hough->m_descriptor.referencePosition <<
" seed y "
617 << seed.hough->m_descriptor.referencePosition <<
" x " << seed.pos <<
" intersect diff " << yloc_diff);
619 if (std::abs(yloc_diff) < distanceCut) {
620 road.
add(candMaximum);
628 std::set<const TgcClusterObj3D*> tgcClusters;
629 std::set<Identifier> triggerLayers;
631 for (
const auto& maximum : maxima) {
632 if (maximum->hough->m_descriptor.sector != sectorData.
sector)
636 for (
auto ehit = maximum->hits.begin(); ehit != maximum->hits.end(); ++ehit) {
640 }
else if (etaHit.
prd) {
647 detectorHoughTransforms.
phiHough(region);
652 for (
const auto& phiHit : phiHits) {
654 if (tgcClusters.find(phiHit->tgc) != tgcClusters.end()) phiHitsInMaximum.push_back(phiHit);
655 }
else if (phiHit->prd) {
656 if (triggerLayers.find(
m_idHelperSvc->gasGapId(phiHit->prd->identify())) != triggerLayers.end())
657 phiHitsInMaximum.push_back(phiHit);
663 << phiHitsInMaximum.size() <<
" phi hits: " << phiHits.size());
676 <<
" -> nPhiMaxima: " << sectorData.
phiMaxVec[region].size()
683 ATH_MSG_DEBUG(
"associateMaximaToPhiMaxima: phi maxima " << phiMaxima.size());
684 if (!road.
seed)
return;
687 for (
const auto& pmaximum : phiMaxima) {
690 ATH_MSG_DEBUG(
" new phi maximum " << pmaximum->max <<
" hits " << pmaximum->hits.size());
693 std::map<Identifier, std::pair<float, float>> triggerLayersPhiMinMax;
694 std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>> tgcClusters;
697 for (
const auto& phiHit : pmaximum->hits) {
702 if (phiHit->tgc->phiCluster.empty())
705 tgcClusters[
m_idHelperSvc->stationIndex(phiHit->tgc->phiCluster.front()->identify())].insert(phiHit->tgc);
706 }
else if (phiHit->prd) {
708 auto mit = triggerLayersPhiMinMax.find(gpId);
709 if (mit == triggerLayersPhiMinMax.end())
710 triggerLayersPhiMinMax[gpId] = std::make_pair(phiHit->phimin, phiHit->phimax);
712 mit->second.first =
std::min(phiHit->phimin, mit->second.first);
713 mit->second.second =
std::max(phiHit->phimax, mit->second.second);
719 ATH_MSG_DEBUG(
"Trigger layers " << triggerLayersPhiMinMax.size() <<
" tgc layers " << tgcClusters.size());
720 for (
auto tgcit = triggerLayersPhiMinMax.begin(); tgcit != triggerLayersPhiMinMax.end(); ++tgcit) {
725 std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit = tgcClusters.begin();
726 std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit_end = tgcClusters.end();
727 for (; stit != stit_end; ++stit) {
728 std::set<const TgcClusterObj3D*>::const_iterator ttit = stit->second.begin();
729 std::set<const TgcClusterObj3D*>::const_iterator ttit_end = stit->second.end();
730 for (; ttit != ttit_end; ++ttit) {
732 << (*ttit)->phiCluster.size());
741 float phimin{10}, phimax{-10};
744 for (
const auto& road_max : road.
maxima) {
749 for (
const auto& etaHit : road_max->hits) {
751 if (etaHit->tgc->etaCluster.empty())
754 if (tgcClusters[stIndex].
count(etaHit->tgc)) {
756 for (
const auto& phiHit : pmaximum->hits) {
757 if (phiHit->tgc == etaHit->tgc) {
758 phimin =
std::min(phiHit->phimin, phimin);
759 phimax =
std::max(phiHit->phimax, phimax);
768 }
else if (etaHit->prd) {
771 auto mit = triggerLayersPhiMinMax.find(gpId);
772 if (mit == triggerLayersPhiMinMax.end())
775 phimin =
std::min(mit->second.first, phimin);
776 phimax =
std::max(mit->second.second, phimax);
787 std::vector<int> sectors;
789 if (sectors.size() > 1) {
790 for (
const int& sec : sectors) {
794 std::vector<int> sectors;
796 if (sectors.size() > 1) {
797 for (
const int& sec : sectors) {
803 ATH_MSG_DEBUG(
" Overlap with Phi maximum: overlap " << noverlaps <<
" no overlap " << nNoOverlaps <<
" phimin " << phimin
804 <<
" phimax " << phimax <<
" neighbouring sector "
812 std::vector<MuonLayerHoughTool::HoughDataPerSector>& houghDataPerSectorVec)
const {
816 for (
unsigned int regLay = 0; regLay < houghData.
maxVec.size(); ++regLay) {
818 int sector = houghData.
sector;
821 for (
int i = 0;
i < 2; ++
i) {
823 int sectorN = (
i == 0) ? sector - 1 : sector + 1;
824 if (
i == 0 && sector == 1) sectorN = 16;
825 if (
i == 1 && sector == 16) sectorN = 1;
832 for (
const auto& maximum : maxima) {
835 if (!maximum->hough) {
841 for (
const auto& maximumN : maximaN) {
843 if (!maximumN->hough) {
849 double rcor = maximumN->hough->m_descriptor.referencePosition *
851 maximum->hough->m_descriptor.referencePosition;
852 double dist = rcor - maximumN->pos;
853 ATH_MSG_DEBUG(
" maximumN->hough " << maximumN->hough->m_descriptor.referencePosition <<
" maximum->hough "
854 << maximum->hough->m_descriptor.referencePosition <<
" maximumN->pos "
855 << maximumN->pos <<
" maximum->pos " << maximum->pos << rcor <<
" distance "
857 if (std::abs(dist) > 100)
continue;
861 ATH_MSG_DEBUG(
" Found maximum in neighbouring sector: max " << maximum->max <<
" pos " << rcor <<
" maxN "
862 << maximumN->max <<
" pos " << maximumN->pos
863 <<
" distance " << dist);
866 for (
int nn = 0; nn < 2; ++nn) {
868 const auto& maxi = nn == 0 ? maximum : maximumN;
869 const auto& maxi2 = nn == 0 ? maximumN : maximum;
871 for (
auto& hit : maxi->hits) {
872 if (hit->debugInfo()) {
873 hit->debugInfo()->phn = maxi2->max;
874 Identifier id = hit->tgc ? hit->tgc->etaCluster.front()->identify() : hit->prd->identify();
887 std::map<MuonHough::MuonPhiLayerHough::Maximum*, MuonLayerHoughTool::MaximumVec>& phiEtaAssociations,
889 std::set<std::shared_ptr<MuonHough::MuonLayerHough::Maximum>> associatedMaxima;
893 ATH_MSG_DEBUG(
"associateMaximaToPhiMaxima in sector " << houghData.
sector <<
": phi maxima " << phiMaxima.size());
895 for (
const auto& phiMaximum : phiMaxima) {
898 ATH_MSG_DEBUG(
" Considering phi maximum " << phiMaximum->max <<
" hits " << phiMaximum->hits.size());
905 std::set<Identifier> triggerLayers;
906 std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>> tgcClusters;
909 for (
const auto& phiHit : phiMaximum->hits) {
911 if (phiHit->tgc->phiCluster.empty())
914 tgcClusters[
m_idHelperSvc->stationIndex(phiHit->tgc->phiCluster.front()->identify())].insert(phiHit->tgc);
915 }
else if (phiHit->prd) {
918 triggerLayers.insert(layId);
922 ATH_MSG_DEBUG(
"Trigger layers " << triggerLayers.size() <<
" tgc layers " << tgcClusters.size());
925 std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit = tgcClusters.begin();
926 std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit_end = tgcClusters.end();
927 for (; stit != stit_end; ++stit) {
928 std::set<const TgcClusterObj3D*>::const_iterator ttit = stit->second.begin();
929 std::set<const TgcClusterObj3D*>::const_iterator ttit_end = stit->second.end();
930 for (; ttit != ttit_end; ++ttit) {
932 << (*ttit)->phiCluster.size());
944 if (maxima.empty())
continue;
948 for (
const auto& maximum : maxima) {
954 int ntrigconfirm = 0;
957 for (
const auto& max_itr :
pos->second) {
958 totmax =
std::max(max_itr->max, totmax);
959 ntrigconfirm += max_itr->triggerConfirmed;
962 totmax += maximum->max;
963 ntrigconfirm += maximum->triggerConfirmed;
966 <<
" neightbour confirmed value " << totmax <<
" trigger confirmations "
970 int nmmHits{0}, ntgcOverlaps{0}, nrpcOverlaps{0}, nstgcOverlaps{0}, nstgcNoOverlaps{0};
973 for (
const auto& etaHit : maximum->hits) {
975 if (tgcClusters[stIndex].
count(etaHit->tgc))
978 }
else if (etaHit->prd) {
982 if (triggerLayers.count(layId)) {
995 if (nmmHits + nstgcNoOverlaps + nstgcOverlaps > 0) {
997 if (maximum->pos < 1200.) {
999 ATH_MSG_DEBUG(
" maximum failed cut " << totmax <<
" cut 8, position " << maximum->pos);
1002 }
else if (maximum->pos > 4300.) {
1004 ATH_MSG_DEBUG(
" maximum failed cut " << totmax <<
" cut 8, position " << maximum->pos);
1009 ATH_MSG_DEBUG(
" maximum failed cut " << totmax <<
" cut 12, position " << maximum->pos);
1015 ATH_MSG_DEBUG(
" Overlap with Phi maximum: tgc " << ntgcOverlaps <<
" stgc " << nstgcOverlaps <<
" rpc " << nrpcOverlaps
1016 <<
" nphiTgc " << tgcClusters[stIndex].
size() <<
" trigLay "
1017 << triggerLayers.size());
1020 << ntgcOverlaps <<
" on phi maximum "
1021 << tgcClusters[stIndex].
size());
1026 << ntgcOverlaps <<
" on phi maximum "
1027 << tgcClusters[stIndex].
size());
1032 <<
" stgcs without overlaps " << nstgcNoOverlaps);
1038 associatedMaxima.insert(maximum);
1039 associatedMaximaVec.push_back(maximum);
1043 associatedMaxima.insert(
pos->second.begin(),
pos->second.end());
1044 associatedMaximaVec.insert(associatedMaximaVec.end(),
pos->second.begin(),
pos->second.end());
1049 if (associatedMaximaVec.empty())
continue;
1050 ATH_MSG_DEBUG(
" processed phi maximum, associated eta maxima " << associatedMaximaVec.size());
1051 phiEtaAssociations[phiMaximum.get()] = std::move(associatedMaximaVec);
1060 if (
layer >= (
int)unassEtaMaxima.size()) {
1061 ATH_MSG_WARNING(
" size of unassEtaMaxima too small for region " << unassEtaMaxima.size() <<
" region "
1068 for (
const auto& mit : maxima) {
1069 if (associatedMaxima.count(mit))
continue;
1070 unassEtaMaxima[
layer].push_back(mit);
1078 ATH_MSG_DEBUG(
"Creating pattern combinations for eta patterns ");
1080 std::vector<MuonPatternChamberIntersect> chamberData;
1085 for (
const auto& max_sec : maxima) {
1087 std::map<Identifier, std::set<const Trk::PrepRawData*>> prdsPerChamber;
1090 for (
const auto&
max : max_sec) {
1094 if (
max->hits.empty()) {
1101 for (
const auto& hit :
max->hits) {
1104 prdsPerChamber[chId].insert(hit->tgc->etaCluster.begin(), hit->tgc->etaCluster.end());
1105 }
else if (hit->prd) {
1107 prdsPerChamber[chId].insert(hit->prd);
1113 return prd1->
identify() < prd2->identify();
1115 std::map<Identifier, std::set<const Trk::PrepRawData*>>
::iterator chit = prdsPerChamber.begin();
1116 std::map<Identifier, std::set<const Trk::PrepRawData*>>
::iterator chit_end = prdsPerChamber.end();
1117 for (; chit != chit_end; ++chit) {
1119 std::vector<const Trk::PrepRawData*> prds;
1120 prds.insert(prds.end(), chit->second.begin(), chit->second.end());
1125 ATH_MSG_DEBUG(
"Adding chamber with intersect phi direction " << gpos.phi() <<
" theta " << gpos.theta());
1126 MuonPatternChamberIntersect
intersect(gpos, gpos.unit(), prds);
1130 if (chamberData.empty())
return;
1132 MuonPatternCombination* combi =
new MuonPatternCombination(
nullptr, chamberData);
1139 std::map<MuonHough::MuonPhiLayerHough::Maximum*, MuonLayerHoughTool::MaximumVec>& phiEtaAssociations,
1141 ATH_MSG_DEBUG(
"Creating pattern combinations from eta/phi combinations " << phiEtaAssociations.size());
1144 std::map<MuonHough::MuonPhiLayerHough::Maximum*, MaximumVec>::const_iterator pit = phiEtaAssociations.begin();
1145 std::map<MuonHough::MuonPhiLayerHough::Maximum*, MaximumVec>::const_iterator pit_end = phiEtaAssociations.end();
1146 for (; pit != pit_end; ++pit) {
1147 if (pit->second.empty())
continue;
1150 std::map<Identifier, std::set<const Trk::PrepRawData*>> phiHitsPerChamber;
1153 for (
const auto& hit : pit->first->hits) {
1156 phiHitsPerChamber[chId].insert(hit->tgc->phiCluster.begin(), hit->tgc->phiCluster.end());
1157 }
else if (hit->prd) {
1159 phiHitsPerChamber[chId].insert(hit->prd);
1164 std::vector<MuonPatternChamberIntersect> chamberData;
1165 std::set<Identifier> addedPhiHits;
1168 std::map<Identifier, std::set<const Trk::PrepRawData*>> prdsPerChamber;
1171 std::map<MuonStationIndex::ChIndex, std::pair<Amg::Vector3D, Amg::Vector3D>> directionsPerChamberLayer;
1174 for (
const auto&
max : pit->second) {
1180 if (
max->hits.empty()) {
1187 for (
const auto& hit :
max->hits) {
1190 chId =
m_idHelperSvc->chamberId(hit->tgc->etaCluster.front()->identify());
1191 prdsPerChamber[chId].insert(hit->tgc->etaCluster.begin(), hit->tgc->etaCluster.end());
1192 }
else if (hit->prd) {
1194 prdsPerChamber[chId].insert(hit->prd);
1201 if (!directionsPerChamberLayer.count(chIndex)) {
1203 double maxpos =
max->pos;
1204 double refPlane = 0.;
1207 refPlane =
max->hough->m_descriptor.referencePosition;
1211 refPlane = hit->prd->detectorElement()->surface(hit->prd->identify()).center().perp();
1213 refPlane = hit->prd->detectorElement()->surface(hit->prd->identify()).center().z();
1215 double r =
isBarrel ? refPlane : maxpos;
1216 double z =
isBarrel ? maxpos : refPlane;
1217 double theta =
max->theta;
1227 double phi = pit->first->pos;
1230 double sinphi = scphi.
sn;
1231 double cosphi = scphi.
cs;
1234 double sintheta = sctheta.
sn;
1235 double costheta = sctheta.
cs;
1237 std::pair<Amg::Vector3D, Amg::Vector3D>& posDir = directionsPerChamberLayer[chIndex];
1241 <<
" setting position: perp " << posDir.first.perp() <<
" z " << posDir.first.z() <<
" phi pos "
1242 << posDir.first.phi() <<
" direction phi " << posDir.second.phi() <<
" theta pos "
1243 << posDir.first.theta() <<
" direction theta " << posDir.second.theta() <<
" ref perp " <<
r <<
" z "
1244 <<
z <<
" phi " << phi <<
" theta " << theta);
1245 if (posDir.first.dot(posDir.second) < 0.) {
1246 ATH_MSG_WARNING(
" direction not pointing to IP " << posDir.first.unit().dot(posDir.second));
1250 std::map<Identifier, std::set<const Trk::PrepRawData*>>
::iterator pos = phiHitsPerChamber.find(chId);
1251 if (
pos != phiHitsPerChamber.end()) {
1253 if (ipos.second) { prdsPerChamber[chId].insert(
pos->second.begin(),
pos->second.end()); }
1259 return prd1->
identify() < prd2->identify();
1261 std::map<Identifier, std::set<const Trk::PrepRawData*>>
::iterator chit = prdsPerChamber.begin();
1262 std::map<Identifier, std::set<const Trk::PrepRawData*>>
::iterator chit_end = prdsPerChamber.end();
1263 for (; chit != chit_end; ++chit) {
1265 std::vector<const Trk::PrepRawData*> prds;
1266 prds.insert(prds.end(), chit->second.begin(), chit->second.end());
1267 std::stable_sort(prds.begin(), prds.end(), sortPrdIds);
1271 std::map<MuonStationIndex::ChIndex, std::pair<Amg::Vector3D, Amg::Vector3D>>::const_iterator
pos =
1272 directionsPerChamberLayer.find(chIndex);
1275 if (
pos != directionsPerChamberLayer.end()) {
1276 gpos =
pos->second.first;
1277 gdir =
pos->second.second;
1279 ATH_MSG_WARNING(
"No global position and direction found, calculating from surface");
1281 gdir = -1 * gpos.unit();
1285 <<
" z " << gpos.z() <<
" phi pos " << gpos.phi() <<
" direction phi " << gdir.phi()
1286 <<
" theta pos " << gpos.theta() <<
" theta " << gdir.theta() <<
" hits "
1294 if (chamberData.empty())
continue;
1295 if (addedPhiHits.empty()) {
1300 ATH_MSG_DEBUG(
"adding pattern combination with chambers " << chamberData.size() <<
" phi layers " << addedPhiHits.size()
1310 if (
hits.empty())
return false;
1313 Identifier id =
hits.front()->tgc ?
hits.front()->tgc->etaCluster.front()->identify() :
hits.front()->prd->identify();
1323 Identifier id_hit =
hits.front()->tgc ?
hits.front()->tgc->etaCluster.front()->identify() :
hits.front()->prd->identify();
1336 unsigned int nmaxima = 0;
1337 while (nmaxima < 5) {
1339 if (
hough.findMaximum(maximum, selectorLoose)) {
1340 hough.associateHitsToMaximum(maximum,
hits);
1342 << nmaxima <<
" " << maximum.
max <<
" trigConfirmed " << maximum.
triggerConfirmed <<
" pos " << maximum.
pos
1343 <<
" theta " << maximum.
theta <<
" binPos " << maximum.
binpos <<
" binRange " << maximum.
binposmin <<
" -- "
1350 const unsigned int nHitsInMaximum = maximum.
hits.size();
1351 for (
unsigned int i = 0;
i < nHitsInMaximum; ++
i) {
1364 if (nmdt > 0 || (nmm + nstgc) > 0) {
1365 maxima.emplace_back(std::make_unique<MuonHough::MuonLayerHough::Maximum>(maximum));
1367 if (maximum.
max >
selector.getCutValue(maximum.
pos)) seedMaxima.push_back(maxima.back());
1372 if (nmaxima > 0) {
ATH_MSG_VERBOSE(
"findMaxima: No more maxima found " << nmaxima); }
1382 if (
hits.empty())
return false;
1388 unsigned int nmaxima = 0;
1389 while (nmaxima < 5) {
1391 if (
hough.findMaximum(maximum, 1.9)) {
1392 hough.associateHitsToMaximum(maximum,
hits);
1394 ATH_MSG_DEBUG(
"findMaxima(Phi): Found Phi maximum " << nmaxima <<
" height " << maximum.
max <<
" pos " << maximum.
pos
1396 <<
" -- " << maximum.
binposmax <<
" nHits " << maximum.
hits.size());
1398 const unsigned int nHitsInMaximum = maximum.
hits.size();
1399 for (
unsigned int i = 0;
i < nHitsInMaximum; ++
i) {
1410 bool maximum_matched =
false;
1411 for (
auto pit = maxima.begin(); pit != maxima.end(); ++pit) {
1417 ATH_MSG_DEBUG(
"extendSeed: sector has already been added! Skip. ");
1418 bool maximum_hitmatched =
true;
1419 for (
unsigned int k = 0;
k < maximum.
hits.size(); ++
k) {
1421 maximum_hitmatched =
false;
1425 if (maximum_hitmatched) {
1426 maximum_matched =
true;
1433 if (maximum_matched) {
1437 maxima.push_back(std::make_shared<MuonHough::MuonPhiLayerHough::Maximum>(maximum));
1441 if (nmaxima > 0) {
ATH_MSG_VERBOSE(
"findMaxima(Phi): No more maxima found " << nmaxima); }
1456 houghData.
sector = sector;
1461 if (
hashes.empty())
continue;
1481 collectionsPerSector.
sector);
1493 typedef PRD_MultiTruthCollection::const_iterator iprdt;
1494 std::pair<iprdt, iprdt>
range = truthCol.equal_range(
id);
1497 if (!
i->second.isValid()) {
1498 ATH_MSG_WARNING(
"Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
1501 if (link.
cptr() && abs(link.
cptr()->pdg_id()) == 13) {
1504 truthHits.insert(
id);
1512 if (mdts.
empty())
return;
1518 unsigned int technology =
m_idHelperSvc->technologyIndex(chid);
1520 unsigned int nmdts(mdts.
size()), nmdtsBad{0};
1527 float r =
rCor(*prd);
1528 float x = barrelLike ?
r : prd->globalPosition().z();
1529 float y = barrelLike ? prd->globalPosition().z() :
r;
1530 int sublayer =
sublay(
id);
1535 debug->time = prd->tdc();
1541 hits.emplace_back(hit);
1546 <<
" -> hits: " << nmdts <<
" bad " << nmdtsBad <<
" isSmallChamber "
1556 unsigned int technology =
m_idHelperSvc->technologyIndex(chid);
1560 unsigned int neta{0}, nphi{0};
1568 <<
" -> eta hits " << neta <<
" phi hits " << nphi);
1571 int sublayer =
sublay(
id);
1573 debug->isEtaPhi = (neta && nphi);
1574 debug->trigConfirm = 1;
1575 debug->time = prd->time();
1578 float weight = (neta && nphi) ? 2 : 1;
1580 const float r =
rCor(*prd);
1581 const float phi = prd->globalPosition().phi();
1582 const double phi1 = phi;
1585 phiHits.emplace_back(hit);
1587 const float x =
rCor(*prd);
1588 const float y = prd->globalPosition().z();
1589 const float stripCor = 0.5 * prd->
detectorElement()->StripWidth(
false);
1590 const float ymin =
y - stripCor;
1591 const float ymax =
y + stripCor;
1592 debug->r = stripCor;
1594 hits.emplace_back(hit);
1600 if (rpcs.
empty())
return;
1603 unsigned int technology =
m_idHelperSvc->technologyIndex(chid);
1608 unsigned int neta{0}, nphi{0};
1616 <<
" -> eta hits " << neta <<
" phi hits " << nphi);
1620 int sublayer =
sublay(
id);
1622 debug->isEtaPhi = (neta && nphi);
1623 debug->trigConfirm = 1;
1624 debug->time = prd->time();
1627 float weight = (neta && nphi) ? 2 : 1;
1629 const float r =
rCor(*prd);
1630 const float phi = prd->globalPosition().phi();
1631 const double phi1 = phi;
1634 phiHits.emplace_back(hit);
1636 const float x =
rCor(*prd);
1637 const float y = prd->globalPosition().z();
1638 const float stripCor = 0.5 * prd->
detectorElement()->StripWidth(
false);
1639 const float ymin =
y - stripCor;
1640 const float ymax =
y + stripCor;
1641 debug->r = stripCor;
1643 hits.emplace_back(hit);
1650 if (mms.
empty())
return;
1656 unsigned int technology =
m_idHelperSvc->technologyIndex(chid);
1661 std::array<double,8> multiplicity{};
1664 int sublayer =
sublay(
id) % 10;
1665 multiplicity[sublayer]++;
1669 for (
int i = 0;
i<8 ;
i++)
if(multiplicity[
i]>0)
ATH_MSG_DEBUG(
" sublayer " <<
i <<
" hits " << multiplicity[
i]);
1674 float x = prd->globalPosition().z();
1675 float y =
rCor(*prd);
1676 int sublayer =
sublay(
id) % 10;
1678 float ymin =
y - stripCor;
1679 float ymax =
y + stripCor;
1685 debug->r = stripCor;
1688 std::unique_ptr<MuonHough::Hit> hit = std::make_unique<MuonHough::Hit>(sublayer,
x,
ymin,
ymax,
weight,
debug, prd);
1689 hits.emplace_back(std::move(hit));
1695 if (stgcs.
empty())
return;
1701 bool isNeighbouringSector = sector != selectedSector;
1702 unsigned int technology =
m_idHelperSvc->technologyIndex(chid);
1705 <<
" -> hits: " << stgcs.
size());
1709 int channelType =
m_idHelperSvc->stgcIdHelper().channelType(
id);
1712 if (isNeighbouringSector && channelType == 1)
continue;
1713 int sublayer =
sublay(
id);
1715 std::unique_ptr<MuonHough::HitDebugInfo>
debug =
1716 std::make_unique<MuonHough::HitDebugInfo>(technology, sector, region,
layer, sublayer);
1717 debug->isEtaPhi = 1;
1718 debug->trigConfirm =
true;
1724 float x = prd->globalPosition().z();
1725 float y =
rCor(*prd);
1726 float stripCor = 1.5;
1732 stripCor = 0.5 * stripWidth;
1734 debug->r = stripCor;
1735 float ymin =
y - stripCor;
1736 float ymax =
y + stripCor;
1738 hits.emplace_back(hit);
1750 ATH_MSG_DEBUG(
" Pad chWidth " << chWidth <<
" phi global " << prd->globalPosition().phi());
1751 }
else if (
m_idHelperSvc->stgcIdHelper().channelType(
id) == 2) {
1758 ATH_MSG_DEBUG(
" Wire Gang chWidth " << chWidth <<
" phi global " << prd->globalPosition().phi());
1769 double phi1 = gp1.phi();
1770 double phi2 = gp2.phi();
1771 double phi1c = phi1;
1772 double phi2c = phi2;
1774 if (phi_check > 0.3) {
1775 ATH_MSG_WARNING(
"bad local phi: in " << phi1 <<
", " << phi2 <<
" sector phi "
1779 if (isNeighbouringSector &&
1783 <<
" global phi: in " << phi1 <<
", " << phi2 <<
" sector phi "
1787 float r =
rCor(*prd);
1788 float phiMin =
std::min(phi1c, phi2c);
1789 float phiMax =
std::max(phi1c, phi2c);
1791 << phiMax <<
" bc " <<
debug->barcode <<
" chw " << chWidth <<
" trigC "
1792 <<
debug->trigConfirm <<
" g phi " << phi1 <<
" " << phi2);
1795 phiHits.emplace_back(phiHit);
1801 std::vector<std::unique_ptr<TgcHitClusteringObj>>& tgcClusteringObjs,
const TgcPrepDataCollection& tgcs,
1803 if (tgcs.
empty())
return;
1804 tgcClusteringObjs.push_back(std::make_unique<TgcHitClusteringObj>(&
m_idHelperSvc->tgcIdHelper()));
1806 std::vector<const TgcPrepData*> prds;
1807 prds.insert(prds.begin(), tgcs.
begin(), tgcs.
end());
1823 ATH_MSG_DEBUG(
"TgcHitClusteringObj, no eta cluster selected! ");
1830 std::vector<int> sectors;
1832 unsigned int technology =
m_idHelperSvc->technologyIndex(chid);
1833 for (
unsigned int si = 0; si < sectors.size(); ++si) {
1834 if (sectors[si] != sector)
continue;
1837 const Identifier id =
cl.etaCluster.front()->identify();
1852 double phi1 = phimin;
1853 double phi2 = phimax;
1856 <<
", y12: "<<y12<<
", y21: "<<y21<<
", y22: "<<y22<<
", phi11: "<<phi11<<
", "
1857 <<
"phi12: "<<phi12<<
", phi21: "<<phi21<<
", phi22: "<<phi22<<
" ymin: "<<
ymin<<
", ymax: "<<
ymax
1858 <<
", phimin: "<<phimin<<
", phimax: "<<phimax);
1861 debug->clusterSize =
cl.etaCluster.size();
1862 debug->clusterLayers = 2;
1863 debug->isEtaPhi =
true;
1864 debug->time =
cl.etaCluster.front()->getBcBitMap();
1873 std::unique_ptr<MuonHough::Hit> hit = std::make_unique<MuonHough::Hit>(sublayer,
x,
ymin,
ymax, 2,
debug,
nullptr, &
cl);
1874 std::unique_ptr<MuonHough::PhiHit> phiHit =
1875 std::make_unique<MuonHough::PhiHit>(sublayer, y11, phi1, phi2, 2, phiDebug,
nullptr, &
cl);
1876 hits.emplace_back(std::move(hit));
1877 phiHits.emplace_back(std::move(phiHit));
1882 <<
" -> etaHits: " <<
hits.size() <<
" phiHits: " << phiHits.size()
1883 <<
" sectors: " << sectors.size());
1893 m_collectionsPerSector[sector - 1].technologyRegionHashVecs[techIndex][sectorLayerHash].push_back(
hash);
1898 if (m_sectorSetup)
return;
1899 std::lock_guard kuchen(m_mutex);
1901 if (m_sectorSetup)
return;
1906 for (
unsigned int i = 0;
i < m_collectionsPerSector.size(); ++
i) {
1907 m_collectionsPerSector[
i].sector =
i + 1;
1908 m_collectionsPerSector[
i].technologyRegionHashVecs.resize(
m_ntechnologies);
1909 for (
auto it = m_collectionsPerSector[
i].technologyRegionHashVecs.begin();
1910 it != m_collectionsPerSector[
i].technologyRegionHashVecs.end(); ++
it) {
1911 it->resize(nsectorHashMax);
1919 auto loadHashes = [
this] (
const MuonIdHelper& idHelper){
1920 auto it = idHelper.module_begin();
1921 const auto it_end = idHelper.module_end();
1922 for (;
it != it_end; ++
it) {
1924 idHelper.get_module_hash(*
it,
hash);
1941 const auto it_end =
m_idHelperSvc->mmIdHelper().detectorElement_end();
1942 for (;
it != it_end; ++
it) {
1951 const auto it_end =
m_idHelperSvc->stgcIdHelper().detectorElement_end();
1952 for (;
it != it_end; ++
it) {
1957 int sectorU = sector != 1 ? sector - 1 : 16;
1958 int sectorD = sector != 16 ? sector + 1 : 1;
1967 const auto it_end =
m_idHelperSvc->tgcIdHelper().module_end();
1968 for (;
it != it_end; ++
it) {
1972 int nstrips = detEl->
nStrips(1);
1975 std::vector<int> sectors1{}, sectors2{};
1978 std::unordered_set<int> added{};
1979 for (
const int sector : sectors1) {
1981 added.insert(sector);
1983 for (
const int sector: sectors2) {
1984 if (added.insert(sector).second){
1993 for (
int sector = 1; sector <= 16; ++sector) {
1997 for (
unsigned int hash = 0;
hash < nsectorHashMax; ++
hash) {
1998 std::pair<MuonStationIndex::DetectorRegionIndex, MuonStationIndex::LayerIndex> regionLayer =
2003 currentRegion = regionLayer.first;
2014 <<
" " << std::setw(4) <<
vec[tech][
hash].
size());
2020 m_sectorSetup =
true;
2024 if (truth.size() ==
found.size()) {
2025 ATH_MSG_DEBUG(
" All hits found: truth " << truth.size() <<
" found " <<
found.size());
2027 ATH_MSG_DEBUG(
" Some truth hits not found: truth " << truth.size() <<
" found " <<
found.size());
2028 std::vector<Identifier>
result(truth.size() -
found.size());
2030 std::set_difference(truth.begin(), truth.end(),
found.begin(),
found.end(),
result.begin());