ATLAS Offline Software
Loading...
Searching...
No Matches
MuonSegmentFinderAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
21
22
24 ATH_CHECK(m_idHelperSvc.retrieve());
25 ATH_CHECK(m_printer.retrieve());
27 ATH_CHECK(m_segmentSelector.retrieve(DisableTool{m_segQuality<0}));
29 ATH_CHECK(m_patternCalibration.retrieve(DisableTool{!m_runMdtSegments}));
30 ATH_CHECK(m_segmentMaker.retrieve(DisableTool{!m_runMdtSegments}));
31
32 const bool doNSW = m_doSTgcSegments || m_doMMSegments;
33 ATH_CHECK(m_clusterCreator.retrieve(DisableTool{!doNSW}));
34 ATH_CHECK(m_clusterSegMakerNSW.retrieve(DisableTool{!doNSW}));
35 ATH_CHECK(m_csc2dSegmentFinder.retrieve(DisableTool{m_cscPrdsKey.empty()}));
36 ATH_CHECK(m_csc4dSegmentFinder.retrieve(DisableTool{m_cscPrdsKey.empty()}));
37
41 ATH_CHECK(m_cscPrdsKey.initialize(!m_cscPrdsKey.empty())); // check for layouts without CSCs
42 ATH_CHECK(m_patternCollKey.initialize());
43
44 return StatusCode::SUCCESS;
45}
46
47StatusCode MuonSegmentFinderAlg::execute(const EventContext& ctx) const {
48
49 NSWSegmentCache nswCache{};
50 nswCache.buildQuads = !m_segmentNSWCollectionKey.empty();
51
52 std::unique_ptr<Trk::SegmentCollection> segmentContainer = std::make_unique<Trk::SegmentCollection>();
53 std::unique_ptr<Trk::SegmentCollection> nswSegmentContainer = !m_segmentNSWCollectionKey.empty() ? std::make_unique<Trk::SegmentCollection>()
54 : nullptr;
55
56
57 const MuonPatternCombinationCollection* patternColl{nullptr};
58 ATH_CHECK(SG::get(patternColl, m_patternCollKey, ctx));
59 ATH_MSG_DEBUG("Processing the pattern collections with " << patternColl->size() << " Collections ");
60
61 for (const Muon::MuonPatternCombination* patt : *patternColl) {
62 ATH_MSG_DEBUG("Working on pattern combination " << m_printer->print(*patt));
63 // check the technology & call the corresponding segment finder
64
65 ATH_CHECK(createSegmentsWithMDTs(ctx, patt, segmentContainer.get()));
66
67
68 createNSWSegments(ctx, patt, nswCache);
69
71 segmentContainer->insert(segmentContainer->end(), std::make_move_iterator(nswCache.constructedSegs.begin()),
72 std::make_move_iterator(nswCache.constructedSegs.end()));
73
74 nswCache.constructedSegs.clear();
75
76 if (!nswSegmentContainer) continue;
77 nswSegmentContainer->insert(nswSegmentContainer->end(), std::make_move_iterator(nswCache.quadSegs.begin()),
78 std::make_move_iterator(nswCache.quadSegs.end()));
79 nswCache.quadSegs.clear();
80
81 } // end loop on pattern combinations
82
83 m_segmentOverlapRemovalTool->removeDuplicates(*segmentContainer);
84
85 std::unique_ptr<MuonSegmentCombinationCollection> csc4dSegmentCombinations{};
86 ATH_CHECK(createCscSegments(ctx, csc4dSegmentCombinations));
87 appendSegmentsFromCombi(csc4dSegmentCombinations, segmentContainer.get());
88
90 ATH_MSG_DEBUG("segments before overlap removal: " << segmentContainer->size());
91 m_segmentOverlapRemovalTool->removeDuplicates(*segmentContainer);
92 ATH_MSG_DEBUG(" Segments after overlap removal: " << segmentContainer->size());
93
94
95 if (m_printSummary){
96 ATH_MSG_INFO("Number of segments found " << segmentContainer->size());
97 for (Trk::Segment* tseg : *segmentContainer) {
98 const Muon::MuonSegment* mseg{dynamic_cast<Muon::MuonSegment*>(tseg)};
99 ATH_MSG_INFO(m_printer->print(*mseg)<<std::endl<<m_printer->print(mseg->containedMeasurements())<<std::endl);
100 }
101 }
102
103
105 ATH_CHECK(handle.record(std::move(segmentContainer)));
106
107 if (!m_segmentNSWCollectionKey.empty()) {
108 m_segmentOverlapRemovalTool->removeDuplicates(*nswSegmentContainer);
110 ATH_CHECK(handle_segNSW.record(std::move(nswSegmentContainer)));
111 }
112 return StatusCode::SUCCESS;
113} // execute
114
115StatusCode MuonSegmentFinderAlg::createCscSegments(const EventContext& ctx,
116 std::unique_ptr<MuonSegmentCombinationCollection>& csc4dSegmentCombinations) const {
117
118 const Muon::CscPrepDataContainer* cscPrds{nullptr};
119 ATH_CHECK(SG::get(cscPrds, m_cscPrdsKey, ctx));
120 if (!cscPrds) return StatusCode::SUCCESS;
121
122 std::vector<const Muon::CscPrepDataCollection*> cscCols;
123 std::copy_if(cscPrds->begin(),cscPrds->end(), std::back_inserter(cscCols), [](const Muon::CscPrepDataCollection* coll) {return !coll->empty();});
124 ATH_MSG_DEBUG("Retrieved CscPrepDataContainer " << cscCols.size());
125 if (cscCols.empty()) return StatusCode::SUCCESS;
126 std::unique_ptr<MuonSegmentCombinationCollection> csc2dSegmentCombinations = m_csc2dSegmentFinder->find(cscCols, ctx);
127 if (!csc2dSegmentCombinations) return StatusCode::SUCCESS;
128
129 csc4dSegmentCombinations = m_csc4dSegmentFinder->find(*csc2dSegmentCombinations, ctx);
130 return StatusCode::SUCCESS;
131}
132void MuonSegmentFinderAlg::appendSegmentsFromCombi(const std::unique_ptr<MuonSegmentCombinationCollection>& combi_coll,
133 Trk::SegmentCollection* segmentContainer) const {
134 if (!combi_coll) return;
136 for (const Muon::MuonSegmentCombination* combi: *combi_coll) {
137 if (!combi) {
138 ATH_MSG_WARNING(" empty MuonSegmentCombination!!! ");
139 continue;
140 }
141 const unsigned int nstations = combi->numberOfStations();
142 const bool useEta = combi->useStripsInSegment(1);
143 const bool usePhi = combi->useStripsInSegment(0);
144
145 // loop over chambers in combi and extract segments
146 for (unsigned int i = 0; i < nstations; ++i) {
147 // loop over segments in station
148 Muon::MuonSegmentCombination::SegmentVec* segments = combi->stationSegments(i);
149 // check if not empty
150 if (!segments || segments->empty()) continue;
151 // loop over new segments, copy them into collection
152 for (std::unique_ptr<Muon::MuonSegment>& seg : *segments) {
153 if(m_segQuality >=0 && !m_segmentSelector->select(*seg, false, m_segQuality, useEta, usePhi)) continue;
154 ATH_MSG_VERBOSE("Append segment "<<std::endl<<m_printer->print(seg->containedMeasurements()));
155 segmentContainer->push_back(std::move(seg));
156 }
157
158 }
159 }
160}
161void MuonSegmentFinderAlg::createNSWSegments(const EventContext& ctx,
162 const Muon::MuonPatternCombination* patt,
163 NSWSegmentCache& cache) const {
164 // turn the PRD into MuonCluster
165 if (!m_doSTgcSegments && !m_doMMSegments) return;
166 std::map<int, std::vector<std::unique_ptr<const Muon::MuonClusterOnTrack>> > clustersPerSector;
167
168
169 for (const Muon::MuonPatternChamberIntersect& it :patt->chamberData()) {
170 if (it.prepRawDataVec().empty()) continue;
171
172 const Identifier id = it.prepRawDataVec().front()->identify();
173 const int sector = m_idHelperSvc->sector(id);
175 if (!m_idHelperSvc->isMM(id) && !m_idHelperSvc->issTgc(id)) continue;
176 for (const Trk::PrepRawData* pit : it.prepRawDataVec()) {
177 const Muon::MuonCluster* cl = dynamic_cast<const Muon::MuonCluster*>(pit);
178 if (!cl) continue;
179 else if (!m_doMMSegments && m_idHelperSvc->isMM(cl->identify())) continue;
180 else if (!m_doSTgcSegments && m_idHelperSvc->issTgc(cl->identify())) continue;
181 else if (m_removeUsedNswHits && cache.usedHits.count(cl->identify())) continue;
182 const Muon::MuonClusterOnTrack* newCluster = m_clusterCreator->createRIO_OnTrack(*cl, cl->globalPosition());
183 if (!newCluster) continue;
184 std::vector<std::unique_ptr<const Muon::MuonClusterOnTrack>>& clusters = clustersPerSector[sector];
185 clusters.emplace_back(newCluster);
186 }
187 }
188 for (auto&[sector, clusters] :clustersPerSector) {
189 ATH_MSG_VERBOSE("Run segment making on sector "<<sector);
190 cache.inputClust = std::move(clusters);
191 m_clusterSegMakerNSW->find(ctx, cache);
192 }
193}
194
195StatusCode MuonSegmentFinderAlg::createSegmentsWithMDTs(const EventContext& ctx,
196 const Muon::MuonPatternCombination* patcomb,
197 Trk::SegmentCollection* segs) const {
198
199 if (!m_runMdtSegments) {
200 ATH_MSG_DEBUG("Do not search segments in the Mdt part of the muon spectrometer");
201 return StatusCode::SUCCESS;
202 }
203
204 bool hasPhiMeasurements = m_patternCalibration->checkForPhiMeasurements(*patcomb);
206 ATH_CHECK(m_patternCalibration->calibrate(ctx, *patcomb, hitsPerRegion));
209 for (const ROTRegion& region : hitsPerRegion) {
210 for (const MdtVec& mdts : region.mdts()) {
211 if (mdts.empty()) continue;
212 ATH_MSG_VERBOSE("Calling segment finding for sector " << m_idHelperSvc->chamberNameString(mdts.front()->identify()));
213 // fit the segments
214 if (m_doFullFinder) {
215 if (msgLvl(MSG::VERBOSE)){
216 std::vector<const Trk::MeasurementBase*> meas {};
217 meas.insert(meas.end(), mdts.begin(), mdts.end());
218 meas.insert(meas.end(), region.clusters().begin(), region.clusters().end());
219 ATH_MSG_VERBOSE("Call segment maker with road pos: "<<Amg::toString(region.regionPos)
220 << " road dir: "<<Amg::toString(region.regionDir)
221 <<" nMdts: "<<mdts.size()<<" nClusters "<<region.clusters().size()
222 <<std::endl<<m_printer->print(meas));
223
224 }
225 m_segmentMaker->find(region.regionPos, region.regionDir, mdts, region.clusters(), hasPhiMeasurements, segs,
226 region.regionDir.mag());
227 } else {
228 std::vector<const Trk::RIO_OnTrack*> rios;
229 rios.insert(rios.begin(), mdts.begin(), mdts.end());
230 m_segmentMaker->find(rios, segs);
231 }
232 } // end loop on hits per region
233 }
234 return StatusCode::SUCCESS;
235}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataVector< Muon::MuonPatternCombination > MuonPatternCombinationCollection
This typedef represents a collection of MuonPatternCombination objects.
bool msgLvl(const MSG::Level lvl) const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
const_iterator end() const
return const_iterator for end of container
const_iterator begin() const
return const_iterator for first entry
Gaudi::Property< bool > m_runMdtSegments
Run the Mdt segment maker (Switched of the NCB systems)
virtual StatusCode initialize() override
Gaudi::Property< bool > m_doFullFinder
Run segment finding with eta / phi determination.
SG::ReadHandleKey< MuonPatternCombinationCollection > m_patternCollKey
StatusCode createCscSegments(const EventContext &ctx, std::unique_ptr< MuonSegmentCombinationCollection > &csc4dSegmentCombinations) const
Retrieve the raw outputs from the Csc segment makers for the curved combination.
void appendSegmentsFromCombi(const std::unique_ptr< MuonSegmentCombinationCollection > &combi_coll, Trk::SegmentCollection *segments) const
SG::WriteHandleKey< Trk::SegmentCollection > m_segmentCollectionKey
StatusCode createSegmentsWithMDTs(const EventContext &ctx, const Muon::MuonPatternCombination *patt, Trk::SegmentCollection *segs) const
ToolHandle< Muon::IMuonSegmentMaker > m_segmentMaker
Gaudi::Property< bool > m_doMMSegments
ToolHandle< Muon::IMuonPatternCalibration > m_patternCalibration
virtual StatusCode execute(const EventContext &ctx) const override
SG::WriteHandleKey< Trk::SegmentCollection > m_segmentNSWCollectionKey
SG::ReadHandleKey< Muon::CscPrepDataContainer > m_cscPrdsKey
Muon::IMuonNSWSegmentFinderTool::SegmentMakingCache NSWSegmentCache
ToolHandle< Muon::IMuonNSWSegmentFinderTool > m_clusterSegMakerNSW
Gaudi::Property< int > m_segQuality
Apply a preselection on the segments.
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
Gaudi::Property< bool > m_printSummary
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
void createNSWSegments(const EventContext &ctx, const Muon::MuonPatternCombination *patt, NSWSegmentCache &cache) const
Gaudi::Property< bool > m_removeUsedNswHits
If switched to true, hits that have been already successfully combined to a segment are removed from ...
ToolHandle< ICscSegmentFinder > m_csc4dSegmentFinder
ToolHandle< Muon::IMuonClusterOnTrackCreator > m_clusterCreator
ToolHandle< Muon::IMuonSegmentOverlapRemovalTool > m_segmentOverlapRemovalTool
ToolHandle< ICscSegmentFinder > m_csc2dSegmentFinder
Gaudi::Property< bool > m_doSTgcSegments
Run the NSW segment maker.
ToolHandle< Muon::IMuonSegmentSelectionTool > m_segmentSelector
std::vector< const MdtDriftCircleOnTrack * > MdtVec
std::vector< ROTRegion > ROTsPerRegion
Base class for Muon cluster RIO_OnTracks.
This class holds information needed for the Moore and MoMu pattern recognition for a muon chamber.
The MuonPatternCombination class provides the means to store the output of the initial global pattern...
const std::vector< MuonPatternChamberIntersect > & chamberData() const
access to the MuonPatternChamberIntersect associated with the MuonPatternCombination
Class to hold a set of MuonSegments belonging together.
std::vector< std::unique_ptr< MuonSegment > > SegmentVec
This is the common class for 3D segments used in the muon spectrometer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Base class for all TrackSegment implementations, extends the common MeasurementBase.
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
MuonPrepDataCollection< CscPrepData > CscPrepDataCollection
MuonPrepDataContainerT< CscPrepData > CscPrepDataContainer
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
DataVector< Trk::Segment > SegmentCollection
bool buildQuads
Toggle whether quad segments should be built or not.
std::vector< std::unique_ptr< Muon::MuonSegment > > quadSegs
Output vector to which the quadruplet segments are pushed back.
std::set< Identifier > usedHits
Set of all hits used in the segment making.
std::vector< std::unique_ptr< Muon::MuonSegment > > constructedSegs
Output vector to which the constructed segments are pushed_back.
std::vector< std::unique_ptr< const Muon::MuonClusterOnTrack > > inputClust
Input vector containing all muon cluster on track.