18 const float OneOverSqrt12 = 1. / std::sqrt(12);
21 using namespace MuonStationIndex;
26 ATH_CHECK(m_muonPRDSelectionTool.retrieve());
28 ATH_CHECK(m_csc2dSegmentFinder.retrieve(DisableTool{!m_idHelperSvc->hasCSC() || m_csc2dSegmentFinder.empty()}));
29 ATH_CHECK(m_csc4dSegmentFinder.retrieve(DisableTool{!m_idHelperSvc->hasCSC() || m_csc4dSegmentFinder.empty()}));
30 ATH_CHECK(m_patternSegs.initialize(!m_patternSegs.empty()));
31 ATH_CHECK(m_segmentMatchingTool.retrieve(DisableTool{m_patternSegs.empty()}));
32 ATH_CHECK(m_houghDataPerSectorVecKey.initialize(!m_houghDataPerSectorVecKey.empty()));
33 ATH_CHECK(m_clusterSegMakerNSW.retrieve(DisableTool{m_clusterSegMakerNSW.empty()|| !m_patternSegs.empty()}));
35 return StatusCode::SUCCESS;
39 const MuonLayerPrepRawData& layerPrepRawData, std::vector<std::shared_ptr<const Muon::MuonSegment> >& segments)
const {
41 " Running segment finding in sector "
43 <<
" layer " << MuonStationIndex::layerName(
intersection.layerSurface.layerIndex) <<
" intersection position: r "
44 <<
intersection.trackParameters->position().perp() <<
" z " <<
intersection.trackParameters->position().z() <<
" locX "
46 <<
" phi " <<
intersection.trackParameters->position().phi());
49 findClusterSegments(ctx,
intersection, layerPrepRawData, segments);
53 findMdtSegments(
intersection, layerPrepRawData, segments);
58 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
61 if (!m_muonPRDSelectionTool->calibrateAndSelect(
intersection, layerPrepRawData, layerROTs)) {
67 using namespace MuonStationIndex;
70 const std::vector<const MdtDriftCircleOnTrack*>& mdts = layerROTs.
getMdts();
71 const std::vector<const MuonClusterOnTrack*>&
clusters = layerROTs.
getClusters(clusterTech);
76 void MuonLayerSegmentFinderTool::findMdtSegments(
const MuonSystemExtension::Intersection&
intersection,
77 const std::vector<const MdtDriftCircleOnTrack*>& mdts,
78 const std::vector<const MuonClusterOnTrack*>&
clusters,
79 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
81 if (mdts.size() <= 2)
return;
83 std::unique_ptr<Trk::SegmentCollection> segColl = std::make_unique<Trk::SegmentCollection>(
SG::VIEW_ELEMENTS);
90 segments.emplace_back(mseg);
96 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
98 if (!layerPrepRawData.
cscs.empty()) findCscSegments(ctx, layerPrepRawData, segments);
101 if (layerPrepRawData.
mms.empty() && layerPrepRawData.
stgcs.empty())
return;
105 if (!m_muonPRDSelectionTool->calibrateAndSelect(
intersection, layerPrepRawData, layerROTs)) {
110 ATH_MSG_DEBUG(
" MM prds " << layerPrepRawData.
mms.size() <<
" STGC prds " << layerPrepRawData.
stgcs.size());
117 NSWSegmentCache cache{};
120 if (!clustersSTGC.empty()) {
122 std::transform(clustersSTGC.begin(), clustersSTGC.end(), std::back_inserter(cache.inputClust),
126 if (!clustersMM.empty()) {
128 std::transform(clustersMM.begin(), clustersMM.end(), std::back_inserter(cache.inputClust),
131 if (cache.inputClust.empty())
return;
134 if (!m_patternSegs.empty()) {
135 std::set<Identifier> needed_rios{};
136 for (std::unique_ptr<const MuonClusterOnTrack>& clus : cache.inputClust) {
137 needed_rios.insert(clus->identify());
143 if (
intersection.trackParameters->associatedSurface().center().z() * seg->globalPosition().z() < 0)
continue;
147 for (
size_t n = 0; !hasNSW &&
n < seg->numberOfContainedROTs(); ++
n) {
148 const MuonClusterOnTrack *clus =
dynamic_cast<const MuonClusterOnTrack *
>(seg->rioOnTrack(
n));
149 hasNSW |= (clus && needed_rios.count(clus->identify()));
152 if (!hasNSW)
continue;
154 if (m_segmentMatchingTool->match(ctx,
intersection, *seg)) segments.emplace_back(seg->clone());
161 m_clusterSegMakerNSW->find(ctx, cache);
163 for (std::unique_ptr<MuonSegment>& seg : cache.constructedSegs) {
165 segments.emplace_back(std::move(seg));
169 void MuonLayerSegmentFinderTool::findCscSegments(
const EventContext& ctx,
const MuonLayerPrepRawData& layerPrepRawData,
170 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
172 std::unique_ptr<MuonSegmentCombinationCollection> combi2D = m_csc2dSegmentFinder->find(layerPrepRawData.
cscs, ctx);
173 if (!combi2D)
return;
176 std::unique_ptr<MuonSegmentCombinationCollection> combi4D = m_csc4dSegmentFinder->find(*combi2D, ctx);
177 if (!combi4D)
return;
180 for (
auto com : *combi4D) {
185 for (
unsigned int i = 0;
i < nstations; ++
i) {
190 if (!segs || segs->empty())
continue;
192 for (std::unique_ptr<MuonSegment>& seg_it : *segs) {
194 segments.emplace_back(std::move(seg_it));
199 void MuonLayerSegmentFinderTool::findMdtSegmentsFromHough(
const EventContext& ctx,
201 std::vector<std::shared_ptr<const Muon::MuonSegment> >& segments)
const {
203 if(m_houghDataPerSectorVecKey.empty())
return;
204 unsigned int nprevSegments = segments.size();
210 SG::ReadHandle houghDataPerSectorVec{m_houghDataPerSectorVecKey, ctx};
211 if (!houghDataPerSectorVec.isValid()) {
217 if (
static_cast<int>(houghDataPerSectorVec->vec.size()) <= sector - 1) {
218 ATH_MSG_WARNING(
" MuonLayerHoughTool::HoughDataPerSectorVec smaller than sector "
219 << houghDataPerSectorVec->vec.size() <<
" sector " << sector);
228 << MuonStationIndex::layerName(layerIndex) <<
" sector hash " <<
sectorLayerHash <<
" houghData "
229 << houghDataPerSectorVec->vec.size() <<
" " << houghDataPerSector.
maxVec.size());
233 ATH_MSG_WARNING(
" houghDataPerSector.maxVec.size() smaller than hash " << houghDataPerSector.
maxVec.size()
245 float r = barrelLike ? m_muonSectorMapping.transformRToSector(
intersection.trackParameters->position().perp(),
phi,
251 float x = barrelLike ?
r :
z;
252 float y = barrelLike ?
z :
r;
253 float theta = std::atan2(
x,
y);
255 ATH_MSG_DEBUG(
" Got Hough maxima " << maxVec.size() <<
" extrapolated position in Hough space (" <<
x <<
"," <<
y
256 <<
") error " << errx <<
" "
257 <<
" angle " <<
theta);
260 std::vector<std::unique_ptr<const Trk::MeasurementBase>> garbage;
261 auto handleMdt = [
this,
intersection, &garbage](
const MdtPrepData& prd, std::vector<const MdtDriftCircleOnTrack*>& mdts) {
265 garbage.emplace_back(mdt);
271 std::vector<const MuonClusterOnTrack*>&
clusters) {
273 if (!cluster)
return;
275 garbage.emplace_back(cluster);
280 MuonLayerHoughTool::MaximumVec::const_iterator mit = maxVec.begin();
281 MuonLayerHoughTool::MaximumVec::const_iterator mit_end = maxVec.end();
282 for (; mit != mit_end; ++mit) {
289 float pull =
residual / std::hypot(errx , maxwidth * OneOverSqrt12);
292 ATH_MSG_DEBUG(
" Hough maximum " << maximum.
max <<
" position (" << refPos <<
"," << maximum.
pos
294 <<
" residual " << residualTheta);
297 if (std::abs(
pull) > 5)
continue;
300 std::vector<const MdtDriftCircleOnTrack*> mdts;
301 std::vector<const MuonClusterOnTrack*>
clusters;
302 for (
const auto& hit : maximum.
hits) {
306 for (
const auto& prd : hit->tgc->etaCluster) {
309 }
else if (hit->prd) {
311 if (m_idHelperSvc->isMdt(
id))
312 handleMdt(
static_cast<const MdtPrepData&
>(*hit->prd), mdts);
321 ATH_MSG_DEBUG(
" Got Phi Hough maxima " << phiMaxVec.size() <<
" phi " <<
phi);
324 MuonLayerHoughTool::PhiMaximumVec::const_iterator pit = phiMaxVec.begin();
325 MuonLayerHoughTool::PhiMaximumVec::const_iterator pit_end = phiMaxVec.end();
326 for (; pit != pit_end; ++pit) {
333 for (
const auto& phi_hit : maximum.
hits) {
336 Identifier id = phi_hit->tgc->phiCluster.front()->identify();
337 if (m_idHelperSvc->layerIndex(
id) !=
intersection.layerSurface.layerIndex)
continue;
338 for (
const auto& prd : phi_hit->tgc->phiCluster) handleCluster(*prd,
clusters);
339 }
else if (phi_hit->prd) {
341 if (m_idHelperSvc->layerIndex(
id) !=
intersection.layerSurface.layerIndex)
continue;
353 ATH_MSG_DEBUG(
" Done maximum: new segments " << segments.size() - nprevSegments);
355 ATH_MSG_DEBUG(
" Done with layer: new segments " << segments.size() - nprevSegments);