 |
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, V, H > &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, V, H > &hndl, const SG::VarHandleKeyType &) |
| specialization for handling Gaudi::Property<SG::VarHandleKey> More...
|
|
Gaudi::Details::PropertyBase & | declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyArrayType &) |
| specialization for handling Gaudi::Property<SG::VarHandleKeyArray> More...
|
|
Gaudi::Details::PropertyBase & | declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleType &) |
| specialization for handling Gaudi::Property<SG::VarHandleBase> More...
|
|
Gaudi::Details::PropertyBase & | declareGaudiProperty (Gaudi::Property< T, V, H > &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 |
|
Gaudi::Property< uint > | m_maxInputPads {this, "maxInputPads", 40, "Maximum number of pads per wedge layer."} |
|
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 819 of file MuonNSWSegmentFinderTool.cxx.
826 std::array<std::set<Identifier>,16> used_hits{};
836 const int channelType =
m_idHelperSvc->stgcIdHelper().channelType(
id);
841 std::set<Identifier>& lay_hits = used_hits[iorder];
842 if (lay_hits.count(
id))
continue;
844 orderedClusters[iorder].emplace_back(hit);
846 if (
nBad)
ATH_MSG_WARNING(
"Unable to classify " <<
nBad <<
" clusters by their layer since they are neither MM nor sTGC");
849 orderedClusters.erase(std::remove_if(orderedClusters.begin(), orderedClusters.end(),
850 [](
const MeasVec&
vec) { return vec.empty(); }),
851 orderedClusters.end());
854 for(
MeasVec& lays: orderedClusters){
856 return channel(a) < channel(b);
864 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 1370 of file MuonNSWSegmentFinderTool.cxx.
1375 const double dZ = std::abs(meas2->globalPosition().z()) -
1376 std::abs(meas1->globalPosition().z());
1381 static const double minTanTheta = 0.75 / std::sinh(maxEtaNSW);
1382 static const double maxTanTheta = 1.25 / std::sinh(minEtaNSW);
1384 const double minDR = minTanTheta * std::abs(dZ);
1385 const double maxDR = maxTanTheta * std::abs(dZ);
1387 const std::pair<double, double> rad1 =
coveredRadii(meas1);
1388 const std::pair<double, double> rad2 =
coveredRadii(meas2);
1390 const double dlR = rad2.first - rad1.first;
1391 const double drR = rad2.second - rad1.second;
1394 <<std::endl<<
". Separation in dR (left/right) "<<dlR<<
"/"<<drR<<
", dZ "<<dZ
1395 <<
" --> dR has to be in "<<minDR<<
" "<<maxDR);
1396 if ((std::abs(dlR) < minDR && std::abs(drR) < minDR) ||
1397 (dZ > 0 && dlR <0 && drR <0) || (dZ < 0 && dlR >0 && drR > 0)) {
1399 }
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 1404 of file MuonNSWSegmentFinderTool.cxx.
1406 const int chNum =
channel(meas);
1410 const double radLeft{meas->associatedSurface().localToGlobal(left).perp()};
1411 const double radRight{meas->associatedSurface().localToGlobal(right).perp()};
1412 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");
292 MuonSegmentVec out_segments{};
295 ATH_MSG_VERBOSE(
"Found " << stereoSegs.size() <<
" MMG stereo seeded segments");
296 out_segments.insert(out_segments.end(), std::make_move_iterator(stereoSegs.begin()),
297 std::make_move_iterator(stereoSegs.end()));
301 auto dump_output = [&]() {
302 cache.constructedSegs.reserve(cache.constructedSegs.size() + out_segments.size());
303 for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
306 if (clus) cache.usedHits.insert(clus->
identify());
308 cache.constructedSegs.push_back(std::move(seg));
312 std::vector<const Muon::MuonClusterOnTrack*> clustPostStereo{};
314 std::array<std::set<Identifier>, 16> masked_segs{};
315 for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
323 if (!out_segments.empty()) {
324 clustPostStereo.reserve(muonClusters.size());
332 const std::vector<const Muon::MuonClusterOnTrack*>& segmentInput = !out_segments.empty() ? clustPostStereo : muonClusters;
337 ATH_MSG_VERBOSE(
"Found " << etaSegs.size() <<
" stgc seeded eta segments");
338 MuonSegmentVec precSegs =
find3DSegments(ctx, segmentInput, etaSegs);
340 out_segments.insert(out_segments.end(),
341 std::make_move_iterator(precSegs.begin()),
342 std::make_move_iterator(precSegs.end()));
347 if (!cache.buildQuads) {
352 for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
353 std::vector<const MuonClusterOnTrack*> seg_hits{};
354 seg_hits.reserve(seg->containedMeasurements().size());
357 if (clus) seg_hits.push_back(clus);
360 for (
int iWedge{1}; iWedge<=4 ; ++iWedge) {
363 if ( quad_hits.size () < 2 || ((iWedge == 2 || iWedge == 3) && quad_hits.size() < 4))
continue;
364 std::vector<const Trk::MeasurementBase*> fit_meas{};
365 std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{
ipConstraint(ctx)};
366 if (pseudoVtx) fit_meas.push_back(pseudoVtx.get());
367 std::copy(quad_hits.begin(), quad_hits.end(), std::back_inserter(fit_meas));
369 const Trk::Surface& surf = quad_hits.front()->associatedSurface();
374 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
377 std::unique_ptr<Trk::Track> segtrack =
fit(ctx, fit_meas, startpar);
378 if (!segtrack)
continue;
383 <<
"position: "<<
to_string(seg->globalPosition())<< std::endl
384 <<
"direction: "<<
to_string(seg->globalDirection())<< std::endl
385 <<
m_printer->print(seg->containedMeasurements()));
387 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 581 of file MuonNSWSegmentFinderTool.cxx.
585 MuonSegmentVec segments{};
588 ATH_MSG_DEBUG(
"Cleaning phi clusters in stgc seeded 3D segments ");
590 ATH_MSG_DEBUG(
"After hit cleaning, there are " << phiClusters.size() <<
" phi clusters to be fit");
596 if (orderedWireClusters.size() + orderedPadClusters.size() < 2) {
597 ATH_MSG_DEBUG(
"Not enough phi hits present, cannot perform the 3D fit!");
598 segments.insert(segments.end(), std::make_move_iterator(etaSegs.begin()), std::make_move_iterator(etaSegs.end()));
603 ATH_MSG_DEBUG(
"Cleaning eta clusters in stgc seeded 3D segments ");
608 bool triedWireSeed{
false};
609 std::vector<NSWSeed> seeds_WiresSTGC;
612 for (std::unique_ptr<Muon::MuonSegment>& etaSeg : etaSegs) {
614 NSWSeed seed2D{
this, *etaSeg};
617 std::vector<NSWSeed> seeds;
620 if (std::abs(etaSeg->globalPosition().eta()) < 2.4) {
621 if (!triedWireSeed) {
623 triedWireSeed =
true;
627 if (!seeds_WiresSTGC.empty()) {
628 seeds = seeds_WiresSTGC;
634 if (seeds.empty() ) {
639 std::back_inserter(orderedPadClustersForSeeding),
649 double etaSegLocX = etaSeg->localParameters()[
Trk::locX];
650 double etaSegLocXZ = etaSeg->localDirection().angleXZ();
652 for (NSWSeed& seed : seeds) {
670 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
671 const Trk::Perigee startpar{perpos, gdir_seg, 0, perpos};
673 NSWSeed seed3D{
this, perpos, gdir_seg};
678 if (nPhiHits < 2)
continue;
680 MeasVec phiHitVec = seed3D.measurements();
685 if (
hitsToTrack(ctx, etaHitsCalibrated, phiHitVec, startpar, segTrkColl)) {
687 ATH_MSG_VERBOSE(
"Segment successfully fitted for wedge "<<singleWedge<<std::endl<<
694 if (!is3Dseg) { segments.push_back(std::move(etaSeg)); }
697 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 393 of file MuonNSWSegmentFinderTool.cxx.
407 for (
MeasVec& hitsInLayer : orderedClust) hitsInLayer =
vetoBursts(std::move(hitsInLayer));
408 orderedClust.erase(std::remove_if(orderedClust.begin(), orderedClust.end(),
409 [](
const MeasVec&
vec) { return vec.empty(); }),
411 if (orderedClust.empty())
return {};
415 ATH_MSG_DEBUG(
"Retrieved " << seeds.size() <<
" seeds in the MMStereoAlg after the ambiguity resolution" );
417 if (seeds.empty())
return {};
420 for (NSWSeed& seed : seeds) {
423 std::vector<const Trk::MeasurementBase*> fit_meas{};
425 std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{
ipConstraint(ctx)};
426 if (pseudoVtx) fit_meas.push_back(pseudoVtx.get());
428 std::copy(calib_clust.begin(), calib_clust.end(), std::back_inserter(fit_meas));
430 const Trk::Surface& surf = calib_clust.front()->associatedSurface();
436 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
441 std::unique_ptr<Trk::Track> segtrack =
fit(ctx, fit_meas, startpar);
442 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 478 of file MuonNSWSegmentFinderTool.cxx.
493 ATH_MSG_DEBUG(
"Cleaning eta clusters in stgc seeded 2D segments ");
500 if (orderedClusters.size() < 4)
return {};
509 for (NSWSeed& seed : seeds) {
510 if (
seed.size() < 4){
511 ATH_MSG_VERBOSE(__func__<<
" :"<<__LINE__<<
" - Seed size: " <<
seed.size() <<
" is below the cut (4)");
515 etaHitVec =
seed.measurements();
533 if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
534 const auto startpar =
Trk::Perigee(perpos, gdir_seg, 0, perpos);
535 ATH_MSG_VERBOSE(
" start parameter " << perpos <<
" pp " << startpar.position() <<
" gd " << gdir_seg.unit() <<
" pp "
536 << startpar.momentum().unit());
539 hitsToTrack(ctx, etaHitVec, phiHitVec, startpar, segTrkColl);
◆ fit()
◆ getCalibratedClusters()
MeasVec Muon::MuonNSWSegmentFinderTool::getCalibratedClusters |
( |
NSWSeed & |
seed | ) |
const |
|
private |
Definition at line 1540 of file MuonNSWSegmentFinderTool.cxx.
1547 std::unique_ptr<const Muon::MuonClusterOnTrack> newClus;
1557 calibratedClusters.emplace_back(
seed.newCalibClust(std::move(newClus)));
1561 calibratedClusters.emplace_back(
seed.newCalibClust(std::move(newClus)));
1565 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 1440 of file MuonNSWSegmentFinderTool.cxx.
1446 std::vector<std::vector<double>> padsPhiL, padsPhiR;
1447 std::vector<double> padsPhiC;
1450 for (
const std::vector<const Muon::sTgcPrepData*>& surfHits : pads) {
1452 std::vector<double> surfPadsPhiL, surfPadsPhiR;
1462 const double halfWidthX = 0.5 * design->
channelWidth(prd->localPosition(),
true);
1463 const double hitPadX = prd->localPosition().x();
1467 bool samePhi = std::find_if(padsPhiC.begin(), padsPhiC.end(), [&hitPadX, &halfWidthX](
const double prevPadPhi) {
1468 return std::abs(hitPadX - prevPadPhi) < 0.9 * halfWidthX;
1469 }) != padsPhiC.end();
1471 if (samePhi)
continue;
1474 surfPadsPhiL.push_back(hitPadX - halfWidthX);
1475 surfPadsPhiR.push_back(hitPadX + halfWidthX);
1476 padsPhiC.push_back(hitPadX);
1480 padsPhiL.push_back(std::move(surfPadsPhiL));
1481 padsPhiR.push_back(std::move(surfPadsPhiR));
1484 unsigned int nSurf = padsPhiR.size();
1488 unsigned int nCombos{1};
1489 for (
const std::vector<double>& surfPadsPhiR : padsPhiR) {
1490 if (!surfPadsPhiR.empty()) nCombos *= surfPadsPhiR.size();
1493 std::vector<std::pair<double, double>> phiOverlap;
1494 phiOverlap.reserve(nCombos);
1496 if (nCombos <= 100) {
1497 unsigned int N{nCombos};
1498 for (
unsigned int isurf{0}; isurf < nSurf; ++isurf) {
1499 if (padsPhiR[isurf].
empty())
continue;
1500 unsigned int nSurfHits = padsPhiR[isurf].size();
1503 for (
unsigned int icombo{0}; icombo < nCombos; ++icombo) {
1505 unsigned int padIdx = (icombo /
N) % nSurfHits;
1508 phiOverlap.emplace_back(padsPhiL[isurf][padIdx], padsPhiR[isurf][padIdx]);
1511 phiOverlap[icombo].first =
std::max(padsPhiL[isurf][padIdx], phiOverlap[icombo].
first);
1512 phiOverlap[icombo].second =
std::min(padsPhiR[isurf][padIdx], phiOverlap[icombo].
second);
1518 phiOverlap.erase(std::remove_if(phiOverlap.begin(), phiOverlap.end(),
1519 [](std::pair<double, double>&
range) { return range.first >= range.second; }),
1521 ATH_MSG_DEBUG(
"Pad seeding - #combinations initial: " << nCombos
1522 <<
", after cleaning for non overlapping pads: " << phiOverlap.size());
1526 for (
unsigned int isurf{0}; isurf < nSurf; ++isurf) {
1527 unsigned int nSurfHits = padsPhiR[isurf].size();
1528 for (
unsigned int ihit{0}; ihit < nSurfHits; ++ihit) {
1529 phiOverlap.emplace_back(padsPhiL[isurf][ihit], padsPhiR[isurf][ihit]);
1532 ATH_MSG_DEBUG(
"Pad seeding - #combinations: " << nCombos <<
" is too large. Seeding from" << phiOverlap.size()
1533 <<
" individual pads.");
◆ hitsToTrack()
Definition at line 741 of file MuonNSWSegmentFinderTool.cxx.
747 std::vector<const Trk::MeasurementBase*> vecFitPts;
748 unsigned int nHitsEta = etaHitVec.size();
749 unsigned int nHitsPhi = phiHitVec.size();
752 std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{
ipConstraint(ctx)},
754 pseudoPhi1{
nullptr}, pseudoPhi2{
nullptr};
756 if (pseudoVtx) { vecFitPts.push_back(pseudoVtx.get()); }
757 if (pseudoVtxCalo) { vecFitPts.push_back(pseudoVtxCalo.get()); }
765 cov(0, 0) = pseudoPrecision;
767 pseudoPhi1 = std::make_unique<Trk::PseudoMeasurementOnTrack>(
Trk::LocalParameters(loc_pseudopars),
769 etaHitVec.front()->associatedSurface());
770 pseudoPhi2 = std::make_unique<Trk::PseudoMeasurementOnTrack>(
Trk::LocalParameters(loc_pseudopars),
772 etaHitVec.back()->associatedSurface());
775 vecFitPts.push_back(pseudoPhi1.get());
776 std::copy(etaHitVec.begin(), etaHitVec.end(), std::back_inserter(vecFitPts));
777 vecFitPts.push_back(pseudoPhi2.get());
778 ATH_MSG_DEBUG(
"Fitting a 2D-segment track with " << nHitsEta <<
" Eta hits");
782 std::merge(phiHitVec.begin(), phiHitVec.end(), etaHitVec.begin(), etaHitVec.end(), std::back_inserter(vecFitPts),
784 double z1 = std::abs(c1->detectorElement()->center(c1->identify()).z());
785 double z2 = std::abs(c2->detectorElement()->center(c2->identify()).z());
788 ATH_MSG_DEBUG(
"Fitting a 3D-segment track with " << nHitsEta <<
" Eta hits and " << nHitsPhi <<
" Phi hits");
792 std::unique_ptr<Trk::Track> segtrack =
fit(ctx, vecFitPts, startpar);
793 if (!segtrack)
return false;
794 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 1592 of file MuonNSWSegmentFinderTool.cxx.
1593 std::stringstream sstr{};
1594 unsigned int lay{0};
1595 for (
const MeasVec& clusts: sortedVec){
1596 sstr<<
"Clusters in Layer: "<<(lay+1)<<std::endl;
1597 sstr<<
"#################################################"<<std::endl;
1598 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 544 of file MuonNSWSegmentFinderTool.cxx.
556 MuonSegmentVec segments{};
557 std::unique_ptr<const TrackCollection> resolvedTracks(
m_ambiTool->process(&segTrkColl));
558 ATH_MSG_DEBUG(
"Resolved track candidates: old size " << segTrkColl.size() <<
" new size " << resolvedTracks->size());
561 for (
const Trk::Track* trk : *resolvedTracks) {
562 const auto* measurements = trk->measurementsOnTrack();
563 const bool has_eta = std::find_if(measurements->begin(), measurements->end(),
565 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
566 return id.is_valid() && !m_idHelperSvc->measuresPhi(id);
567 }) != trk->measurementsOnTrack()->end();
568 if (!has_eta)
continue;
573 segments.emplace_back(std::move(seg));
◆ resolveAmbiguities() [2/2]
std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::resolveAmbiguities |
( |
std::vector< NSWSeed > && |
unresolved | ) |
const |
|
private |
Definition at line 1414 of file MuonNSWSegmentFinderTool.cxx.
1415 std::vector<NSWSeed> seeds;
1416 seeds.reserve(unresolved.size());
1417 std::sort(unresolved.begin(), unresolved.end(),[](
const NSWSeed&
a,
const NSWSeed&
b){
1418 return a.chi2() < b.chi2();
1420 for (NSWSeed& seed : unresolved) {
1421 bool add_seed{
true};
1422 for (NSWSeed&
good : seeds) {
1433 if (add_seed) seeds.push_back(std::move(seed));
1435 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 1122 of file MuonNSWSegmentFinderTool.cxx.
1124 std::vector<NSWSeed> seeds;
1125 std::array<unsigned int, 4>
layers{};
1126 unsigned int trials{0}, used_layers{0};
1128 constexpr
size_t lastMMLay = 11;
1129 std::vector<NSWSeed> laySeeds;
1132 std::stringstream sstr{};
1133 for (
int e4 =
std::min(lastMMLay, orderedClusters.size() -1);
e4 >= 3 ; --
e4) {
1135 for (
int e3 =
e4 -1 ;
e3 >= 2; --
e3) {
1141 const unsigned int old_trials = trials;
1143 if (old_trials == trials)
continue;
1145 used_layers += !laySeeds.empty();
1146 seeds.insert(seeds.end(), std::make_move_iterator(laySeeds.begin()),
1147 std::make_move_iterator(laySeeds.end()));
1150 sstr<<
" Attempts thus far "<<old_trials<<
" attempts now "<<trials<<
" --- "<<
e1<<
","<<
e2<<
","<<
e3<<
","<<
e4<<std::endl;
1152 sstr<<
"Layer: "<<lay<<
" number of measurements "<<orderedClusters[lay].size()<<std::endl;
1154 sstr<<
" **** "<<
print(meas)<<std::endl;
1156 sstr<<std::endl<<std::endl<<std::endl;
1163 if (trials > 100000) {
1166 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 1173 of file MuonNSWSegmentFinderTool.cxx.
1176 std::vector<NSWSeed> seeds{};
1178 std::array<unsigned int, 4> lay_ord{};
1179 for (
size_t s = 0;
s < selLayers.size(); ++
s) {
1180 unsigned int lay = selLayers[
s];
1188 else lay_ord[
s] = 3;
1190 auto swap_strips = [&selLayers, &lay_ord] (
unsigned int i,
unsigned j){
1195 if (lay_ord[0] == lay_ord[1]){
1196 if (lay_ord[1] != lay_ord[2]) swap_strips(1,2);
1197 else if (lay_ord[1] != lay_ord[3]) swap_strips(1,3);
1204 if (lay_ord[2] == lay_ord[3]) {
1207 if (lay_ord[3] != lay_ord[0] && lay_ord[3] != lay_ord[1]) swap_strips(3,0);
1209 ATH_MSG_VERBOSE(
"No way to rearrange the strips such that the latter two strips cross.");
1214 std::array<SeedMeasurement, 4> base_seed{};
1215 for (
size_t s = 0;
s < selLayers.size(); ++
s) {
1216 unsigned int lay = selLayers[
s];
1217 base_seed[
s] = orderedClusters[lay].front();
1220 const double A = (base_seed[1].pos().z() - base_seed[0].pos().z());
1221 const double G = (base_seed[2].pos().z() - base_seed[0].pos().z());
1222 const double K = (base_seed[3].pos().z() - base_seed[0].pos().z());
1225 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);
1226 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);
1228 if (std::abs(diamond.determinant()) < std::numeric_limits<float>::epsilon()) {
1230 << diamond << std::endl
1231 <<
" is singular " << diamond.determinant() <<
" with rank "
1232 << (Eigen::FullPivLU<
AmgSymMatrix(2)>{diamond}.rank()));
1237 << diamond << std::endl
1238 <<
"May give a couple of stereo seeds " << diamond.determinant());
1247 const double TwoDotZero = base_seed[2].dirDot(base_seed[0]);
1248 const double ThreeDotZero = base_seed[3].dirDot(base_seed[0]);
1249 const double ThreeDotOne = base_seed[3].dirDot(base_seed[1]);
1250 const double TwoDotOne = base_seed[2].dirDot(base_seed[1]);
1252 auto estimate_muon = [&] () -> std::optional<std::
array<
double,2>> {
1253 const Amg::Vector3D Y0 = K * base_seed[2].pos() -
G * base_seed[3].pos() - KmG * base_seed[0].pos();
1254 const Amg::Vector3D Y1 = AmG * base_seed[3].pos() - KmG * base_seed[1].pos() + KmA * base_seed[2].pos();
1255 const double Y0dotE0 = base_seed[0].dirDot(Y0);
1256 const double Y1dotE1 = base_seed[1].dirDot(Y1);
1258 const AmgVector(2) centers = (KmG * (base_seed[0].
pos() - base_seed[1].
pos()) +
1259 Y0dotE0 * base_seed[0].
dir() +
1260 A * (base_seed[3].
pos() - base_seed[2].
pos()) -
1261 Y1dotE1 * base_seed[1].
dir())
1265 const std::
array<
double, 4> lengths{(Y0dotE0 + K * sol_pars[0] * TwoDotZero -
G * sol_pars[1] * ThreeDotZero) / KmG,
1266 (Y1dotE1 + AmG * sol_pars[1] *ThreeDotOne + KmA * sol_pars[0] * TwoDotOne) / KmG, sol_pars[0], sol_pars[1]};
1270 std::optional<Amg::Vector3D> seg_pos{std::nullopt}, seg_dir{std::nullopt};
1271 for (
unsigned int i = 0;
i < base_seed.size(); ++
i) {
1277 seg_pos = std::make_optional<Amg::Vector3D>(base_seed[0].
pos() +
1278 lengths[0] * base_seed[0].
dir());
1282 seg_dir = std::make_optional<Amg::Vector3D>((base_seed[1].
pos() +
1283 lengths[1] *base_seed[1].
dir() - (*seg_pos)).
unit());
1286 std::optional<double> mu_crossing = Amg::intersect<3>(*seg_pos, *seg_dir, base_seed[
i].
pos(),base_seed[
i].
dir());
1288 <<
" ("<< std::string( halfLength > std::abs(lengths[
i]) ?
"inside" :
"outside")<<
" wedge) "
1289 << halfLength <<
" vs. "<<std::abs(lengths[
i])<<
" crossing point: "<<std::abs(*mu_crossing));
1290 }
else if (!
accept)
return std::nullopt;
1292 if (!
accept)
return std::nullopt;
1293 return std::make_optional<std::array<double,2>>({lengths[0], lengths[1]});
1298 MeasVec::const_iterator begin2{orderedClusters[selLayers[1]].begin()};
1299 MeasVec::const_iterator begin3{orderedClusters[selLayers[2]].begin()};
1300 MeasVec::const_iterator begin4{orderedClusters[selLayers[3]].begin()};
1302 const MeasVec::const_iterator end2{orderedClusters[selLayers[1]].end()};
1303 const MeasVec::const_iterator end3{orderedClusters[selLayers[2]].end()};
1304 const MeasVec::const_iterator end4{orderedClusters[selLayers[3]].end()};
1307 base_seed[0] = lay1;
1308 for (MeasVec::const_iterator lay2 = begin2; lay2 != end2; ++lay2) {
1310 base_seed[1] = *lay2;
1323 for (MeasVec::const_iterator lay3 = begin3; lay3 != end3; ++lay3) {
1332 base_seed[2] = *lay3;
1334 for (MeasVec::const_iterator lay4 = begin4 ; lay4 != end4; ++lay4) {
1343 base_seed[3] = (*lay4);
1344 std::optional<std::array<double, 2>> isects = estimate_muon();
1346 if (!isects)
continue;
1347 NSWSeed
seed{
this, base_seed, *isects};
1349 if (
seed.size() < 4)
continue;
1351 const double eta = std::abs(
seed.dir().eta());
1352 if (eta < minEtaNSW || eta > maxEtaNSW) {
1355 if (
seed.dir().block<2,1>(0,0).dot(
seed.pos().block<2,1>(0,0)) < 0.)
continue;
1359 if (
deltaPhi > sector_mapping.sectorWidth(
m_idHelperSvc->sector(base_seed[0]->identify())))
continue;
1361 getClustersOnSegment(orderedClusters, seed, {selLayers[0], selLayers[1],selLayers[2], selLayers[3]});
1362 seeds.emplace_back(std::move(seed));
◆ segmentSeedFromPads()
Do not run an empty container
Definition at line 985 of file MuonNSWSegmentFinderTool.cxx.
987 std::vector<NSWSeed> seeds;
989 if (orderedClusters.empty())
return seeds;
991 std::vector<std::vector<const Muon::sTgcPrepData*>> sTgcIP(4);
992 std::vector<std::vector<const Muon::sTgcPrepData*>> sTgcHO(4);
995 for (
int iml : {1, 2}) {
996 int il = (iml == 1) ? 0 : orderedClusters.size() - 1;
997 int iend = (iml == 1) ? orderedClusters.size() : -1;
998 int idir = (iml == 1) ? 1 : -1;
999 unsigned int nLayersWithHitMatch{0};
1002 for (;
il != iend;
il += idir) {
1003 double lastDistance{1000.};
1004 if (nLayersWithHitMatch >= sTgcIP.size()) {
1005 sTgcIP.resize(nLayersWithHitMatch + 1);
1006 sTgcHO.resize(nLayersWithHitMatch + 1);
1008 std::vector<const Muon::sTgcPrepData*>& matchedHits =
1009 (iml == 1) ? sTgcIP.at(nLayersWithHitMatch) : sTgcHO.at(nLayersWithHitMatch);
1014 if (!padHit)
continue;
1017 if (
m_idHelperSvc->stgcIdHelper().multilayer(padHit->identify()) != iml)
continue;
1020 if (!design)
continue;
1023 const Trk::Surface& surf = padHit->detectorElement()->surface(padHit->identify());
1031 double chWidth = design->
channelWidth(padHit->localPosition(),
false);
1032 double etaDistance = std::abs(padHit->localPosition().y() - segLocPosOnSurf[1]);
1033 if (etaDistance > 0.5 * chWidth)
continue;
1034 ATH_MSG_DEBUG(
" etaDistance " << etaDistance <<
" between pad center and position on the pad.");
1036 if (matchedHits.empty()) {
1038 matchedHits.push_back(padHit);
1040 }
else if (std::abs(etaDistance - lastDistance) < 0.001) {
1042 matchedHits.push_back(padHit);
1043 ATH_MSG_DEBUG(
" added etaDistance: " << etaDistance <<
" size " << matchedHits.size());
1044 }
else if (etaDistance < lastDistance) {
1046 matchedHits.clear();
1047 matchedHits.push_back(padHit);
1048 ATH_MSG_DEBUG(
" replacing best etaDistance with: " << etaDistance);
1052 lastDistance = etaDistance;
1055 if (!matchedHits.empty()) ++nLayersWithHitMatch;
1060 if (!nLayersWithHitMatch)
return seeds;
1065 std::vector<std::pair<double, double>> sTgcIP_phiRanges =
getPadPhiOverlap(sTgcIP);
1066 std::vector<std::pair<double, double>> sTgcHO_phiRanges =
getPadPhiOverlap(sTgcHO);
1071 const auto& surfPrdL1 = prdL1->detectorElement()->surface();
1072 const auto& surfPrdL2 = prdL2->detectorElement()->surface();
1075 for (
const std::pair<double, double>& range1 : sTgcIP_phiRanges) {
1076 double midPhi1 = 0.5 * (range1.first + range1.second);
1079 surfPrdL1.localToGlobal(lp1, gpL1, gpL1);
1081 Amg::Vector2D lp1_lowPhi{range1.first, prdL1->localPosition().y()};
1082 Amg::Vector2D lp1_highPhi{range1.second, prdL1->localPosition().y()};
1087 surfPrdL1.localToGlobal(lp1_lowPhi, gp1_lowPhi, gp1_lowPhi);
1088 surfPrdL1.localToGlobal(lp1_highPhi, gp1_highPhi, gp1_highPhi);
1090 Trk::Intersection intersect_lowPhi = surfPrdL2.straightLineIntersection(gp1_lowPhi, gp1_lowPhi,
false,
false);
1091 Trk::Intersection intersect_highPhi = surfPrdL2.straightLineIntersection(gp1_highPhi, gp1_highPhi,
false,
false);
1096 surfPrdL2.globalToLocal(intersect_lowPhi.
position, intersect_lowPhi.
position, lpIntersect_lowPhi);
1097 surfPrdL2.globalToLocal(intersect_highPhi.
position, intersect_highPhi.
position, lpIntersect_highPhi);
1099 for (
const std::pair<double, double>& range2 : sTgcHO_phiRanges) {
1100 double midPhi2 = 0.5 * (range2.first + range2.second);
1102 if( lpIntersect_highPhi.x() - range2.first < 0 || range2.second - lpIntersect_lowPhi.x() < 0) {
1103 ATH_MSG_DEBUG(
" segmentSeedFromPads: skipping seed with non-overlapping phi ranges");
1109 surfPrdL2.localToGlobal(lp2, gpL2, gpL2);
1113 seeds.emplace_back(
this, gpL1, gDir);
1117 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 868 of file MuonNSWSegmentFinderTool.cxx.
870 std::vector<NSWSeed> seeds;
874 if (orderedClusters.size() < 4)
return seeds;
880 int seedingLayersL{0};
881 for (
unsigned int ilayerL{0}; (ilayerL < orderedClusters.size() && seedingLayersL <
m_nOfSeedLayers); ++ilayerL) {
882 bool usedLayerL{
false};
885 if (usePhi !=
m_idHelperSvc->measuresPhi(hitL->identify()))
continue;
890 int seedingLayersR{0};
891 for (
unsigned int ilayerR = orderedClusters.size() - 1; (ilayerR > ilayerL && seedingLayersR <
m_nOfSeedLayers);
893 bool usedLayerR{
false};
895 if (usePhi !=
m_idHelperSvc->measuresPhi(hitR->identify()))
continue;
897 NSWSeed
seed{
this,hitL, hitR};
899 const double eta =
seed.dir().perp() > std::numeric_limits<float>::epsilon() ? std::abs(
seed.dir().eta()): FLT_MAX;
900 if (eta < minEtaNSW || eta > maxEtaNSW) {
905 if(std::abs(std::abs(
m_idHelperSvc->stationEta(hitL->identify())) - std::abs(
m_idHelperSvc->stationEta(hitR->identify()))) > 1) {
909 Trk::Intersection intersect = hitR->detectorElement()->surface(hitR->identify()).straightLineIntersection(hitL->globalPosition(),hitL->globalPosition().unit(),
false,
false);
911 hitR->detectorElement()->surface(hitR->identify()).globalToLocal(
intersect.position,
intersect.position, lpos_intersect);
914 hitR->detectorElement()->surface(hitR->identify()).globalToLocal(hitR->globalPosition(), hitR->globalPosition(), lPosR);
917 if(std::abs(lpos_intersect.x() - lPosR.x()) > 87.5 )
continue;
923 seeds.emplace_back(std::move(seed));
926 if (usedLayerR) ++seedingLayersR;
929 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 1604 of file MuonNSWSegmentFinderTool.cxx.
1612 prunedMeas.reserve(clustInLay.size());
1613 const unsigned int firstCh =
channel(clustInLay[0]);
1614 const unsigned int lastCh =
channel(clustInLay[clustInLay.size() -1]);
1616 const unsigned int deltaCh = lastCh - firstCh;
1619 firstCh<<
", highest channel: "<<lastCh<<
" bin width: "<<
m_ocupMmBinWidth<<
" number of bins"<<
nBins);
1622 occupancyHisto.resize(
nBins);
1624 bin.reserve(clustInLay.size());
1630 occupancyHisto[
bin].push_back(std::move(meas));
1640 for (
unsigned int i = 0;
i < occupancyHisto.size() -1; ++
i) {
1642 ATH_MSG_VERBOSE(
"The two neighbouring bins "<<
i<<
"&"<<(
i+1)<<
" have too many clusters "<<std::endl<<
1643 print(occupancyHisto[
i])<<std::endl<<
print(occupancyHisto[
i+1]));
1644 occupancyHisto[
i].clear();
1645 occupancyHisto[
i+1].clear();
1651 std::make_move_iterator(
bin.end()),
1652 std::back_inserter(prunedMeas));
1655 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_maxInputPads
Gaudi::Property<uint> Muon::MuonNSWSegmentFinderTool::m_maxInputPads {this, "maxInputPads", 40, "Maximum number of pads per wedge layer."} |
|
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
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
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>
@ OWN_ELEMENTS
this data object owns its elements
CalibratedSpacePoint::Covariance_t inverse(const CalibratedSpacePoint::Covariance_t &mat)
Inverts the parsed matrix.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Out copy_if(In first, const In &last, Out res, const Pred &p)
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()) ]
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.