18 const float OneOverSqrt12 = 1. / std::sqrt(12);
22 MuonLayerSegmentFinderTool::MuonLayerSegmentFinderTool(
const std::string&
type,
const std::string&
name,
const IInterface*
parent) :
24 declareInterface<IMuonLayerSegmentFinderTool>(
this);
39 return StatusCode::SUCCESS;
43 const MuonLayerPrepRawData& layerPrepRawData, std::vector<std::shared_ptr<const Muon::MuonSegment> >& segments)
const {
45 " Running segment finding in sector "
48 <<
intersection.trackParameters->position().perp() <<
" z " <<
intersection.trackParameters->position().z() <<
" locX "
50 <<
" phi " <<
intersection.trackParameters->position().phi());
62 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
73 const std::vector<const MdtDriftCircleOnTrack*>& mdts = layerROTs.
getMdts();
74 const std::vector<const MuonClusterOnTrack*>&
clusters = layerROTs.
getClusters(clusterTech);
80 const std::vector<const MdtDriftCircleOnTrack*>& mdts,
81 const std::vector<const MuonClusterOnTrack*>&
clusters,
82 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
84 if (mdts.size() <= 2)
return;
86 std::unique_ptr<Trk::SegmentCollection> segColl = std::make_unique<Trk::SegmentCollection>(
SG::VIEW_ELEMENTS);
93 segments.emplace_back(mseg);
99 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
104 if (layerPrepRawData.
mms.empty() && layerPrepRawData.
stgcs.empty())
return;
113 ATH_MSG_DEBUG(
" MM prds " << layerPrepRawData.
mms.size() <<
" STGC prds " << layerPrepRawData.
stgcs.size());
120 NSWSegmentCache cache{};
123 if (!clustersSTGC.empty()) {
125 std::transform(clustersSTGC.begin(), clustersSTGC.end(), std::back_inserter(cache.inputClust),
129 if (!clustersMM.empty()) {
131 std::transform(clustersMM.begin(), clustersMM.end(), std::back_inserter(cache.inputClust),
134 if (cache.inputClust.empty())
return;
137 if (!m_patternSegs.empty()) {
138 std::set<Identifier> needed_rios{};
139 for (std::unique_ptr<const MuonClusterOnTrack>& clus : cache.inputClust) {
140 needed_rios.insert(clus->identify());
146 if (
intersection.trackParameters->associatedSurface().center().z() * seg->globalPosition().z() < 0)
continue;
150 for (
size_t n = 0; !hasNSW &&
n < seg->numberOfContainedROTs(); ++
n) {
151 const MuonClusterOnTrack *clus =
dynamic_cast<const MuonClusterOnTrack *
>(seg->rioOnTrack(
n));
152 hasNSW |= (clus && needed_rios.count(clus->identify()));
155 if (!hasNSW)
continue;
157 if (m_segmentMatchingTool->match(ctx,
intersection, *seg)) segments.emplace_back(seg->clone());
164 m_clusterSegMakerNSW->find(ctx, cache);
166 for (std::unique_ptr<MuonSegment>& seg : cache.constructedSegs) {
168 segments.emplace_back(std::move(seg));
172 void MuonLayerSegmentFinderTool::findCscSegments(
const EventContext& ctx,
const MuonLayerPrepRawData& layerPrepRawData,
173 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments)
const {
175 std::unique_ptr<MuonSegmentCombinationCollection> combi2D = m_csc2dSegmentFinder->find(layerPrepRawData.
cscs, ctx);
176 if (!combi2D)
return;
179 std::unique_ptr<MuonSegmentCombinationCollection> combi4D = m_csc4dSegmentFinder->find(*combi2D, ctx);
180 if (!combi4D)
return;
183 for (
auto com : *combi4D) {
188 for (
unsigned int i = 0;
i < nstations; ++
i) {
193 if (!segs || segs->empty())
continue;
195 for (std::unique_ptr<MuonSegment>& seg_it : *segs) {
197 segments.emplace_back(std::move(seg_it));
202 void MuonLayerSegmentFinderTool::findMdtSegmentsFromHough(
const EventContext& ctx,
204 std::vector<std::shared_ptr<const Muon::MuonSegment> >& segments)
const {
206 if(m_houghDataPerSectorVecKey.empty())
return;
207 unsigned int nprevSegments = segments.size();
214 if (!houghDataPerSectorVec.isValid()) {
220 if (
static_cast<int>(houghDataPerSectorVec->vec.size()) <= sector - 1) {
221 ATH_MSG_WARNING(
" MuonLayerHoughTool::HoughDataPerSectorVec smaller than sector "
222 << houghDataPerSectorVec->vec.size() <<
" sector " << sector);
227 unsigned int sectorLayerHash = MuonStationIndex::sectorLayerHash(regionIndex, layerIndex);
230 << sector <<
" " << MuonStationIndex::regionName(regionIndex) <<
" "
231 << MuonStationIndex::layerName(layerIndex) <<
" sector hash " << sectorLayerHash <<
" houghData "
232 << houghDataPerSectorVec->vec.size() <<
" " << houghDataPerSector.
maxVec.size());
235 if (houghDataPerSector.
maxVec.size() <= sectorLayerHash) {
236 ATH_MSG_WARNING(
" houghDataPerSector.maxVec.size() smaller than hash " << houghDataPerSector.
maxVec.size()
237 <<
" hash " << sectorLayerHash);
248 float r = barrelLike ? m_muonSectorMapping.transformRToSector(
intersection.trackParameters->position().perp(),
phi,
254 float x = barrelLike ?
r :
z;
255 float y = barrelLike ?
z :
r;
256 float theta = std::atan2(
x,
y);
258 ATH_MSG_DEBUG(
" Got Hough maxima " << maxVec.size() <<
" extrapolated position in Hough space (" <<
x <<
"," <<
y
259 <<
") error " << errx <<
" "
260 <<
" angle " <<
theta);
263 std::vector<std::unique_ptr<const Trk::MeasurementBase>> garbage;
264 auto handleMdt = [
this,
intersection, &garbage](
const MdtPrepData& prd, std::vector<const MdtDriftCircleOnTrack*>& mdts) {
268 garbage.emplace_back(mdt);
274 std::vector<const MuonClusterOnTrack*>&
clusters) {
276 if (!cluster)
return;
278 garbage.emplace_back(cluster);
283 MuonLayerHoughTool::MaximumVec::const_iterator mit = maxVec.begin();
284 MuonLayerHoughTool::MaximumVec::const_iterator mit_end = maxVec.end();
285 for (; mit != mit_end; ++mit) {
292 float pull =
residual / std::hypot(errx , maxwidth * OneOverSqrt12);
295 ATH_MSG_DEBUG(
" Hough maximum " << maximum.
max <<
" position (" << refPos <<
"," << maximum.
pos
297 <<
" residual " << residualTheta);
300 if (std::abs(
pull) > 5)
continue;
303 std::vector<const MdtDriftCircleOnTrack*> mdts;
304 std::vector<const MuonClusterOnTrack*>
clusters;
305 for (
const auto& hit : maximum.
hits) {
309 for (
const auto& prd : hit->tgc->etaCluster) {
312 }
else if (hit->prd) {
314 if (m_idHelperSvc->isMdt(
id))
315 handleMdt(
static_cast<const MdtPrepData&
>(*hit->prd), mdts);
324 ATH_MSG_DEBUG(
" Got Phi Hough maxima " << phiMaxVec.size() <<
" phi " <<
phi);
327 MuonLayerHoughTool::PhiMaximumVec::const_iterator pit = phiMaxVec.begin();
328 MuonLayerHoughTool::PhiMaximumVec::const_iterator pit_end = phiMaxVec.end();
329 for (; pit != pit_end; ++pit) {
336 for (
const auto& phi_hit : maximum.
hits) {
339 Identifier id = phi_hit->tgc->phiCluster.front()->identify();
340 if (m_idHelperSvc->layerIndex(
id) !=
intersection.layerSurface.layerIndex)
continue;
341 for (
const auto& prd : phi_hit->tgc->phiCluster) handleCluster(*prd,
clusters);
342 }
else if (phi_hit->prd) {
344 if (m_idHelperSvc->layerIndex(
id) !=
intersection.layerSurface.layerIndex)
continue;
356 ATH_MSG_DEBUG(
" Done maximum: new segments " << segments.size() - nprevSegments);
358 ATH_MSG_DEBUG(
" Done with layer: new segments " << segments.size() - nprevSegments);