Loading [MathJax]/jax/output/SVG/config.js
 |
ATLAS Offline Software
|
#include <MuonNSWSegmentFinderTool.h>
|
| MuonNSWSegmentFinderTool (const std::string &type, const std::string &name, const IInterface *parent) |
| default constructor More...
|
|
virtual | ~MuonNSWSegmentFinderTool ()=default |
| destructor More...
|
|
virtual StatusCode | initialize () override |
|
void | find (const EventContext &ctx, SegmentMakingCache &cache) const override |
|
int | wedgeNumber (const Muon::MuonClusterOnTrack *cluster) const |
|
int | layerNumber (const Muon::MuonClusterOnTrack *cluster) const |
|
int | channel (const Muon::MuonClusterOnTrack *cluster) const |
| Returns the channel of the measurement on the layer. More...
|
|
const IMuonIdHelperSvc * | idHelper () const |
|
bool | isPad (const Muon::MuonClusterOnTrack *clust) const |
|
bool | isStrip (const Muon::MuonClusterOnTrack *clust) const |
|
bool | isWire (const Muon::MuonClusterOnTrack *clust) const |
|
template<size_t N> |
std::string | printSeed (const std::array< SeedMeasurement, N > &seed) const |
|
std::string | print (const SeedMeasurement &meas) const |
|
std::string | print (const MeasVec &clusters) const |
|
std::string | print (const LayerMeasVec &sortedVec) const |
|
ServiceHandle< StoreGateSvc > & | evtStore () |
| The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc . More...
|
|
const ServiceHandle< StoreGateSvc > & | evtStore () const |
| The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc . More...
|
|
const ServiceHandle< StoreGateSvc > & | detStore () const |
| The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc . More...
|
|
virtual StatusCode | sysInitialize () override |
| Perform system initialization for an algorithm. More...
|
|
virtual StatusCode | sysStart () override |
| Handle START transition. More...
|
|
virtual std::vector< Gaudi::DataHandle * > | inputHandles () const override |
| Return this algorithm's input handles. More...
|
|
virtual std::vector< Gaudi::DataHandle * > | outputHandles () const override |
| Return this algorithm's output handles. More...
|
|
Gaudi::Details::PropertyBase & | declareProperty (Gaudi::Property< T > &t) |
|
Gaudi::Details::PropertyBase * | declareProperty (const std::string &name, SG::VarHandleKey &hndl, const std::string &doc, const SG::VarHandleKeyType &) |
| Declare a new Gaudi property. More...
|
|
Gaudi::Details::PropertyBase * | declareProperty (const std::string &name, SG::VarHandleBase &hndl, const std::string &doc, const SG::VarHandleType &) |
| Declare a new Gaudi property. More...
|
|
Gaudi::Details::PropertyBase * | declareProperty (const std::string &name, SG::VarHandleKeyArray &hndArr, const std::string &doc, const SG::VarHandleKeyArrayType &) |
|
Gaudi::Details::PropertyBase * | declareProperty (const std::string &name, T &property, const std::string &doc, const SG::NotHandleType &) |
| Declare a new Gaudi property. More...
|
|
Gaudi::Details::PropertyBase * | declareProperty (const std::string &name, T &property, const std::string &doc="none") |
| Declare a new Gaudi property. More...
|
|
void | updateVHKA (Gaudi::Details::PropertyBase &) |
|
MsgStream & | msg () const |
|
MsgStream & | msg (const MSG::Level lvl) const |
|
bool | msgLvl (const MSG::Level lvl) const |
|
|
std::vector< std::unique_ptr< Muon::MuonSegment > > | findStereoSegments (const EventContext &ctx, const std::vector< const Muon::MuonClusterOnTrack * > &allClusts, int singleWedge=0) const |
| Runs the NSW segment maker by combining 4 Micromega layers to a stereo seed. More...
|
|
std::vector< std::unique_ptr< Muon::MuonSegment > > | findStgcPrecisionSegments (const EventContext &ctx, const std::vector< const Muon::MuonClusterOnTrack * > &MuonClusters, int singleWedge=0) const |
| Combines 2 sTgc strip layers to find 2D segments constraining the muon in the eta direction. More...
|
|
std::vector< std::unique_ptr< Muon::MuonSegment > > | find3DSegments (const EventContext &ctx, const std::vector< const Muon::MuonClusterOnTrack * > &MuonClusters, std::vector< std::unique_ptr< Muon::MuonSegment >> &etaSegs, int singleWedge=0) const |
|
MeasVec | cleanClusters (const std::vector< const Muon::MuonClusterOnTrack * > &MuonClusters, int hit_sel, int singleWedge) const |
|
LayerMeasVec | classifyByLayer (const MeasVec &clusters, int hit_sel) const |
|
std::vector< NSWSeed > | segmentSeedFromStgc (const LayerMeasVec &orderedClusters, bool usePhi) const |
|
std::vector< NSWSeed > | segmentSeedFromMM (const LayerMeasVec &orderedClusters) const |
|
std::vector< NSWSeed > | segmentSeedFromMM (const LayerMeasVec &orderedClusters, std::array< unsigned int, 4 > selLayers, unsigned int &trial_counter) const |
|
std::vector< NSWSeed > | segmentSeedFromPads (const LayerMeasVec &orderedClusters, const Muon::MuonSegment &etaSeg) const |
|
std::vector< std::pair< double, double > > | getPadPhiOverlap (const std::vector< std::vector< const Muon::sTgcPrepData * >> &pads) const |
|
int | getClustersOnSegment (const LayerMeasVec &orderedclusters, NSWSeed &seed, const std::set< unsigned int > &exclude, bool useStereo=true) const |
|
MeasVec | getCalibratedClusters (NSWSeed &seed) const |
|
bool | hitsToTrack (const EventContext &ctx, const MeasVec &etaHitVec, const MeasVec &phiHitVec, const Trk::TrackParameters &startpar, TrackCollection &segTrkColl) const |
|
std::unique_ptr< Trk::PseudoMeasurementOnTrack > | ipConstraint (const EventContext &ctx) const |
| creates the IP constraint More...
|
|
std::unique_ptr< Trk::PseudoMeasurementOnTrack > | caloConstraint (const Trk::TrackParameters &startpar) const |
|
std::vector< NSWSeed > | resolveAmbiguities (std::vector< NSWSeed > &&unresolved) const |
|
std::vector< std::unique_ptr< Muon::MuonSegment > > | resolveAmbiguities (const EventContext &ctx, const TrackCollection &segColl, const Trk::Segment::Author a) const |
|
std::unique_ptr< Trk::Track > | fit (const EventContext &ctx, const std::vector< const Trk::MeasurementBase * > &fit_meas, const Trk::TrackParameters &perigee) const |
|
ChannelConstraint | compatiblyFromIP (const SeedMeasurement &meas1, const SeedMeasurement &meas2) const |
| Checks whether the two measurements are compatible within the IP constraint
More...
|
|
std::pair< double, double > | coveredRadii (const SeedMeasurement &meas) const |
| Returns the minimal & maximal radial distance of a measurement. More...
|
|
MeasVec | vetoBursts (MeasVec &&clustInLay) const |
| Removes clusters from high activity areas in the detector. More...
|
|
Gaudi::Details::PropertyBase & | declareGaudiProperty (Gaudi::Property< T > &hndl, const SG::VarHandleKeyType &) |
| specialization for handling Gaudi::Property<SG::VarHandleKey> More...
|
|
Gaudi::Details::PropertyBase & | declareGaudiProperty (Gaudi::Property< T > &hndl, const SG::VarHandleKeyArrayType &) |
| specialization for handling Gaudi::Property<SG::VarHandleKeyArray> More...
|
|
Gaudi::Details::PropertyBase & | declareGaudiProperty (Gaudi::Property< T > &hndl, const SG::VarHandleType &) |
| specialization for handling Gaudi::Property<SG::VarHandleBase> More...
|
|
Gaudi::Details::PropertyBase & | declareGaudiProperty (Gaudi::Property< T > &t, const SG::NotHandleType &) |
| specialization for handling everything that's not a Gaudi::Property<SG::VarHandleKey> or a <SG::VarHandleKeyArray> More...
|
|
|
ServiceHandle< IMuonIdHelperSvc > | m_idHelperSvc |
|
ServiceHandle< IMuonEDMHelperSvc > | m_edmHelperSvc |
|
ToolHandle< Trk::ITrackAmbiguityProcessorTool > | m_ambiTool |
| Tool for ambiguity solving. More...
|
|
ToolHandle< Trk::ITrackFitter > | m_slTrackFitter |
|
ToolHandle< IMuonTrackToSegmentTool > | m_trackToSegmentTool |
|
PublicToolHandle< MuonEDMPrinterTool > | m_printer |
|
ToolHandle< IMuonTrackCleaner > | m_trackCleaner |
|
ToolHandle< Trk::ITrackSummaryTool > | m_trackSummary |
|
ToolHandle< IMuonClusterOnTrackCreator > | m_muonClusterCreator {this, "MuonClusterCreator", ""} |
|
Gaudi::Property< bool > | m_ipConstraint {this, "IPConstraint", true} |
|
Gaudi::Property< bool > | m_caloConstraint {this, "CaloConstraint", false} |
| Use a virtual point at the calorimeter exit with same Z as constraint... More...
|
|
Gaudi::Property< double > | m_maxClustDist {this, "ClusterDistance", 5.} |
|
Gaudi::Property< int > | m_nOfSeedLayers {this, "NOfSeedLayers", 1} |
|
Gaudi::Property< bool > | m_useStereoSeeding {this, "SeedMMStereos", true} |
|
Gaudi::Property< bool > | m_usesTGCSeeding {this, "SeedWithsTGCS", true} |
|
Gaudi::Property< unsigned int > | m_ocupMmBinWidth |
| Protection against slobbering Micromega events. More...
|
|
Gaudi::Property< unsigned int > | m_ocupMmNumPerBin |
|
Gaudi::Property< unsigned int > | m_ocupMmNumPerPair |
|
StoreGateSvc_t | m_evtStore |
| Pointer to StoreGate (event store by default) More...
|
|
StoreGateSvc_t | m_detStore |
| Pointer to StoreGate (detector store by default) More...
|
|
std::vector< SG::VarHandleKeyArray * > | m_vhka |
|
bool | m_varHandleArraysDeclared |
|
Definition at line 126 of file MuonNSWSegmentFinderTool.h.
◆ LayerMeasVec
◆ MeasVec
◆ MuonClusterPtr
◆ MuonClusterVec
◆ SeedMeasurement
◆ StoreGateSvc_t
◆ ChannelConstraint
◆ HitType
◆ MuonNSWSegmentFinderTool()
Muon::MuonNSWSegmentFinderTool::MuonNSWSegmentFinderTool |
( |
const std::string & |
type, |
|
|
const std::string & |
name, |
|
|
const IInterface * |
parent |
|
) |
| |
◆ ~MuonNSWSegmentFinderTool()
virtual Muon::MuonNSWSegmentFinderTool::~MuonNSWSegmentFinderTool |
( |
| ) |
|
|
virtualdefault |
◆ caloConstraint()
◆ channel()
◆ classifyByLayer()
Definition at line 806 of file MuonNSWSegmentFinderTool.cxx.
813 std::array<std::set<Identifier>,16> used_hits{};
823 const int channelType =
m_idHelperSvc->stgcIdHelper().channelType(
id);
828 std::set<Identifier>& lay_hits = used_hits[iorder];
829 if (lay_hits.count(
id))
continue;
831 orderedClusters[iorder].emplace_back(hit);
833 if (
nBad)
ATH_MSG_WARNING(
"Unable to classify " <<
nBad <<
" clusters by their layer since they are neither MM nor sTGC");
836 orderedClusters.erase(std::remove_if(orderedClusters.begin(), orderedClusters.end(),
837 [](
const MeasVec&
vec) { return vec.empty(); }),
838 orderedClusters.end());
841 for(
MeasVec& lays: orderedClusters){
843 return channel(a) < channel(b);
851 return orderedClusters;
◆ cleanClusters()
◆ compatiblyFromIP()
Checks whether the two measurements are compatible within the IP constraint
direction of final segment is well compatible with the IP cut
Use the Identity that 1./sinh(eta) = tan(theta) https://www.wolframalpha.com/input?i=1.%2Fsinh%28-ln%28tan%28x%2F2%29%29%29+-+tan%28x%29 Add another 0.25 as safety margin
Calculate the transverse radii at the edges of the
Definition at line 1317 of file MuonNSWSegmentFinderTool.cxx.
1322 const double dZ = std::abs(meas2->globalPosition().z()) -
1323 std::abs(meas1->globalPosition().z());
1328 static const double minTanTheta = 0.75 / std::sinh(maxEtaNSW);
1329 static const double maxTanTheta = 1.25 / std::sinh(minEtaNSW);
1331 const double minDR = minTanTheta * std::abs(dZ);
1332 const double maxDR = maxTanTheta * std::abs(dZ);
1334 const std::pair<double, double> rad1 =
coveredRadii(meas1);
1335 const std::pair<double, double> rad2 =
coveredRadii(meas2);
1337 const double dlR = rad2.first - rad1.first;
1338 const double drR = rad2.second - rad1.second;
1341 <<std::endl<<
". Separation in dR (left/right) "<<dlR<<
"/"<<drR<<
", dZ "<<dZ
1342 <<
" --> dR has to be in "<<minDR<<
" "<<maxDR);
1343 if ((std::abs(dlR) < minDR && std::abs(drR) < minDR) ||
1344 (dZ > 0 && dlR <0 && drR <0) || (dZ < 0 && dlR >0 && drR > 0)) {
1346 }
if (std::abs(dlR) > maxDR && std::abs(drR) > maxDR && dlR * drR > 0.){
◆ coveredRadii()
std::pair< double, double > Muon::MuonNSWSegmentFinderTool::coveredRadii |
( |
const SeedMeasurement & |
meas | ) |
const |
|
inlineprivate |
Returns the minimal & maximal radial distance of a measurement.
Definition at line 1351 of file MuonNSWSegmentFinderTool.cxx.
1353 const int chNum =
channel(meas);
1357 const double radLeft{meas->associatedSurface().localToGlobal(left).perp()};
1358 const double radRight{meas->associatedSurface().localToGlobal(right).perp()};
1359 return std::make_pair(radLeft, radRight);
◆ declareGaudiProperty() [1/4]
specialization for handling Gaudi::Property<SG::VarHandleKeyArray>
Definition at line 170 of file AthCommonDataStore.h.
175 hndl.documentation());
◆ declareGaudiProperty() [2/4]
specialization for handling Gaudi::Property<SG::VarHandleKey>
Definition at line 156 of file AthCommonDataStore.h.
161 hndl.documentation());
◆ declareGaudiProperty() [3/4]
specialization for handling Gaudi::Property<SG::VarHandleBase>
Definition at line 184 of file AthCommonDataStore.h.
189 hndl.documentation());
◆ declareGaudiProperty() [4/4]
◆ declareProperty() [1/6]
Declare a new Gaudi property.
- Parameters
-
name | Name of the property. |
hndl | Object holding the property value. |
doc | Documentation string for the property. |
This is the version for types that derive from SG::VarHandleBase
. The property value object is put on the input and output lists as appropriate; then we forward to the base class.
Definition at line 245 of file AthCommonDataStore.h.
250 this->declare(hndl.
vhKey());
251 hndl.
vhKey().setOwner(
this);
253 return PBASE::declareProperty(
name,hndl,
doc);
◆ declareProperty() [2/6]
Declare a new Gaudi property.
- Parameters
-
name | Name of the property. |
hndl | Object holding the property value. |
doc | Documentation string for the property. |
This is the version for types that derive from SG::VarHandleKey
. The property value object is put on the input and output lists as appropriate; then we forward to the base class.
Definition at line 221 of file AthCommonDataStore.h.
229 return PBASE::declareProperty(
name,hndl,
doc);
◆ declareProperty() [3/6]
◆ declareProperty() [4/6]
Declare a new Gaudi property.
- Parameters
-
name | Name of the property. |
property | Object holding the property value. |
doc | Documentation string for the property. |
This is the generic version, for types that do not derive from SG::VarHandleKey
. It just forwards to the base class version of declareProperty
.
Definition at line 333 of file AthCommonDataStore.h.
338 return PBASE::declareProperty(
name, property,
doc);
◆ declareProperty() [5/6]
Declare a new Gaudi property.
- Parameters
-
name | Name of the property. |
property | Object holding the property value. |
doc | Documentation string for the property. |
This dispatches to either the generic declareProperty
or the one for VarHandle/Key/KeyArray.
Definition at line 352 of file AthCommonDataStore.h.
◆ declareProperty() [6/6]
◆ detStore()
◆ evtStore() [1/2]
◆ evtStore() [2/2]
◆ extraDeps_update_handler()
Add StoreName to extra input/output deps as needed.
use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given
◆ find()
Remove all stereo segment hits from further processing
All segments
Single wedge segments. Important for the alignment runs
Loop over the 4 quads to create the segment container
The micromegas need 4 hits on track
Create the perigee parameter
Create the segment
Implements Muon::IMuonNSWSegmentFinderTool.
Definition at line 283 of file MuonNSWSegmentFinderTool.cxx.
285 std::vector<const Muon::MuonClusterOnTrack*> muonClusters{};
286 muonClusters.reserve(cache.inputClust.size());
287 std::transform(cache.inputClust.begin(), cache.inputClust.end(), std::back_inserter(muonClusters),
288 [](
const std::unique_ptr<const MuonClusterOnTrack>&
cl){return cl.get();});
289 ATH_MSG_DEBUG(
"Entering MuonNSWSegmentFinderTool with " << muonClusters.size() <<
" clusters to be fit");
291 MuonSegmentVec out_segments{};
294 ATH_MSG_VERBOSE(
"Found " << stereoSegs.size() <<
" MMG stereo seeded segments");
295 out_segments.insert(out_segments.end(), std::make_move_iterator(stereoSegs.begin()),
296 std::make_move_iterator(stereoSegs.end()));
299 auto dump_output = [&]() {
300 cache.constructedSegs.reserve(cache.constructedSegs.size() + out_segments.size());
301 for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
304 if (clus) cache.usedHits.insert(clus->
identify());
306 cache.constructedSegs.push_back(std::move(seg));
310 std::vector<const Muon::MuonClusterOnTrack*> clustPostStereo{};
312 std::array<std::set<Identifier>, 16> masked_segs{};
313 for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
320 if (!out_segments.empty()) {
321 clustPostStereo.reserve(muonClusters.size());
326 const std::vector<const Muon::MuonClusterOnTrack*>& segmentInput = !out_segments.empty() ? clustPostStereo : muonClusters;
331 ATH_MSG_VERBOSE(
"Found " << etaSegs.size() <<
" stgc seeded eta segments");
332 MuonSegmentVec precSegs =
find3DSegments(ctx, segmentInput, etaSegs);
334 out_segments.insert(out_segments.end(),
335 std::make_move_iterator(precSegs.begin()),
336 std::make_move_iterator(precSegs.end()));
341 if (!cache.buildQuads) {
346 for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
347 std::vector<const MuonClusterOnTrack*> seg_hits{};
348 seg_hits.reserve(seg->containedMeasurements().size());
351 if (clus) seg_hits.push_back(clus);
354 for (
int iWedge{1}; iWedge<=4 ; ++iWedge) {
357 if ( quad_hits.size () < 2 || ((iWedge == 2 || iWedge == 3) && quad_hits.size() < 4))
continue;
358 std::vector<const Trk::MeasurementBase*> fit_meas{};
359 std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{
ipConstraint(ctx)};
360 if (pseudoVtx) fit_meas.push_back(pseudoVtx.get());
361 std::copy(quad_hits.begin(), quad_hits.end(), std::back_inserter(fit_meas));
363 const Trk::Surface& surf = quad_hits.front()->associatedSurface();
368 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
371 std::unique_ptr<Trk::Track> segtrack =
fit(ctx, fit_meas, startpar);
372 if (!segtrack)
continue;
377 <<
"position: "<<
to_string(seg->globalPosition())<< std::endl
378 <<
"direction: "<<
to_string(seg->globalDirection())<< std::endl
379 <<
m_printer->print(seg->containedMeasurements()));
381 cache.quadSegs.emplace_back(std::move(seg));
◆ find3DSegments()
1 - All micromega layers have ideally been consumed. Try the seeding from the phi wires.
Definition at line 575 of file MuonNSWSegmentFinderTool.cxx.
579 MuonSegmentVec segments{};
582 ATH_MSG_DEBUG(
"Cleaning phi clusters in stgc seeded 3D segments ");
584 ATH_MSG_DEBUG(
"After hit cleaning, there are " << phiClusters.size() <<
" phi clusters to be fit");
590 if (orderedWireClusters.size() + orderedPadClusters.size() < 2) {
591 ATH_MSG_DEBUG(
"Not enough phi hits present, cannot perform the 3D fit!");
592 segments.insert(segments.end(), std::make_move_iterator(etaSegs.begin()), std::make_move_iterator(etaSegs.end()));
597 ATH_MSG_DEBUG(
"Cleaning eta clusters in stgc seeded 3D segments ");
602 bool triedWireSeed{
false};
603 std::vector<NSWSeed> seeds_WiresSTGC;
606 for (std::unique_ptr<Muon::MuonSegment>& etaSeg : etaSegs) {
608 NSWSeed seed2D{
this, *etaSeg};
611 std::vector<NSWSeed> seeds;
614 if (std::abs(etaSeg->globalPosition().eta()) < 2.4) {
615 if (!triedWireSeed) {
617 triedWireSeed =
true;
621 if (!seeds_WiresSTGC.empty()) {
622 seeds = seeds_WiresSTGC;
636 double etaSegLocX = etaSeg->localParameters()[
Trk::locX];
637 double etaSegLocXZ = etaSeg->localDirection().angleXZ();
639 for (NSWSeed& seed : seeds) {
657 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
658 const Trk::Perigee startpar{perpos, gdir_seg, 0, perpos};
660 NSWSeed seed3D{
this, perpos, gdir_seg};
665 if (nPhiHits < 2)
continue;
667 MeasVec phiHitVec = seed3D.measurements();
672 if (
hitsToTrack(ctx, etaHitsCalibrated, phiHitVec, startpar, segTrkColl)) {
674 ATH_MSG_VERBOSE(
"Segment successfully fitted for wedge "<<singleWedge<<std::endl<<
681 if (!is3Dseg) { segments.push_back(std::move(etaSeg)); }
684 segments.insert(segments.end(), std::make_move_iterator(new_segs.begin()), std::make_move_iterator(new_segs.end()));
◆ findStereoSegments()
Runs the NSW segment maker by combining 4 Micromega layers to a stereo seed.
Subsequentally, the hits on the hit road are added to the seeed and the segment is fitted
- Parameters
-
ctx | EventContext |
allClusts | Collection of all EventContext objects |
singleWedge | 0 (use all 4 multiplets) 2/3 |
- Returns
Order any parsed hit into the layer structure
Loop over the seeds
Require that the seed has at least one extra hit, if we're not restricting ourselves to a single wedge
Craete the perigee parameter
Create the segment
Definition at line 387 of file MuonNSWSegmentFinderTool.cxx.
401 for (
MeasVec& hitsInLayer : orderedClust) hitsInLayer =
vetoBursts(std::move(hitsInLayer));
402 orderedClust.erase(std::remove_if(orderedClust.begin(), orderedClust.end(),
403 [](
const MeasVec&
vec) { return vec.empty(); }),
405 if (orderedClust.empty())
return {};
409 ATH_MSG_VERBOSE(
"Retrieved " << seeds.size() <<
" seeds in the MMStereoAlg after the ambiguity resolution" );
411 if (seeds.empty())
return {};
414 for (NSWSeed& seed : seeds) {
417 std::vector<const Trk::MeasurementBase*> fit_meas{};
419 std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{
ipConstraint(ctx)};
420 if (pseudoVtx) fit_meas.push_back(pseudoVtx.get());
422 std::copy(calib_clust.begin(), calib_clust.end(), std::back_inserter(fit_meas));
424 const Trk::Surface& surf = calib_clust.front()->associatedSurface();
430 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
435 std::unique_ptr<Trk::Track> segtrack =
fit(ctx, fit_meas, startpar);
436 if (segtrack) trackSegs.push_back(std::move(segtrack));
◆ findStgcPrecisionSegments()
MuonSegmentVec Muon::MuonNSWSegmentFinderTool::findStgcPrecisionSegments |
( |
const EventContext & |
ctx, |
|
|
const std::vector< const Muon::MuonClusterOnTrack * > & |
MuonClusters, |
|
|
int |
singleWedge = 0 |
|
) |
| const |
|
private |
Combines 2 sTgc strip layers to find 2D segments constraining the muon in the eta direction.
Resolve the ambiguities amongsty the tracks and convert the result
Definition at line 472 of file MuonNSWSegmentFinderTool.cxx.
487 ATH_MSG_DEBUG(
"Cleaning eta clusters in stgc seeded 2D segments ");
494 if (orderedClusters.size() < 4)
return {};
503 for (NSWSeed& seed : seeds) {
504 if (
seed.size() < 4){
505 ATH_MSG_VERBOSE(__func__<<
" :"<<__LINE__<<
" - Seed size: " <<
seed.size() <<
" is below the cut (4)");
509 etaHitVec =
seed.measurements();
527 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
528 const auto startpar =
Trk::Perigee(perpos, gdir_seg, 0, perpos);
529 ATH_MSG_VERBOSE(
" start parameter " << perpos <<
" pp " << startpar.position() <<
" gd " << gdir_seg.unit() <<
" pp "
530 << startpar.momentum().unit());
533 hitsToTrack(ctx, etaHitVec, phiHitVec, startpar, segTrkColl);
◆ fit()
◆ getCalibratedClusters()
MeasVec Muon::MuonNSWSegmentFinderTool::getCalibratedClusters |
( |
NSWSeed & |
seed | ) |
const |
|
private |
Definition at line 1487 of file MuonNSWSegmentFinderTool.cxx.
1494 std::unique_ptr<const Muon::MuonClusterOnTrack> newClus;
1504 calibratedClusters.emplace_back(
seed.newCalibClust(std::move(newClus)));
1508 calibratedClusters.emplace_back(
seed.newCalibClust(std::move(newClus)));
1512 return calibratedClusters;
◆ getClustersOnSegment()
int Muon::MuonNSWSegmentFinderTool::getClustersOnSegment |
( |
const LayerMeasVec & |
orderedclusters, |
|
|
NSWSeed & |
seed, |
|
|
const std::set< unsigned int > & |
exclude, |
|
|
bool |
useStereo = true |
|
) |
| const |
|
private |
◆ getPadPhiOverlap()
std::vector< std::pair< double, double > > Muon::MuonNSWSegmentFinderTool::getPadPhiOverlap |
( |
const std::vector< std::vector< const Muon::sTgcPrepData * >> & |
pads | ) |
const |
|
private |
Definition at line 1387 of file MuonNSWSegmentFinderTool.cxx.
1393 std::vector<std::vector<double>> padsPhiL, padsPhiR;
1394 std::vector<double> padsPhiC;
1397 for (
const std::vector<const Muon::sTgcPrepData*>& surfHits : pads) {
1399 std::vector<double> surfPadsPhiL, surfPadsPhiR;
1409 const double halfWidthX = 0.5 * design->
channelWidth(prd->localPosition(),
true);
1410 const double hitPadX = prd->localPosition().x();
1414 bool samePhi = std::find_if(padsPhiC.begin(), padsPhiC.end(), [&hitPadX, &halfWidthX](
const double prevPadPhi) {
1415 return std::abs(hitPadX - prevPadPhi) < 0.9 * halfWidthX;
1416 }) != padsPhiC.end();
1418 if (samePhi)
continue;
1421 surfPadsPhiL.push_back(hitPadX - halfWidthX);
1422 surfPadsPhiR.push_back(hitPadX + halfWidthX);
1423 padsPhiC.push_back(hitPadX);
1427 padsPhiL.push_back(std::move(surfPadsPhiL));
1428 padsPhiR.push_back(std::move(surfPadsPhiR));
1431 unsigned int nSurf = padsPhiR.size();
1435 unsigned int nCombos{1};
1436 for (
const std::vector<double>& surfPadsPhiR : padsPhiR) {
1437 if (!surfPadsPhiR.empty()) nCombos *= surfPadsPhiR.size();
1440 std::vector<std::pair<double, double>> phiOverlap;
1441 phiOverlap.reserve(nCombos);
1443 if (nCombos <= 100) {
1444 unsigned int N{nCombos};
1445 for (
unsigned int isurf{0}; isurf < nSurf; ++isurf) {
1446 if (padsPhiR[isurf].
empty())
continue;
1447 unsigned int nSurfHits = padsPhiR[isurf].size();
1450 for (
unsigned int icombo{0}; icombo < nCombos; ++icombo) {
1452 unsigned int padIdx = (icombo /
N) % nSurfHits;
1455 phiOverlap.emplace_back(padsPhiL[isurf][padIdx], padsPhiR[isurf][padIdx]);
1458 phiOverlap[icombo].first =
std::max(padsPhiL[isurf][padIdx], phiOverlap[icombo].
first);
1459 phiOverlap[icombo].second =
std::min(padsPhiR[isurf][padIdx], phiOverlap[icombo].
second);
1465 phiOverlap.erase(std::remove_if(phiOverlap.begin(), phiOverlap.end(),
1466 [](std::pair<double, double>&
range) { return range.first >= range.second; }),
1468 ATH_MSG_DEBUG(
"Pad seeding - #combinations initial: " << nCombos
1469 <<
", after cleaning for non overlapping pads: " << phiOverlap.size());
1473 for (
unsigned int isurf{0}; isurf < nSurf; ++isurf) {
1474 unsigned int nSurfHits = padsPhiR[isurf].size();
1475 for (
unsigned int ihit{0}; ihit < nSurfHits; ++ihit) {
1476 phiOverlap.emplace_back(padsPhiL[isurf][ihit], padsPhiR[isurf][ihit]);
1479 ATH_MSG_DEBUG(
"Pad seeding - #combinations: " << nCombos <<
" is too large. Seeding from" << phiOverlap.size()
1480 <<
" individual pads.");
◆ hitsToTrack()
Definition at line 728 of file MuonNSWSegmentFinderTool.cxx.
734 std::vector<const Trk::MeasurementBase*> vecFitPts;
735 unsigned int nHitsEta = etaHitVec.size();
736 unsigned int nHitsPhi = phiHitVec.size();
739 std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{
ipConstraint(ctx)},
741 pseudoPhi1{
nullptr}, pseudoPhi2{
nullptr};
743 if (pseudoVtx) { vecFitPts.push_back(pseudoVtx.get()); }
744 if (pseudoVtxCalo) { vecFitPts.push_back(pseudoVtxCalo.get()); }
752 cov(0, 0) = pseudoPrecision;
754 pseudoPhi1 = std::make_unique<Trk::PseudoMeasurementOnTrack>(
Trk::LocalParameters(loc_pseudopars),
756 etaHitVec.front()->associatedSurface());
757 pseudoPhi2 = std::make_unique<Trk::PseudoMeasurementOnTrack>(
Trk::LocalParameters(loc_pseudopars),
759 etaHitVec.back()->associatedSurface());
762 vecFitPts.push_back(pseudoPhi1.get());
763 std::copy(etaHitVec.begin(), etaHitVec.end(), std::back_inserter(vecFitPts));
764 vecFitPts.push_back(pseudoPhi2.get());
765 ATH_MSG_VERBOSE(
"Fitting a 2D-segment track with " << nHitsEta <<
" Eta hits");
769 std::merge(phiHitVec.begin(), phiHitVec.end(), etaHitVec.begin(), etaHitVec.end(), std::back_inserter(vecFitPts),
771 double z1 = std::abs(c1->detectorElement()->center(c1->identify()).z());
772 double z2 = std::abs(c2->detectorElement()->center(c2->identify()).z());
775 ATH_MSG_VERBOSE(
"Fitting a 3D-segment track with " << nHitsEta <<
" Eta hits and " << nHitsPhi <<
" Phi hits");
779 std::unique_ptr<Trk::Track> segtrack =
fit(ctx, vecFitPts, startpar);
780 if (!segtrack)
return false;
781 segTrkColl.
push_back(std::move(segtrack));
◆ idHelper()
◆ initialize()
StatusCode Muon::MuonNSWSegmentFinderTool::initialize |
( |
| ) |
|
|
overridevirtual |
Definition at line 262 of file MuonNSWSegmentFinderTool.cxx.
273 ATH_MSG_FATAL(
"The muon should come from the IP && horizontally from the Calo..."<<
274 "We need to place a very good basball player at the calo exit to deflect the muon horizontally.");
275 return StatusCode::FAILURE;
278 return StatusCode::SUCCESS;
◆ inputHandles()
Return this algorithm's input handles.
We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.
◆ interfaceID()
static const InterfaceID& Muon::IMuonNSWSegmentFinderTool::interfaceID |
( |
| ) |
|
|
inlinestaticinherited |
access to tool interface
Definition at line 22 of file IMuonNSWSegmentFinderTool.h.
23 static const InterfaceID IID_IMuonNSWSegmentFinderTool(
"Muon::IMuonNSWSegmentFinderTool", 1, 0);
24 return IID_IMuonNSWSegmentFinderTool;
◆ ipConstraint()
◆ isPad()
◆ isStrip()
◆ isWire()
◆ layerNumber()
◆ msg() [1/2]
◆ msg() [2/2]
◆ msgLvl()
◆ outputHandles()
Return this algorithm's output handles.
We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.
◆ print() [1/3]
std::string Muon::MuonNSWSegmentFinderTool::print |
( |
const LayerMeasVec & |
sortedVec | ) |
const |
Definition at line 1539 of file MuonNSWSegmentFinderTool.cxx.
1540 std::stringstream sstr{};
1541 unsigned int lay{0};
1542 for (
const MeasVec& clusts: sortedVec){
1543 sstr<<
"Clusters in Layer: "<<(lay+1)<<std::endl;
1544 sstr<<
"#################################################"<<std::endl;
1545 sstr<<
print(clusts);
◆ print() [2/3]
std::string Muon::MuonNSWSegmentFinderTool::print |
( |
const MeasVec & |
clusters | ) |
const |
◆ print() [3/3]
◆ printSeed()
template<size_t N>
std::string Muon::MuonNSWSegmentFinderTool::printSeed |
( |
const std::array< SeedMeasurement, N > & |
seed | ) |
const |
◆ renounce()
◆ renounceArray()
◆ resolveAmbiguities() [1/2]
Definition at line 538 of file MuonNSWSegmentFinderTool.cxx.
550 MuonSegmentVec segments{};
551 std::unique_ptr<const TrackCollection> resolvedTracks(
m_ambiTool->process(&segTrkColl));
552 ATH_MSG_DEBUG(
"Resolved track candidates: old size " << segTrkColl.size() <<
" new size " << resolvedTracks->size());
555 for (
const Trk::Track* trk : *resolvedTracks) {
556 const auto* measurements = trk->measurementsOnTrack();
557 const bool has_eta = std::find_if(measurements->begin(), measurements->end(),
559 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
560 return id.is_valid() && !m_idHelperSvc->measuresPhi(id);
561 }) != trk->measurementsOnTrack()->end();
562 if (!has_eta)
continue;
567 segments.emplace_back(std::move(seg));
◆ resolveAmbiguities() [2/2]
std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::resolveAmbiguities |
( |
std::vector< NSWSeed > && |
unresolved | ) |
const |
|
private |
Definition at line 1361 of file MuonNSWSegmentFinderTool.cxx.
1362 std::vector<NSWSeed> seeds;
1363 seeds.reserve(unresolved.size());
1364 std::sort(unresolved.begin(), unresolved.end(),[](
const NSWSeed&
a,
const NSWSeed&
b){
1365 return a.chi2() < b.chi2();
1367 for (NSWSeed& seed : unresolved) {
1368 bool add_seed{
true};
1369 for (NSWSeed&
good : seeds) {
1380 if (add_seed) seeds.push_back(std::move(seed));
1382 ATH_MSG_VERBOSE(seeds.size()<<
" out of "<<unresolved.size()<<
" passed the overlap removal");
◆ segmentSeedFromMM() [1/2]
layers 12-15 contain stgcs and are not of interest...
Combinatorics debugging stream
Definition at line 1069 of file MuonNSWSegmentFinderTool.cxx.
1071 std::vector<NSWSeed> seeds;
1072 std::array<unsigned int, 4>
layers{};
1073 unsigned int trials{0}, used_layers{0};
1075 constexpr
size_t lastMMLay = 11;
1076 std::vector<NSWSeed> laySeeds;
1079 std::stringstream sstr{};
1080 for (
int e4 =
std::min(lastMMLay, orderedClusters.size() -1);
e4 >= 3 ; --
e4) {
1082 for (
int e3 =
e4 -1 ;
e3 >= 2; --
e3) {
1088 const unsigned int old_trials = trials;
1090 if (old_trials == trials)
continue;
1092 used_layers += !laySeeds.empty();
1093 seeds.insert(seeds.end(), std::make_move_iterator(laySeeds.begin()),
1094 std::make_move_iterator(laySeeds.end()));
1097 sstr<<
" Attempts thus far "<<old_trials<<
" attempts now "<<trials<<
" --- "<<
e1<<
","<<
e2<<
","<<
e3<<
","<<
e4<<std::endl;
1099 sstr<<
"Layer: "<<lay<<
" number of measurements "<<orderedClusters[lay].size()<<std::endl;
1101 sstr<<
" **** "<<
print(meas)<<std::endl;
1103 sstr<<std::endl<<std::endl<<std::endl;
1110 if (trials > 100000) {
1113 ATH_MSG_VERBOSE(
"Out of "<<trials<<
" possible seeds, "<<seeds.size()<<
" were finally built. Used in total "<<used_layers<<
" layers");
◆ segmentSeedFromMM() [2/2]
std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::segmentSeedFromMM |
( |
const LayerMeasVec & |
orderedClusters, |
|
|
std::array< unsigned int, 4 > |
selLayers, |
|
|
unsigned int & |
trial_counter |
|
) |
| const |
|
inlineprivate |
Determine whether the layer is X(1) / U(2) or V(3)
Order the strips such that the first and second pair consist each of crossing strips
The second pair is parallel
Assign the first measurement of each layer to calculate the linear transformation
Habemus valid strip quartett
Function to calculate the muon crossing
Reserve space for 200 seeds
The two channels are too narrow. Same conclusion holds for all previous hits from this layer combined with the next ones of layer 1
The opening angle of these two channels is just too wide
The first or the second one can cross with the third one
Reject combinations that consist only of 1 strip clusters
We will revise this requirement in the near future. Keep the block for the moment
Definition at line 1120 of file MuonNSWSegmentFinderTool.cxx.
1123 std::vector<NSWSeed> seeds{};
1125 std::array<unsigned int, 4> lay_ord{};
1126 for (
size_t s = 0;
s < selLayers.size(); ++
s) {
1127 unsigned int lay = selLayers[
s];
1135 else lay_ord[
s] = 3;
1137 auto swap_strips = [&selLayers, &lay_ord] (
unsigned int i,
unsigned j){
1142 if (lay_ord[0] == lay_ord[1]){
1143 if (lay_ord[1] != lay_ord[2]) swap_strips(1,2);
1144 else if (lay_ord[1] != lay_ord[3]) swap_strips(1,3);
1151 if (lay_ord[2] == lay_ord[3]) {
1154 if (lay_ord[3] != lay_ord[0] && lay_ord[3] != lay_ord[1]) swap_strips(3,0);
1156 ATH_MSG_VERBOSE(
"No way to rearrange the strips such that the latter two strips cross.");
1161 std::array<SeedMeasurement, 4> base_seed{};
1162 for (
size_t s = 0;
s < selLayers.size(); ++
s) {
1163 unsigned int lay = selLayers[
s];
1164 base_seed[
s] = orderedClusters[lay].front();
1167 const double A = (base_seed[1].pos().z() - base_seed[0].pos().z());
1168 const double G = (base_seed[2].pos().z() - base_seed[0].pos().z());
1169 const double K = (base_seed[3].pos().z() - base_seed[0].pos().z());
1172 diamond.block<2, 1>(0, 1) = ((
A -
G) * base_seed[3].dirDot(base_seed[1]) * base_seed[1].dir() +
G * base_seed[3].dirDot(base_seed[0]) * base_seed[0].dir() -
A * base_seed[3].dir()).block<2, 1>(0, 0);
1173 diamond.block<2, 1>(0, 0) = ((K -
A) * base_seed[2].dirDot(base_seed[1]) * base_seed[1].dir() - K * base_seed[2].dirDot(base_seed[0]) * base_seed[0].dir() +
A * base_seed[2].dir()).block<2, 1>(0, 0);
1175 if (std::abs(diamond.determinant()) < std::numeric_limits<float>::epsilon()) {
1177 << diamond << std::endl
1178 <<
" is singular " << diamond.determinant() <<
" with rank "
1179 << (Eigen::FullPivLU<
AmgSymMatrix(2)>{diamond}.rank()));
1184 << diamond << std::endl
1185 <<
"May give a couple of stereo seeds " << diamond.determinant());
1194 const double TwoDotZero = base_seed[2].dirDot(base_seed[0]);
1195 const double ThreeDotZero = base_seed[3].dirDot(base_seed[0]);
1196 const double ThreeDotOne = base_seed[3].dirDot(base_seed[1]);
1197 const double TwoDotOne = base_seed[2].dirDot(base_seed[1]);
1199 auto estimate_muon = [&] () -> std::optional<std::
array<
double,2>> {
1200 const Amg::Vector3D Y0 = K * base_seed[2].pos() -
G * base_seed[3].pos() - KmG * base_seed[0].pos();
1201 const Amg::Vector3D Y1 = AmG * base_seed[3].pos() - KmG * base_seed[1].pos() + KmA * base_seed[2].pos();
1202 const double Y0dotE0 = base_seed[0].dirDot(Y0);
1203 const double Y1dotE1 = base_seed[1].dirDot(Y1);
1205 const AmgVector(2) centers = (KmG * (base_seed[0].
pos() - base_seed[1].
pos()) +
1206 Y0dotE0 * base_seed[0].
dir() +
1207 A * (base_seed[3].
pos() - base_seed[2].
pos()) -
1208 Y1dotE1 * base_seed[1].
dir())
1212 const std::
array<
double, 4> lengths{(Y0dotE0 + K * sol_pars[0] * TwoDotZero -
G * sol_pars[1] * ThreeDotZero) / KmG,
1213 (Y1dotE1 + AmG * sol_pars[1] *ThreeDotOne + KmA * sol_pars[0] * TwoDotOne) / KmG, sol_pars[0], sol_pars[1]};
1217 std::optional<Amg::Vector3D> seg_pos{std::nullopt}, seg_dir{std::nullopt};
1218 for (
unsigned int i = 0;
i < base_seed.size(); ++
i) {
1224 seg_pos = std::make_optional<Amg::Vector3D>(base_seed[0].
pos() +
1225 lengths[0] * base_seed[0].
dir());
1229 seg_dir = std::make_optional<Amg::Vector3D>((base_seed[1].
pos() +
1230 lengths[1] *base_seed[1].
dir() - (*seg_pos)).
unit());
1233 std::optional<double> mu_crossing = Amg::intersect<3>(*seg_pos, *seg_dir, base_seed[
i].
pos(),base_seed[
i].
dir());
1235 <<
" ("<< std::string( halfLength > std::abs(lengths[
i]) ?
"inside" :
"outside")<<
" wedge) "
1236 << halfLength <<
" vs. "<<std::abs(lengths[
i])<<
" crossing point: "<<std::abs(*mu_crossing));
1237 }
else if (!
accept)
return std::nullopt;
1239 if (!
accept)
return std::nullopt;
1240 return std::make_optional<std::array<double,2>>({lengths[0], lengths[1]});
1245 MeasVec::const_iterator begin2{orderedClusters[selLayers[1]].begin()};
1246 MeasVec::const_iterator begin3{orderedClusters[selLayers[2]].begin()};
1247 MeasVec::const_iterator begin4{orderedClusters[selLayers[3]].begin()};
1249 const MeasVec::const_iterator end2{orderedClusters[selLayers[1]].end()};
1250 const MeasVec::const_iterator end3{orderedClusters[selLayers[2]].end()};
1251 const MeasVec::const_iterator end4{orderedClusters[selLayers[3]].end()};
1254 base_seed[0] = lay1;
1255 for (MeasVec::const_iterator lay2 = begin2; lay2 != end2; ++lay2) {
1257 base_seed[1] = *lay2;
1270 for (MeasVec::const_iterator lay3 = begin3; lay3 != end3; ++lay3) {
1279 base_seed[2] = *lay3;
1281 for (MeasVec::const_iterator lay4 = begin4 ; lay4 != end4; ++lay4) {
1290 base_seed[3] = (*lay4);
1291 std::optional<std::array<double, 2>> isects = estimate_muon();
1293 if (!isects)
continue;
1294 NSWSeed
seed{
this, base_seed, *isects};
1296 if (
seed.size() < 4)
continue;
1298 const double eta = std::abs(
seed.dir().eta());
1299 if (eta < minEtaNSW || eta > maxEtaNSW) {
1302 if (
seed.dir().block<2,1>(0,0).dot(
seed.pos().block<2,1>(0,0)) < 0.)
continue;
1306 if (
deltaPhi > sector_mapping.sectorWidth(
m_idHelperSvc->sector(base_seed[0]->identify())))
continue;
1308 getClustersOnSegment(orderedClusters, seed, {selLayers[0], selLayers[1],selLayers[2], selLayers[3]});
1309 seeds.emplace_back(std::move(seed));
◆ segmentSeedFromPads()
Do not run an empty container
Definition at line 956 of file MuonNSWSegmentFinderTool.cxx.
958 std::vector<NSWSeed> seeds;
960 if (orderedClusters.empty())
return seeds;
962 std::vector<std::vector<const Muon::sTgcPrepData*>> sTgcIP(4);
963 std::vector<std::vector<const Muon::sTgcPrepData*>> sTgcHO(4);
966 for (
int iml : {1, 2}) {
967 int il = (iml == 1) ? 0 : orderedClusters.size() - 1;
968 int iend = (iml == 1) ? orderedClusters.size() : -1;
969 int idir = (iml == 1) ? 1 : -1;
970 unsigned int nLayersWithHitMatch{0};
973 for (;
il != iend;
il += idir) {
974 double lastDistance{1000.};
975 if (nLayersWithHitMatch >= sTgcIP.size()) {
976 sTgcIP.resize(nLayersWithHitMatch + 1);
977 sTgcHO.resize(nLayersWithHitMatch + 1);
979 std::vector<const Muon::sTgcPrepData*>& matchedHits =
980 (iml == 1) ? sTgcIP.at(nLayersWithHitMatch) : sTgcHO.at(nLayersWithHitMatch);
985 if (!padHit)
continue;
988 if (
m_idHelperSvc->stgcIdHelper().multilayer(padHit->identify()) != iml)
continue;
991 if (!design)
continue;
994 const Trk::Surface& surf = padHit->detectorElement()->surface(padHit->identify());
1002 double chWidth = design->
channelWidth(padHit->localPosition(),
false);
1003 double etaDistance = std::abs(padHit->localPosition().y() - segLocPosOnSurf[1]);
1004 if (etaDistance > 0.5 * chWidth)
continue;
1005 ATH_MSG_DEBUG(
" etaDistance " << etaDistance <<
" between pad center and position on the pad.");
1007 if (matchedHits.empty()) {
1009 matchedHits.push_back(padHit);
1011 }
else if (std::abs(etaDistance - lastDistance) < 0.001) {
1013 matchedHits.push_back(padHit);
1014 ATH_MSG_DEBUG(
" added etaDistance: " << etaDistance <<
" size " << matchedHits.size());
1015 }
else if (etaDistance < lastDistance) {
1017 matchedHits.clear();
1018 matchedHits.push_back(padHit);
1019 ATH_MSG_DEBUG(
" replacing best etaDistance with: " << etaDistance);
1023 lastDistance = etaDistance;
1026 if (!matchedHits.empty()) ++nLayersWithHitMatch;
1031 if (!nLayersWithHitMatch)
return seeds;
1036 std::vector<std::pair<double, double>> sTgcIP_phiRanges =
getPadPhiOverlap(sTgcIP);
1037 std::vector<std::pair<double, double>> sTgcHO_phiRanges =
getPadPhiOverlap(sTgcHO);
1042 const auto& surfPrdL1 = prdL1->detectorElement()->surface();
1043 const auto& surfPrdL2 = prdL2->detectorElement()->surface();
1046 for (
const std::pair<double, double>& range1 : sTgcIP_phiRanges) {
1047 double midPhi1 = 0.5 * (range1.first + range1.second);
1050 surfPrdL1.localToGlobal(lp1, gpL1, gpL1);
1052 for (
const std::pair<double, double>& range2 : sTgcHO_phiRanges) {
1053 double midPhi2 = 0.5 * (range2.first + range2.second);
1056 surfPrdL2.localToGlobal(lp2, gpL2, gpL2);
1060 seeds.emplace_back(
this, gpL1, gDir);
1064 ATH_MSG_DEBUG(
" segmentSeedFromPads: seeds.size() " << seeds.size());
◆ segmentSeedFromStgc()
std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::segmentSeedFromStgc |
( |
const LayerMeasVec & |
orderedClusters, |
|
|
bool |
usePhi |
|
) |
| const |
|
private |
Reject
Definition at line 855 of file MuonNSWSegmentFinderTool.cxx.
857 std::vector<NSWSeed> seeds;
861 if (orderedClusters.size() < 4)
return seeds;
867 int seedingLayersL{0};
868 for (
unsigned int ilayerL{0}; (ilayerL < orderedClusters.size() && seedingLayersL <
m_nOfSeedLayers); ++ilayerL) {
869 bool usedLayerL{
false};
872 if (usePhi !=
m_idHelperSvc->measuresPhi(hitL->identify()))
continue;
877 int seedingLayersR{0};
878 for (
unsigned int ilayerR = orderedClusters.size() - 1; (ilayerR > ilayerL && seedingLayersR <
m_nOfSeedLayers);
880 bool usedLayerR{
false};
882 if (usePhi !=
m_idHelperSvc->measuresPhi(hitR->identify()))
continue;
884 NSWSeed
seed{
this,hitL, hitR};
886 const double eta =
seed.dir().perp() > std::numeric_limits<float>::epsilon() ? std::abs(
seed.dir().eta()): FLT_MAX;
887 if (eta < minEtaNSW || eta > maxEtaNSW) {
894 seeds.emplace_back(std::move(seed));
897 if (usedLayerR) ++seedingLayersR;
900 if (usedLayerL) ++seedingLayersL;
◆ sysInitialize()
◆ sysStart()
Handle START transition.
We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.
◆ updateVHKA()
◆ vetoBursts()
MeasVec Muon::MuonNSWSegmentFinderTool::vetoBursts |
( |
MeasVec && |
clustInLay | ) |
const |
|
private |
Removes clusters from high activity areas in the detector.
The micromegas are slobbering quite a lot in the 2023 data taking leading to uncopable comptuing times. The burst vetoing aims to mitigate this situation. A histogram with a bin width of m_ocupMmBinWidth is defined Hits are filled into the accoring bin using their channel number Bins with large activity are then cleared. In the second step, pairs of bins where their sum is too exhaustive are removed.
Define the number of bins
Fill the measurements into the histograms
Apply the single bin cleaning
Apply the pair wise bin cleaning
Copy the rest over
Definition at line 1551 of file MuonNSWSegmentFinderTool.cxx.
1559 prunedMeas.reserve(clustInLay.size());
1560 const unsigned int firstCh =
channel(clustInLay[0]);
1561 const unsigned int lastCh =
channel(clustInLay[clustInLay.size() -1]);
1563 const unsigned int deltaCh = lastCh - firstCh;
1566 firstCh<<
", highest channel: "<<lastCh<<
" bin width: "<<
m_ocupMmBinWidth<<
" number of bins"<<
nBins);
1569 occupancyHisto.resize(
nBins);
1571 bin.reserve(clustInLay.size());
1577 occupancyHisto[
bin].push_back(std::move(meas));
1587 for (
unsigned int i = 0;
i < occupancyHisto.size() -1; ++
i) {
1589 ATH_MSG_VERBOSE(
"The two neighbouring bins "<<
i<<
"&"<<(
i+1)<<
" have too many clusters "<<std::endl<<
1590 print(occupancyHisto[
i])<<std::endl<<
print(occupancyHisto[
i+1]));
1591 occupancyHisto[
i].clear();
1592 occupancyHisto[
i+1].clear();
1598 std::make_move_iterator(
bin.end()),
1599 std::back_inserter(prunedMeas));
1602 ATH_MSG_VERBOSE(
"Number of measurements before pruning "<<clustInLay.size()<<
" number of measurments survived the pruning "<<prunedMeas.size());
◆ wedgeNumber()
◆ m_ambiTool
Initial value:{
this,
"SegmentAmbiguityTool",
"Trk::SimpleAmbiguityProcessorTool/MuonAmbiProcessor",
}
Tool for ambiguity solving.
Definition at line 148 of file MuonNSWSegmentFinderTool.h.
◆ m_caloConstraint
Gaudi::Property<bool> Muon::MuonNSWSegmentFinderTool::m_caloConstraint {this, "CaloConstraint", false} |
|
private |
◆ m_detStore
◆ m_edmHelperSvc
Initial value:{
this,
"edmHelper",
"Muon::MuonEDMHelperSvc/MuonEDMHelperSvc",
"Handle to the service providing the IMuonEDMHelperSvc interface",
}
Definition at line 141 of file MuonNSWSegmentFinderTool.h.
◆ m_evtStore
◆ m_idHelperSvc
◆ m_ipConstraint
Gaudi::Property<bool> Muon::MuonNSWSegmentFinderTool::m_ipConstraint {this, "IPConstraint", true} |
|
private |
◆ m_maxClustDist
Gaudi::Property<double> Muon::MuonNSWSegmentFinderTool::m_maxClustDist {this, "ClusterDistance", 5.} |
|
private |
◆ m_muonClusterCreator
◆ m_nOfSeedLayers
Gaudi::Property<int> Muon::MuonNSWSegmentFinderTool::m_nOfSeedLayers {this, "NOfSeedLayers", 1} |
|
private |
◆ m_ocupMmBinWidth
Gaudi::Property<unsigned int> Muon::MuonNSWSegmentFinderTool::m_ocupMmBinWidth |
|
private |
Initial value:{this, "MmOccupancyBinWidth", 100,
"Size of the channel window to group the MicroMegaCluster"}
Protection against slobbering Micromega events.
Definition at line 193 of file MuonNSWSegmentFinderTool.h.
◆ m_ocupMmNumPerBin
Gaudi::Property<unsigned int> Muon::MuonNSWSegmentFinderTool::m_ocupMmNumPerBin |
|
private |
Initial value:{this, "MmOccupancySingleCut", 5,
"Cut on the number of MicroMega clusters in a particular occupancy bin"}
Definition at line 195 of file MuonNSWSegmentFinderTool.h.
◆ m_ocupMmNumPerPair
Gaudi::Property<unsigned int> Muon::MuonNSWSegmentFinderTool::m_ocupMmNumPerPair |
|
private |
Initial value:{this, "MmOccupancyPairCut", 7,
"Cut on the number of MicroMega clusters in two neighbouring occupancy bins"}
Definition at line 197 of file MuonNSWSegmentFinderTool.h.
◆ m_printer
◆ m_slTrackFitter
◆ m_trackCleaner
◆ m_trackSummary
Initial value:{
this,
"TrackSummaryTool",
"Trk::TrackSummaryTool/MuidTrackSummaryTool",
}
Definition at line 173 of file MuonNSWSegmentFinderTool.h.
◆ m_trackToSegmentTool
Initial value:{
this,
"TrackToSegmentTool",
"Muon::MuonTrackToSegmentTool/MuonTrackToSegmentTool",
}
Definition at line 158 of file MuonNSWSegmentFinderTool.h.
◆ m_useStereoSeeding
Gaudi::Property<bool> Muon::MuonNSWSegmentFinderTool::m_useStereoSeeding {this, "SeedMMStereos", true} |
|
private |
◆ m_usesTGCSeeding
Gaudi::Property<bool> Muon::MuonNSWSegmentFinderTool::m_usesTGCSeeding {this, "SeedWithsTGCS", true} |
|
private |
◆ m_varHandleArraysDeclared
◆ m_vhka
The documentation for this class was generated from the following files:
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
void localToGlobalDirection(const Trk::LocalDirection &locdir, Amg::Vector3D &globdir) const
This method transforms a local direction wrt the plane to a global direction.
Parameters defining the design of the readout sTGC pads.
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Intersection straightLineIntersection(const T &pars, bool forceDir=false, const Trk::BoundaryCheck &bchk=false) const
fst straight line intersection schema - templated for charged and neutral parameters
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling
const Amg::Vector3D & position() const
Access method for the position.
Eigen::Matrix< double, 2, 1 > Vector2D
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
StatusCode accept(const xAOD::Muon *mu)
StoreGateSvc_t m_evtStore
Pointer to StoreGate (event store by default)
std::vector< SG::VarHandleKeyArray * > m_vhka
bool msgLvl(const MSG::Level lvl) const
std::vector< size_t > vec
std::set< std::string > exclude
list of directories to be excluded
#define ATH_MSG_VERBOSE(x)
bool const RAWDATA *ch2 const
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
double hasStereoAngle() const
returns whether the stereo angle is non-zero
#define AmgSymMatrix(dim)
std::pair< double, ParamDefs > DefinedParameter
virtual void setOwner(IDataHandleHolder *o)=0
@ OWN_ELEMENTS
this data object owns its elements
CalibratedSpacePoint::Covariance_t inverse(const CalibratedSpacePoint::Covariance_t &mat)
Inverts the parsed matrix.
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
StoreGateSvc_t m_detStore
Pointer to StoreGate (detector store by default)
represents the three-dimensional global direction with respect to a planar surface frame.
double channelWidth(const Amg::Vector2D &pos, bool measPhi, bool preciseMeas=false) const
calculate local channel width
virtual void renounce()=0
std::conditional< std::is_base_of< SG::VarHandleKeyArray, T >::value, VarHandleKeyArrayType, type2 >::type type
const Perigee * perigeeParameters() const
return Perigee.
std::string to_string(const DetectorType &type)
value_type push_back(value_type pElem)
Add an element to the end of the collection.
Eigen::Matrix< double, 3, 1 > Vector3D
virtual Intersection straightLineIntersection(const Amg::Vector3D &pos, const Amg::Vector3D &dir, bool forceDir, Trk::BoundaryCheck bchk) const override final
fast straight line intersection schema - standard: provides closest intersection and (signed) path le...
double channelHalfLength(int st, bool left) const
STRIPS ONLY: calculate channel length on the given side of the x axis (for MM stereo strips)
const PtrVector & stdcont() const
Return the underlying std::vector of the container.
bool rightEdge(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the right edge of the strip.
const Amg::Vector3D & momentum() const
Access method for the momentum.
bool empty() const noexcept
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const =0
Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean chec...
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
void sort(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, const Compare &comp)
Specialization of sort for DataVector/List.
#define ATH_MSG_WARNING(x)
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
Identifier identify() const
return the identifier -extends MeasurementBase
double stereoAngle() const
returns the stereo angle
def merge(input_file_pattern, output_file)
Merge many input LHE files into a single output file.
SG::VarHandleKey & vhKey()
Return a non-const reference to the HandleKey.
double chiSquared() const
returns the of the overall track fit
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
virtual const Amg::Vector3D & globalPosition() const override final
global position
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation.
Class to represent sTgc measurements.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>
Base class for Muon cluster RIO_OnTracks.
const Amg::Vector3D & globalDirection() const
global direction
bool leftEdge(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the left edge of the strip.