12 constexpr unsigned int num_sectors = 16;
16 inline const Trk::PrepRawData* prepData(
const std::shared_ptr<MuonHough::Hit>& hit) {
17 if (hit->prd)
return hit->prd;
18 if (hit->tgc)
return hit->tgc->phiCluster.front();
23 struct hough_chamber {
26 std::set<int> sectors;
44 return StatusCode::SUCCESS;
48 ATH_MSG_DEBUG(
"Cakes are availablei in "<<ctx.eventID().event_number());
52 if (!input_container.
isValid()) {
54 return StatusCode::FAILURE;
64 ATH_MSG_DEBUG(
"Find the inner detector candidates to be used for MuGirl / Segment tagging");
71 return StatusCode::SUCCESS;
77 return StatusCode::FAILURE;
79 if (tag_map->empty()) {
81 return StatusCode::SUCCESS;
84 for (
const auto& combined_tags : *tag_map) {
85 if (combined_tags.second->author() != xAOD::Muon::MuidCo) {
86 ATH_MSG_WARNING(
"Found a non MuidCo tag.... Please check " << combined_tags.second->toString());
91 out_cache.
tag_map.push_back(std::move(cache));
98 return StatusCode::SUCCESS;
125 std::vector<Muon::MuonSystemExtension::Intersection> intersects = extension->
layerIntersections();
145 if (msgLevel(MSG::DEBUG)) {
146 std::stringstream sstr;
148 sstr <<
" * " << extended->
toString() << std::endl;
151 sstr << std::endl <<
" ======== The following tracks were already successfully combined ======== " << std::endl;
153 sstr <<
" = " << combined->
toString() << std::endl;
157 sstr << std::endl <<
" ++++++++ The following candidates were not extrapolated ++++++++ " << std::endl;
163 std::find_if(begin, end,
166 sstr <<
" + " << rejected->
toString() << std::endl;
170 <<
" tracks through the spectrometer" << std::endl
174 return StatusCode::SUCCESS;
181 return StatusCode::FAILURE;
183 const std::vector<Muon::HoughDataPerSec>& hough_data = readHandle->vec;
185 auto count_finished = [&output_cache]() ->
unsigned int {
187 for (
const auto& sector_hits : output_cache.
hit_sectors) { n += sector_hits.second.size() >= num_sectors; }
195 const RegionIndex region_index =
static_cast<RegionIndex
>(det_region);
200 const std::set<Identifier>& masked_hits = output_cache.
consumed_hits[hash];
203 auto num_hough_hits = [&masked_hits,
this](
const std::shared_ptr<MuonHough::MuonLayerHough::Maximum>& hough_maximum) {
204 std::map<Identifier, hough_chamber> chamber_counts;
205 for (
const std::shared_ptr<MuonHough::Hit>& hough_hit : hough_maximum->hits) {
214 hough_chamber& chamber = chamber_counts[
m_idHelperSvc->chamberId(chId)];
217 chamber.eta += glob_pos.eta();
222 for (
auto& ch_it : chamber_counts) {
223 if (N.nhits < ch_it.second.nhits) { N = std::move(ch_it.second); }
226 N.eta /= std::max(N.nhits, 1);
233 for (
const std::shared_ptr<MuonHough::MuonLayerHough::Maximum>& maxima : eta_hits) {
235 const hough_chamber effect_hits = num_hough_hits(maxima);
240 <<
", hits: " << effect_hits.nhits);
242 for (
const int sector : effect_hits.sectors) {
243 output_cache.
hit_sectors[region_index].insert(sector);
245 output_cache.
eta_seeds[sector].push_back(effect_hits.eta);
248 if (count_finished() >=
toInt(RegionIndex::DetectorRegionIndexMax)) {
249 ATH_MSG_VERBOSE(
"The MS is filled up with Hough seeds. We do not need to search for them any longer");
254 for (
auto& theta_pair : output_cache.
eta_seeds) {
std::sort(theta_pair.second.begin(), theta_pair.second.end()); }
257 return StatusCode::SUCCESS;
261 if (!segmentContainer.
isValid()) {
263 return StatusCode::FAILURE;
265 for (
const Trk::Segment* trk_segment : *segmentContainer) {
269 ATH_MSG_WARNING(
"How can it be that a Muon segment is not a muon segment?");
281 const Identifier meas_id = m_edmHelperSvc->getIdentifier(*meas);
282 return meas_id.is_valid() && (m_idHelperSvc->isMM(meas_id) || m_idHelperSvc->issTgc(meas_id));
286 maskHits(muon_segment, output_cache);
290 return StatusCode::SUCCESS;
295 const double ThetaID = ms_entry->
position().theta();
296 std::vector<int> id_sectors;
298 auto sector_match = [&id_sectors,
this](
const Amg::Vector3D& seg_pos) ->
bool {
299 std::vector<int> seg_sectors;
301 return std::find_if(id_sectors.begin(), id_sectors.end(), [&seg_sectors](
const int id_sec) {
302 return std::find(seg_sectors.begin(), seg_sectors.end(), id_sec) != seg_sectors.end();
303 }) != id_sectors.end();
307 const double dTheta = pos.theta() - ThetaID;
308 const bool theta_match = std::abs(
dTheta) < 0.2;
313 if (!sector_match(pos)) {
324 const double etaID = ms_entry->
position().eta();
325 std::vector<int> id_sectors;
327 for (
const int& sect : id_sectors) {
329 if (theta_itr == cache.
eta_seeds.end())
continue;
330 if (std::find_if(theta_itr->second.begin(), theta_itr->second.end(),
331 [&etaID](
const double eta_seed) { return std::abs(etaID - eta_seed) < 0.1; }) != theta_itr->second.end())
340 ATH_MSG_VERBOSE(
"No candidates for stau reconstruction will be written");
341 return StatusCode::SUCCESS;
343 ATH_MSG_DEBUG(
"Now find the candidates to be considered for MuGirlStau");
356 cache.
candidate = std::make_unique<MuonCombined::InDetCandidate>(idMuidCo.id_trk->indetTrackParticleLink());
364 ATH_MSG_DEBUG(
"Could not determine the intersections. Although that should be possible");
373 return a->indetTrackParticle().pt() < b->indetTrackParticle().pt();});
375 return StatusCode::SUCCESS;
381 const RegionIndex region_index =
m_idHelperSvc->regionIndex(seg_id);
383 std::set<Identifier>& id_set = output_cache.
consumed_hits[hash];
386 id_set.insert(meas_id);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
DataVector adapter that acts like it holds const pointers.
DataVector< MuonCombined::InDetCandidate > InDetCandidateCollection
This typedef represents a collection of InDetCandidate objects.
DataModel_detail::const_iterator< DataVector > const_iterator
size_type size() const noexcept
Returns the number of elements in the collection.
TagBase implementation for a combined fit.
std::vector< const Muon::MuonSegment * > associatedSegments() const override
access to associated segments, empty vector if non available
void setExtension(std::unique_ptr< Muon::MuonSystemExtension > extension)
bool isSiliconAssociated() const
Returns true if this candidate was formed from a special far forward InDet track.
const Trk::CaloExtension * getCaloExtension() const
const xAOD::TrackParticle & indetTrackParticle() const
access TrackParticle
void setSiliconAssociated(bool)
Pass true if this candiate was created from a special far forward InDet track.
const Muon::MuonSystemExtension * getExtension() const
std::string toString() const
print candidate to string
const ElementLink< xAOD::TrackParticleContainer > & indetTrackParticleLink() const
access TrackParticleLink
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
StatusCode create(const EventContext &ctx, InDetCandidateCache &cache) const
Create the InDetCandidaes with system extensions.
SG::ReadHandleKey< Trk::SegmentCollection > m_segmentKey
Let's exploit the segments to get rid of as much tracks as possible.
SG::ReadHandleKey< MuonCombined::InDetCandidateToTagMap > m_combTagMap
That is the collection of MuidCo candidates.
StatusCode findSegments(const EventContext &ctx, InDetCandidateCache &output_cache) const
Select good segments.
StatusCode findHitSectors(const EventContext &ctx, InDetCandidateCache &output_cache) const
Find the sectors in the MS with muon signals.
Gaudi::Property< bool > m_extendSAF
Shall SAF tracks be equiped with a muon system extension used by MuGirl later.
const Muon::MuonSectorMapping m_sector_mapping
StatusCode selectCandidates(const EventContext &ctx, InDetCandidateCache &cache) const
Select the MuidCo candidates and put the associated id tracks on a block list.
bool hasMatchingSeed(const MuonCombined::InDetCandidate &id_cand, const InDetCandidateCache &cache) const
Searches for hough seeds within theta < 0.2 && sharing the same sector.
bool hasMatchingSegment(const MuonCombined::InDetCandidate &id_cand, const InDetCandidateCache &cache) const
Searches for segments within theta < 0.2 && sharing the same sector.
PublicToolHandle< Muon::IMuonSegmentSelectionTool > m_segmentSelector
StatusCode execute(const EventContext &ctx) const override
ToolHandle< Muon::IMuonSystemExtensionTool > m_muonSystemExtensionTool
The system extension tool extrapolates the candidate through the spectrometer.
StatusCode createStaus(const EventContext &ctx, const InDetCandidateCollection *ext_candidates, const MuidCoVector &tag_map) const
std::vector< MuidCoCache > MuidCoVector
void maskHits(const Muon::MuonSegment *muon_seg, InDetCandidateCache &output_cache) const
Mask the hits of the corresponding muon segment as used.
Gaudi::Property< bool > m_restrictExtension
Restrict the extrapolation of ID tracks to sectors in the MS where at least a hit is recorded.
SG::ReadHandleKey< InDetCandidateCollection > m_inputCandidate
Gaudi::Property< int > m_houghMin
The hough maxima always contain at least 2 hits.
SG::WriteHandleKey< InDetCandidateCollection > m_bulkInDetCandKey
Collection of InDet candidates written for MuGirl and MuonSegmentTag.
SG::WriteHandleKey< InDetCandidateCollection > m_stauInDetCandKey
Collection of InDet candidates written for MuGirlStau.
ServiceHandle< Muon::IMuonEDMHelperSvc > m_edmHelperSvc
StatusCode initialize() override
Gaudi::Property< int > m_segmentQuality
Gaudi::Property< bool > m_extendBulk
Shall ordinary ID tracks be equiped with a muon system extension used by MuGirl later.
Gaudi::Property< bool > m_excludeNSW
Prelimnary studies have shown that the NSWs generate a massive amount of fake candidates.
Gaudi::Property< float > m_extThreshold
Minimum pt threshold of the IdCandidate to be extrapolated through the spectrometer.
SG::ReadHandleKey< Muon::HoughDataPerSectorVec > m_houghDataPerSectorVecKey
Use the hough data to find sectors in the speectrometer traversed by a muon.
This is the common class for 3D segments used in the muon spectrometer.
virtual const Amg::Vector3D & globalPosition() const override final
global position
Tracking class to hold the extrapolation from a particle from the calo entry to the end of muon syste...
const Trk::TrackParameters & muonEntryLayerIntersection() const
access to intersection with the muon entry layer
const std::vector< Intersection > & layerIntersections() const
access to the intersections with the layers.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const DataObjID & fullKey() const
Return the key as a DataObjID.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
const TrackParameters * muonEntryLayerIntersection() const
access to intersection with the muon entry layer return nullptr if the intersection failed
This class is the pure abstract base class for all fittable tracking measurements.
const Amg::Vector3D & position() const
Access method for the position.
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Identifier identify() const
return the identifier
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
virtual const Amg::Vector3D & center() const =0
Return the center of the element.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Eigen::Matrix< double, 3, 1 > Vector3D
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
DetectorRegionIndex
enum to classify the different layers in the muon spectrometer
constexpr int toInt(const EnumType enumVal)
unsigned int sectorLayerHash(DetectorRegionIndex detectorRegionIndex, LayerIndex layerIndex)
create a hash out of region and layer
const std::string & regionName(DetectorRegionIndex index)
convert DetectorRegionIndex into a string
LayerIndex
enum to classify the different layers in the muon spectrometer
ParametersBase< TrackParametersDim, Charged > TrackParameters
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
std::unique_ptr< InDetCandidateCollection > outputContainer
Output container for the StoreGate.
const InDetCandidateCollection * input_candidates
Collection of the InDet candidates to consider.
std::set< const MuonCombined::InDetCandidate * > excluded_trks
Inner detector tracks to exclude.
std::map< Muon::MuonStationIndex::DetectorRegionIndex, std::set< int > > hit_sectors
Hit sector map.
std::vector< const Muon::MuonSegment * > candidate_segments
Muon segments that could be potentially used for MuGirl / MuTagIMO.
std::map< int, std::vector< double > > eta_seeds
std::map< unsigned int, std::set< Identifier > > consumed_hits
Map of hits that were successfully combined to a muon segment Key is the hash made out of region & la...
MuidCoVector tag_map
Combined fit tag map.
std::set< const Muon::MuonSegment * > combined_segs
List of segments that were successfully combined to a muon.
Helper struct to cache the MuidCo track and it's associated segments while keeping the association In...
std::vector< std::shared_ptr< MuonHough::MuonLayerHough::Maximum > > MaximumVec