ATLAS Offline Software
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
Muon::MuonNSWSegmentFinderTool Class Reference

#include <MuonNSWSegmentFinderTool.h>

Inheritance diagram for Muon::MuonNSWSegmentFinderTool:
Collaboration diagram for Muon::MuonNSWSegmentFinderTool:

Public Types

using SeedMeasurement = NSWSeed::SeedMeasurement
 
using MeasVec = NSWSeed::MeasVec
 
using LayerMeasVec = std::vector< MeasVec >
 
using MuonClusterPtr = std::unique_ptr< const Muon::MuonClusterOnTrack >
 
using MuonClusterVec = std::vector< MuonClusterPtr >
 

Public Member Functions

 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 IMuonIdHelperSvcidHelper () 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
 

Static Public Member Functions

static const InterfaceID & interfaceID ()
 access to tool interface More...
 

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution More...
 
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
 
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed. More...
 

Private Types

enum  HitType { Eta = 1, Phi = 1 << 1, Wire = 1 << 2, Pad = 1 << 3 }
 
enum  ChannelConstraint { ChannelConstraint::InWindow, ChannelConstraint::TooNarrow, ChannelConstraint::TooWide }
 
typedef ServiceHandle< StoreGateSvcStoreGateSvc_t
 

Private Member Functions

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< NSWSeedsegmentSeedFromStgc (const LayerMeasVec &orderedClusters, bool usePhi) const
 
std::vector< NSWSeedsegmentSeedFromMM (const LayerMeasVec &orderedClusters) const
 
std::vector< NSWSeedsegmentSeedFromMM (const LayerMeasVec &orderedClusters, std::array< unsigned int, 4 > selLayers, unsigned int &trial_counter) const
 
std::vector< NSWSeedsegmentSeedFromPads (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::PseudoMeasurementOnTrackipConstraint (const EventContext &ctx) const
 creates the IP constraint More...
 
std::unique_ptr< Trk::PseudoMeasurementOnTrackcaloConstraint (const Trk::TrackParameters &startpar) const
 
std::vector< NSWSeedresolveAmbiguities (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::Trackfit (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...
 

Private Attributes

ServiceHandle< IMuonIdHelperSvcm_idHelperSvc
 
ServiceHandle< IMuonEDMHelperSvcm_edmHelperSvc
 
ToolHandle< Trk::ITrackAmbiguityProcessorToolm_ambiTool
 Tool for ambiguity solving. More...
 
ToolHandle< Trk::ITrackFitterm_slTrackFitter
 
ToolHandle< IMuonTrackToSegmentToolm_trackToSegmentTool
 
PublicToolHandle< MuonEDMPrinterToolm_printer
 
ToolHandle< IMuonTrackCleanerm_trackCleaner
 
ToolHandle< Trk::ITrackSummaryToolm_trackSummary
 
ToolHandle< IMuonClusterOnTrackCreatorm_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< uintm_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
 

Detailed Description

Definition at line 126 of file MuonNSWSegmentFinderTool.h.

Member Typedef Documentation

◆ LayerMeasVec

Definition at line 204 of file MuonNSWSegmentFinderTool.h.

◆ MeasVec

Definition at line 203 of file MuonNSWSegmentFinderTool.h.

◆ MuonClusterPtr

Definition at line 27 of file IMuonNSWSegmentFinderTool.h.

◆ MuonClusterVec

Definition at line 28 of file IMuonNSWSegmentFinderTool.h.

◆ SeedMeasurement

Definition at line 202 of file MuonNSWSegmentFinderTool.h.

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Member Enumeration Documentation

◆ ChannelConstraint

Enumerator
InWindow 
TooNarrow 
TooWide 

Definition at line 298 of file MuonNSWSegmentFinderTool.h.

298  {
299  InWindow,
300  TooNarrow,
301  TooWide
302 
303  };

◆ HitType

Enumerator
Eta 
Phi 
Wire 
Pad 

Definition at line 230 of file MuonNSWSegmentFinderTool.h.

230 { Eta = 1, Phi = 1 << 1, Wire = 1 << 2, Pad = 1 << 3 };

Constructor & Destructor Documentation

◆ MuonNSWSegmentFinderTool()

Muon::MuonNSWSegmentFinderTool::MuonNSWSegmentFinderTool ( const std::string &  type,
const std::string &  name,
const IInterface *  parent 
)

default constructor

Definition at line 256 of file MuonNSWSegmentFinderTool.cxx.

256  :
258  declareInterface<IMuonNSWSegmentFinderTool>(this);
259  }

◆ ~MuonNSWSegmentFinderTool()

virtual Muon::MuonNSWSegmentFinderTool::~MuonNSWSegmentFinderTool ( )
virtualdefault

destructor

Member Function Documentation

◆ caloConstraint()

std::unique_ptr< Trk::PseudoMeasurementOnTrack > Muon::MuonNSWSegmentFinderTool::caloConstraint ( const Trk::TrackParameters startpar) const
private

Definition at line 701 of file MuonNSWSegmentFinderTool.cxx.

701  {
702  if (!m_caloConstraint) return nullptr;
703  constexpr double errVtx{1.*Gaudi::Units::m};
704  Amg::MatrixX covVtx(2,2);
705  covVtx.setIdentity();
706  covVtx = errVtx * errVtx * covVtx;
707  const Amg::Vector3D parPos{startpar.position()};
708  Amg::Vector3D projection{parPos.x(), parPos.y(), 0};
709  // project
710  Trk::PerigeeSurface perVtx(projection);
711  return std::make_unique<Trk::PseudoMeasurementOnTrack>(Trk::LocalParameters(Trk::DefinedParameter(0, Trk::locX),
713  std::move(covVtx),
714  std::move(perVtx));
715 
716  }

◆ channel()

int Muon::MuonNSWSegmentFinderTool::channel ( const Muon::MuonClusterOnTrack cluster) const

Returns the channel of the measurement on the layer.

Definition at line 953 of file MuonNSWSegmentFinderTool.cxx.

953  {
954  if (m_idHelperSvc->isMM(cluster->identify())) return m_idHelperSvc->mmIdHelper().channel(cluster->identify());
955  if (m_idHelperSvc->issTgc(cluster->identify())) return m_idHelperSvc->stgcIdHelper().channel(cluster->identify());
956  return -1;
957  }

◆ classifyByLayer()

MuonNSWSegmentFinderTool::LayerMeasVec Muon::MuonNSWSegmentFinderTool::classifyByLayer ( const MeasVec clusters,
int  hit_sel 
) const
private

Definition at line 819 of file MuonNSWSegmentFinderTool.cxx.

820  {
821  // Classifies clusters by layer, starting from the layer closest to the IP and moving outwards.
822  // "clusters" is expected to contain only eta (MM+sTGC strip) or only phi hits (sTGC pads XOR wires).
823  // The returned vector contains only layers that have hits.
824 
825  LayerMeasVec orderedClusters(16);
826  std::array<std::set<Identifier>,16> used_hits{};
827  int nBad{0};
828  for (const Muon::MuonClusterOnTrack* hit : clusters) {
829  const int iorder = layerNumber(hit);
830  if (iorder < 0) {
831  ++nBad;
832  continue;
833  }
834  const Identifier id = hit->identify();
835  if (m_idHelperSvc->issTgc(id)) {
836  const int channelType = m_idHelperSvc->stgcIdHelper().channelType(id);
837  // skip sTGC pads if using wires, or skip wires if using pads
838  if (!(hit_sel & HitType::Pad) && channelType == sTgcIdHelper::Pad) continue;
839  if (!(hit_sel & HitType::Wire) && channelType == sTgcIdHelper::Wire) continue;
840  }
841  std::set<Identifier>& lay_hits = used_hits[iorder];
842  if (lay_hits.count(id)) continue;
843  lay_hits.insert(id);
844  orderedClusters[iorder].emplace_back(hit);
845  }
846  if (nBad) ATH_MSG_WARNING("Unable to classify " << nBad << " clusters by their layer since they are neither MM nor sTGC");
847 
848  // Erase layers without hits
849  orderedClusters.erase(std::remove_if(orderedClusters.begin(), orderedClusters.end(),
850  [](const MeasVec& vec) { return vec.empty(); }),
851  orderedClusters.end());
852 
853 
854  for( MeasVec& lays: orderedClusters){
855  std::sort(lays.begin(),lays.end(), [this](const SeedMeasurement& a, const SeedMeasurement& b){
856  return channel(a) < channel(b);
857  });
858  ATH_MSG_DEBUG("Found in layer "<<m_idHelperSvc->toStringDetEl(lays[0]->identify())<<" "<<lays.size()<<" clusters");
859 
860 
861  }
862  ATH_MSG_VERBOSE("Collected clusters "<<print(orderedClusters));
863 
864  return orderedClusters;
865  }

◆ cleanClusters()

MeasVec Muon::MuonNSWSegmentFinderTool::cleanClusters ( const std::vector< const Muon::MuonClusterOnTrack * > &  MuonClusters,
int  hit_sel,
int  singleWedge 
) const
private

Definition at line 799 of file MuonNSWSegmentFinderTool.cxx.

800  {
801  // Keep only eta (MM && sTGC) or phi (sTGC) clusters
802  // In single-wedge mode keep only clusters from the requested wedge
804  clusters.reserve(muonClusters.size());
805  for (const Muon::MuonClusterOnTrack* cluster : muonClusters) {
806  if (!cluster) continue;
807  if (singleWedge && singleWedge != wedgeNumber(cluster)) continue;
808  const Identifier id = cluster->identify();
809  if (((hit_sel & HitType::Eta) && !m_idHelperSvc->measuresPhi(id)) ||
810  ((hit_sel & HitType::Phi) && m_idHelperSvc->measuresPhi(id)))
811  clusters.emplace_back(cluster);
812  }
813 
814  ATH_MSG_VERBOSE(" After hit cleaning, there are " << clusters.size() );
815  return clusters;
816  }

◆ compatiblyFromIP()

MuonNSWSegmentFinderTool::ChannelConstraint Muon::MuonNSWSegmentFinderTool::compatiblyFromIP ( const SeedMeasurement meas1,
const SeedMeasurement meas2 
) const
inlineprivate

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.

1370  {
1372 
1373  // For a given dZ the measurements can only be separated by a certain dR such that the
1375  const double dZ = std::abs(meas2->globalPosition().z()) -
1376  std::abs(meas1->globalPosition().z());
1377 
1381  static const double minTanTheta = 0.75 / std::sinh(maxEtaNSW);
1382  static const double maxTanTheta = 1.25 / std::sinh(minEtaNSW);
1383 
1384  const double minDR = minTanTheta * std::abs(dZ);
1385  const double maxDR = maxTanTheta * std::abs(dZ);
1386 
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;
1392  ATH_MSG_VERBOSE("compatiblyFromIP() -- Measurements "<<std::endl
1393  <<print(meas1)<<std::endl<<print(meas2)
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.){
1401  }
1403  }

◆ 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.

1404  {
1405  const MuonGM::MuonChannelDesign* design = getDesign(meas);
1406  const int chNum = channel(meas);
1408  design->leftEdge(chNum, left);
1409  design->rightEdge(chNum, right);
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);
1413  }

◆ declareGaudiProperty() [1/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleKeyArrayType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKeyArray>

Definition at line 170 of file AthCommonDataStore.h.

172  {
173  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
174  hndl.value(),
175  hndl.documentation());
176 
177  }

◆ declareGaudiProperty() [2/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleKeyType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158  {
159  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
160  hndl.value(),
161  hndl.documentation());
162 
163  }

◆ declareGaudiProperty() [3/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleBase>

Definition at line 184 of file AthCommonDataStore.h.

186  {
187  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
188  hndl.value(),
189  hndl.documentation());
190  }

◆ declareGaudiProperty() [4/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  t,
const SG::NotHandleType  
)
inlineprivateinherited

specialization for handling everything that's not a Gaudi::Property<SG::VarHandleKey> or a <SG::VarHandleKeyArray>

Definition at line 199 of file AthCommonDataStore.h.

200  {
201  return PBASE::declareProperty(t);
202  }

◆ declareProperty() [1/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleBase hndl,
const std::string &  doc,
const SG::VarHandleType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
hndlObject holding the property value.
docDocumentation 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.

249  {
250  this->declare(hndl.vhKey());
251  hndl.vhKey().setOwner(this);
252 
253  return PBASE::declareProperty(name,hndl,doc);
254  }

◆ declareProperty() [2/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleKey hndl,
const std::string &  doc,
const SG::VarHandleKeyType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
hndlObject holding the property value.
docDocumentation 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.

225  {
226  this->declare(hndl);
227  hndl.setOwner(this);
228 
229  return PBASE::declareProperty(name,hndl,doc);
230  }

◆ declareProperty() [3/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleKeyArray hndArr,
const std::string &  doc,
const SG::VarHandleKeyArrayType  
)
inlineinherited

Definition at line 259 of file AthCommonDataStore.h.

263  {
264 
265  // std::ostringstream ost;
266  // ost << Algorithm::name() << " VHKA declareProp: " << name
267  // << " size: " << hndArr.keys().size()
268  // << " mode: " << hndArr.mode()
269  // << " vhka size: " << m_vhka.size()
270  // << "\n";
271  // debug() << ost.str() << endmsg;
272 
273  hndArr.setOwner(this);
274  m_vhka.push_back(&hndArr);
275 
276  Gaudi::Details::PropertyBase* p = PBASE::declareProperty(name, hndArr, doc);
277  if (p != 0) {
278  p->declareUpdateHandler(&AthCommonDataStore<PBASE>::updateVHKA, this);
279  } else {
280  ATH_MSG_ERROR("unable to call declareProperty on VarHandleKeyArray "
281  << name);
282  }
283 
284  return p;
285 
286  }

◆ declareProperty() [4/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
T &  property,
const std::string &  doc,
const SG::NotHandleType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
propertyObject holding the property value.
docDocumentation 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.

337  {
338  return PBASE::declareProperty(name, property, doc);
339  }

◆ declareProperty() [5/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
T &  property,
const std::string &  doc = "none" 
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
propertyObject holding the property value.
docDocumentation 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.

355  {
356  typedef typename SG::HandleClassifier<T>::type htype;
357  return declareProperty (name, property, doc, htype());
358  }

◆ declareProperty() [6/6]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > &  t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145  {
146  typedef typename SG::HandleClassifier<T>::type htype;
148  }

◆ detStore()

const ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

95 { return m_detStore; }

◆ evtStore() [1/2]

ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

85 { return m_evtStore; }

◆ evtStore() [2/2]

const ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( ) const
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 90 of file AthCommonDataStore.h.

90 { return m_evtStore; }

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase &  ExtraDeps)
protectedinherited

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()

void Muon::MuonNSWSegmentFinderTool::find ( const EventContext &  ctx,
SegmentMakingCache cache 
) const
overridevirtual

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.

283  {
284 
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");
290 
291  // Find segments using the MM strips as a seed
292  MuonSegmentVec out_segments{};
293  {
294  MuonSegmentVec stereoSegs = findStereoSegments(ctx, muonClusters, 0);
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()));
298  }
299 
300  // Push back mm seded segments and cache used hits
301  auto dump_output = [&]() {
302  cache.constructedSegs.reserve(cache.constructedSegs.size() + out_segments.size());
303  for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
304  for (const Trk::MeasurementBase* meas : seg->containedMeasurements()) {
305  const Muon::MuonClusterOnTrack* clus = dynamic_cast<const Muon::MuonClusterOnTrack*>(meas);
306  if (clus) cache.usedHits.insert(clus->identify());
307  }
308  cache.constructedSegs.push_back(std::move(seg));
309  }
310  };
311 
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) {
316  for (const Trk::MeasurementBase* meas : seg->containedMeasurements()) {
317  const Muon::MuonClusterOnTrack* clus = dynamic_cast<const Muon::MuonClusterOnTrack*>(meas);
318  if (clus) masked_segs[layerNumber(clus)].insert(clus->identify());
319  }
320  }
321 
322  // Create new vector of clusters excluding the ones used in the mm seeded segments
323  if (!out_segments.empty()) {
324  clustPostStereo.reserve(muonClusters.size());
325  for (const Muon::MuonClusterOnTrack* clus : muonClusters) {
326  if (!masked_segs[layerNumber(clus)].count(clus->identify())) clustPostStereo.push_back(clus);
327  }
328  }
329 
330  // If we did not find any mm seeded segments use the full hit vector to build stgc seeded segments
331  // otherwise use the ones that did not make it onto a segment yet
332  const std::vector<const Muon::MuonClusterOnTrack*>& segmentInput = !out_segments.empty() ? clustPostStereo : muonClusters;
333 
335  {
336  MuonSegmentVec etaSegs = findStgcPrecisionSegments(ctx, segmentInput);
337  ATH_MSG_VERBOSE("Found " << etaSegs.size() << " stgc seeded eta segments");
338  MuonSegmentVec precSegs = find3DSegments(ctx, segmentInput, etaSegs);
339  ATH_MSG_VERBOSE("Found " << precSegs.size() << " 3D segments");
340  out_segments.insert(out_segments.end(),
341  std::make_move_iterator(precSegs.begin()),
342  std::make_move_iterator(precSegs.end()));
343  }
344 
345 
346 
347  if (!cache.buildQuads) {
348  dump_output();
349  return;
350  }
352  for (std::unique_ptr<Muon::MuonSegment>& seg : out_segments) {
353  std::vector<const MuonClusterOnTrack*> seg_hits{};
354  seg_hits.reserve(seg->containedMeasurements().size());
355  for (const Trk::MeasurementBase* meas : seg->containedMeasurements()) {
356  const Muon::MuonClusterOnTrack* clus = dynamic_cast<const Muon::MuonClusterOnTrack*>(meas);
357  if (clus) seg_hits.push_back(clus);
358  }
360  for (int iWedge{1}; iWedge<=4 ; ++iWedge) {
361  MeasVec quad_hits = cleanClusters(seg_hits, HitType::Eta | HitType::Phi, 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();
370  Trk::Intersection intersect = surf.straightLineIntersection(seg->globalPosition(), seg->globalDirection(), false, false);
371  const Amg::Vector3D& gpos_seg = intersect.position;
372  Amg::Vector3D gdir_seg{seg->globalDirection()};
373  Amg::Vector3D perpos = gpos_seg - 10 * gdir_seg.unit();
374  if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
375  Trk::Perigee startpar{perpos, gdir_seg, 0, perpos};
377  std::unique_ptr<Trk::Track> segtrack = fit(ctx, fit_meas, startpar);
378  if (!segtrack) continue;
379 
380  std::unique_ptr<MuonSegment> seg{m_trackToSegmentTool->convert(ctx, *segtrack)};
381  if (seg) {
382  ATH_MSG_VERBOSE(" adding new quad segment " << m_printer->print(*seg) << std::endl
383  <<"position: "<<to_string(seg->globalPosition())<< std::endl
384  <<"direction: "<<to_string(seg->globalDirection())<< std::endl
385  << m_printer->print(seg->containedMeasurements()));
386  seg->setAuthor(Trk::Segment::NswQuadAlign);
387  cache.quadSegs.emplace_back(std::move(seg));
388  }
389  }
390  }
391  dump_output();
392  }

◆ find3DSegments()

MuonSegmentVec Muon::MuonNSWSegmentFinderTool::find3DSegments ( const EventContext &  ctx,
const std::vector< const Muon::MuonClusterOnTrack * > &  MuonClusters,
std::vector< std::unique_ptr< Muon::MuonSegment >> &  etaSegs,
int  singleWedge = 0 
) const
private

1 - All micromega layers have ideally been consumed. Try the seeding from the phi wires.

Definition at line 581 of file MuonNSWSegmentFinderTool.cxx.

584  {
585  MuonSegmentVec segments{};
586  // cluster cleaning #1; select only phi hits (must be from all wedges, in order to phi-seed)
587 
588  ATH_MSG_DEBUG("Cleaning phi clusters in stgc seeded 3D segments ");
589  MeasVec phiClusters = cleanClusters(muonClusters, HitType::Phi | HitType::Wire, singleWedge);
590  ATH_MSG_DEBUG("After hit cleaning, there are " << phiClusters.size() << " phi clusters to be fit");
591 
592 
593  // classify the phi clusters by layer
594  LayerMeasVec orderedWireClusters = classifyByLayer(phiClusters, HitType::Wire);
595  LayerMeasVec orderedPadClusters = classifyByLayer(phiClusters, HitType::Pad); // pads only
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()));
599  return segments;
600  }
601 
602  // cluster cleaning #2; select only eta hits
603  ATH_MSG_DEBUG("Cleaning eta clusters in stgc seeded 3D segments ");
604  MeasVec etaClusters = cleanClusters(muonClusters, HitType::Eta, singleWedge);
605  LayerMeasVec orderedEtaClusters = classifyByLayer(etaClusters, HitType::Eta);
606 
607  // loop on eta segments
608  bool triedWireSeed{false}; // wire seeds need to be retrieved only once (the first time they are needed)
609  std::vector<NSWSeed> seeds_WiresSTGC;
610  TrackCollection segTrkColl{SG::OWN_ELEMENTS};
611  // Loop on eta segments
612  for (std::unique_ptr<Muon::MuonSegment>& etaSeg : etaSegs) {
613  bool is3Dseg{false};
614  NSWSeed seed2D{this, *etaSeg};
615  getClustersOnSegment(orderedEtaClusters, seed2D, {}); // eta clusters
616 
617  std::vector<NSWSeed> seeds;
620  if (std::abs(etaSeg->globalPosition().eta()) < 2.4) {
621  if (!triedWireSeed) {
622  // wire seeds need to be retrieved only once (they don't depend on the eta segment)
623  triedWireSeed = true;
624  seeds_WiresSTGC = segmentSeedFromStgc(orderedWireClusters, true);
625  }
626 
627  if (!seeds_WiresSTGC.empty()) {
628  seeds = seeds_WiresSTGC;
629  ATH_MSG_DEBUG(" Seeding from sTGC wires");
630  }
631  }
632 
633  // 3 - last resort, try sTGC pads
634  if (seeds.empty() ) {
635 
636  // only perform seeding with layers that have less than m_maxInputPads hits
637  LayerMeasVec orderedPadClustersForSeeding;
638  std::ranges::copy_if(orderedPadClusters,
639  std::back_inserter(orderedPadClustersForSeeding),
640  [this](const MeasVec& vec) { return vec.size() < m_maxInputPads; });
641 
642  seeds = segmentSeedFromPads(orderedPadClustersForSeeding, *etaSeg);
643  ATH_MSG_DEBUG(" Seeding from sTGC pads");
644  }
645 
646  // Loop on phi seeds
647  MeasVec phiHitVec;
648  const Trk::PlaneSurface& etaSegSurf = etaSeg->associatedSurface();
649  double etaSegLocX = etaSeg->localParameters()[Trk::locX];
650  double etaSegLocXZ = etaSeg->localDirection().angleXZ();
651 
652  for (NSWSeed& seed : seeds) {
653  // calculate start parameters for the fit
654  // combine the local position and direction of the eta-seed (segment)
655  // and local position and direction of the phi-seed to generate 3D starting parameters
656  Trk::Intersection intersect = etaSegSurf.straightLineIntersection(seed.pos(), seed.dir(), false, false);
657  Amg::Vector2D lpos_seed{Amg::Vector2D::Zero()};
658  Trk::LocalDirection ldir_seed{};
659  etaSegSurf.globalToLocal(intersect.position, intersect.position, lpos_seed);
660  etaSegSurf.globalToLocalDirection(seed.dir(), ldir_seed);
661 
662  Amg::Vector2D lpos_seg(etaSegLocX, lpos_seed[Trk::locY]);
663  Trk::LocalDirection ldir_seg(etaSegLocXZ, ldir_seed.angleYZ());
664 
665  Amg::Vector3D gpos_seg{Amg::Vector3D::Zero()}, gdir_seg{Amg::Vector3D::Zero()};
666  etaSegSurf.localToGlobal(lpos_seg, gpos_seg, gpos_seg);
667  etaSegSurf.localToGlobalDirection(ldir_seg, gdir_seg);
668 
669  Amg::Vector3D perpos = gpos_seg - 10 * gdir_seg.unit();
670  if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
671  const Trk::Perigee startpar{perpos, gdir_seg, 0, perpos};
672 
673  NSWSeed seed3D{this, perpos, gdir_seg};
674 
675  // gather phi hits aligned with the segment
676  int nPhiHits = getClustersOnSegment(orderedPadClusters, seed3D,{}); // add pad hits (from the requested wedge if any)
677  nPhiHits += getClustersOnSegment(orderedWireClusters, seed3D, {}); // add wire hits (from the requested wedge if any)
678  if (nPhiHits < 2) continue; // at least two phi hits
679 
680  MeasVec phiHitVec = seed3D.measurements();
681  // calibrate the eta hits
682  MeasVec etaHitsCalibrated = getCalibratedClusters(seed2D);
683 
684  // fit
685  if (hitsToTrack(ctx, etaHitsCalibrated, phiHitVec, startpar, segTrkColl)) {
686  is3Dseg = true;
687  ATH_MSG_VERBOSE("Segment successfully fitted for wedge "<<singleWedge<<std::endl<<
688  m_printer->print(*segTrkColl.back()));
689  }
690  } // end loop on phi seeds
691 
692  // if we failed to combine the eta segment with phi measurements,
693  // just add the eta segment to the collection.
694  if (!is3Dseg) { segments.push_back(std::move(etaSeg)); }
695  } // end loop on precision plane segments
696  MuonSegmentVec new_segs = resolveAmbiguities(ctx, segTrkColl, Trk::Segment::NswStgcSeeded);
697  segments.insert(segments.end(), std::make_move_iterator(new_segs.begin()), std::make_move_iterator(new_segs.end()));
698  return segments;
699  }

◆ findStereoSegments()

MuonSegmentVec Muon::MuonNSWSegmentFinderTool::findStereoSegments ( const EventContext &  ctx,
const std::vector< const Muon::MuonClusterOnTrack * > &  allClusts,
int  singleWedge = 0 
) const
private

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
ctxEventContext
allClustsCollection of all EventContext objects
singleWedge0 (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.

395  {
396 
397  if (!m_useStereoSeeding){
398  ATH_MSG_VERBOSE("MMStereoSeeding disabled!");
399  return {};
400  }
401 
402  ATH_MSG_VERBOSE("Running MMStereoSeeding");
404  LayerMeasVec orderedClust =
405  classifyByLayer(cleanClusters(allClusts, HitType::Eta | HitType::Phi, singleWedge), HitType::Wire | HitType::Pad);
406 
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(); }),
410  orderedClust.end());
411  if (orderedClust.empty()) return {};
412 
413 
414  std::vector<NSWSeed> seeds = segmentSeedFromMM(orderedClust);
415  ATH_MSG_DEBUG("Retrieved " << seeds.size() << " seeds in the MMStereoAlg after the ambiguity resolution" );
416 
417  if (seeds.empty()) return {};
420  for (NSWSeed& seed : seeds) {
423  std::vector<const Trk::MeasurementBase*> fit_meas{};
424 
425  std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{ipConstraint(ctx)};
426  if (pseudoVtx) fit_meas.push_back(pseudoVtx.get());
427  MeasVec calib_clust = getCalibratedClusters(seed);
428  std::copy(calib_clust.begin(), calib_clust.end(), std::back_inserter(fit_meas));
430  const Trk::Surface& surf = calib_clust.front()->associatedSurface();
431 
432  Trk::Intersection intersect = surf.straightLineIntersection(seed.pos(), seed.dir(), false, false);
433  const Amg::Vector3D& gpos_seg = intersect.position;
434  Amg::Vector3D gdir_seg{seed.dir()};
435  Amg::Vector3D perpos = gpos_seg - 10 * gdir_seg.unit();
436  if (perpos.dot(gdir_seg) < 0) gdir_seg *= -1;
437 
438  Trk::Perigee startpar{perpos, gdir_seg, 0, perpos};
439 
441  std::unique_ptr<Trk::Track> segtrack = fit(ctx, fit_meas, startpar);
442  if (segtrack) trackSegs.push_back(std::move(segtrack));
443  }
444  return resolveAmbiguities(ctx, trackSegs, Trk::Segment::Author::NswStereoSeeded);
445  }

◆ 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.

480  {
481 
482  if (!m_usesTGCSeeding){
483  ATH_MSG_VERBOSE("2D sTGC seeding disabled!");
484  return {};
485  }
486 
487  ATH_MSG_VERBOSE("Running 2D sTGC seeding");
488 
489 
490  // clean the muon clusters; select only the eta hits.
491  // in single-wedge mode the eta seeds are retrieved from the specific wedge
492 
493  ATH_MSG_DEBUG("Cleaning eta clusters in stgc seeded 2D segments ");
494  MeasVec clusters = cleanClusters(muonClusters, HitType::Eta, singleWedge); // eta hits only
495  ATH_MSG_VERBOSE(" After hit cleaning, there are " << clusters.size() << " precision 2D clusters");
496 
497  // classify eta clusters by layer
498  LayerMeasVec orderedClusters = classifyByLayer(clusters, 0);
499 
500  if (orderedClusters.size() < 4) return {}; // at least four layers with eta hits (MM and sTGC)
501 
502  // create segment seeds
503  std::vector<NSWSeed> seeds = segmentSeedFromStgc(orderedClusters, false);
504  ATH_MSG_DEBUG(" Found " << seeds.size() << " 2D seeds");
505  // Loop on seeds: find all clusters near the seed and try to fit
506  MeasVec etaHitVec, phiHitVec;
507  TrackCollection segTrkColl{SG::OWN_ELEMENTS};
508 
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)");
512  continue;
513  }
514 
515  etaHitVec = seed.measurements();
516  const Trk::PlaneSurface& surf = static_cast<const Trk::PlaneSurface&>(etaHitVec.front()->associatedSurface());
517  // calculate start parameters for the fit
518  // local position and direction of the eta-seed on the surface of the first cluster
519  Trk::Intersection intersect = surf.straightLineIntersection(seed.pos(), seed.dir(), false, false);
520  Amg::Vector2D lpos_seed{Amg::Vector2D::Zero()};
521  Trk::LocalDirection ldir_seed{};
522  surf.globalToLocal(intersect.position, intersect.position, lpos_seed);
523  surf.globalToLocalDirection(seed.dir(), ldir_seed);
524 
525  // use the seed info to generate start parameters (dummy values for phi)
526  Amg::Vector2D lpos(lpos_seed[Trk::locX], 0.);
527  Trk::LocalDirection ldir(ldir_seed.angleXZ(), -M_PI_2);
528  Amg::Vector3D gpos_seg{Amg::Vector3D::Zero()}, gdir_seg{Amg::Vector3D::Zero()};
529  surf.localToGlobal(lpos, gpos_seg, gpos_seg);
530  surf.localToGlobalDirection(ldir, gdir_seg);
531 
532  Amg::Vector3D perpos = gpos_seg - 10 * gdir_seg.unit();
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());
537 
538  // fit the hits
539  hitsToTrack(ctx, etaHitVec, phiHitVec, startpar, segTrkColl);
540  }
542  return resolveAmbiguities(ctx, segTrkColl, Trk::Segment::Author::NswStgcSeeded);
543  }

◆ fit()

std::unique_ptr< Trk::Track > Muon::MuonNSWSegmentFinderTool::fit ( const EventContext &  ctx,
const std::vector< const Trk::MeasurementBase * > &  fit_meas,
const Trk::TrackParameters perigee 
) const
private

Definition at line 447 of file MuonNSWSegmentFinderTool.cxx.

449  {
450  ATH_MSG_DEBUG("Fit segment from (" << to_string(perigee.position())<< " pointing to " <<
451  to_string(perigee.momentum())<<". Contained measurements in candidate: " << std::endl
452  << m_printer->print(fit_meas));
453  std::unique_ptr<Trk::Track> segtrack = m_slTrackFitter->fit(ctx, fit_meas, perigee, false, Trk::nonInteracting);
454  if (!segtrack) {
455  ATH_MSG_DEBUG("Fit failed");
456  return nullptr;
457  }
458  ATH_MSG_VERBOSE("--> Fit succeeded");
459  std::unique_ptr<Trk::Track> cleanedTrack = m_trackCleaner->clean(*segtrack, ctx);
460  if (cleanedTrack && cleanedTrack->perigeeParameters() != segtrack->perigeeParameters()) { segtrack.swap(cleanedTrack); }
461  // quality criteria
462  if (!m_edmHelperSvc->goodTrack(*segtrack, 10)) {
463  if (segtrack->fitQuality()) {
464  ATH_MSG_DEBUG("Segment fit with chi^2/nDoF = " << segtrack->fitQuality()->chiSquared() << "/"
465  << segtrack->fitQuality()->numberDoF());
466  }
467  return nullptr;
468  }
469  // update the track summary and add the track to the collection
470  m_trackSummary->updateTrack(ctx, *segtrack);
471  ATH_MSG_DEBUG("Segment accepted with chi^2/nDoF = " << segtrack->fitQuality()->chiSquared() << "/"
472  << segtrack->fitQuality()->numberDoF());
473  return segtrack;
474  }

◆ getCalibratedClusters()

MeasVec Muon::MuonNSWSegmentFinderTool::getCalibratedClusters ( NSWSeed seed) const
private

Definition at line 1540 of file MuonNSWSegmentFinderTool.cxx.

1540  {
1541 
1542  MeasVec calibratedClusters;
1543  MeasVec clusters = seed.measurements();
1544 
1545  // loop on the segment clusters and use the phi of the seed to correct them
1546  for (const SeedMeasurement& clus : clusters) {
1547  std::unique_ptr<const Muon::MuonClusterOnTrack> newClus;
1548 
1549  // get the intercept of the seed direction with the cluster surface
1550  const Identifier hitID = clus->identify();
1551  const Trk::Surface& surf = clus->associatedSurface();
1552  Trk::Intersection intersect = surf.straightLineIntersection(seed.pos(), seed.dir(), false, false);
1553 
1554  if (m_idHelperSvc->isMM(hitID)) {
1555  // build a new MM cluster on track with correct position
1556  std::unique_ptr<const Muon::MuonClusterOnTrack> newClus {m_muonClusterCreator->correct(*clus->prepRawData(), intersect.position, seed.dir())};
1557  calibratedClusters.emplace_back(seed.newCalibClust(std::move(newClus)));
1558  } else if (m_idHelperSvc->issTgc(hitID)) {
1559  // build a new sTGC cluster on track with correct position
1560  std::unique_ptr<const Muon::MuonClusterOnTrack> newClus {m_muonClusterCreator->correct(*clus->prepRawData(), intersect.position, seed.dir())};
1561  calibratedClusters.emplace_back(seed.newCalibClust(std::move(newClus)));
1562  }
1563  }
1564 
1565  return calibratedClusters;
1566  }

◆ getClustersOnSegment()

int Muon::MuonNSWSegmentFinderTool::getClustersOnSegment ( const LayerMeasVec orderedclusters,
NSWSeed seed,
const std::set< unsigned int > &  exclude,
bool  useStereo = true 
) const
private

Definition at line 960 of file MuonNSWSegmentFinderTool.cxx.

961  {
962  ATH_MSG_VERBOSE(" getClustersOnSegment: layers " << orderedclusters.size());
963  int nHitsAdded{0};
964 
965  for (const MeasVec& surfHits : orderedclusters) {
966  if (exclude.count(layerNumber(surfHits[0]))) continue;
967  // get the best hit candidate on this layer
968 
969  for (const SeedMeasurement& hit : surfHits) {
970 
971  const Identifier id = hit->identify();
972  const MuonGM::MuonChannelDesign* design = getDesign(hit);
973 
974  //In case of the 2D eta stgc seeding we don't want the MMG stereo hits on the segment
975  if ( !useStereo && m_idHelperSvc->isMM(id) && design->hasStereoAngle() ) continue;
976 
977  nHitsAdded += seed.add(hit, m_maxClustDist);
978  }
979  }
980  ATH_MSG_VERBOSE(" getClustersOnSegment: returning " << nHitsAdded << " hits ");
981  return nHitsAdded;
982  }

◆ 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.

1441  {
1442  // 'pads' contains segment hit candidates, classified in four layers (IP or HO).
1443  // Layers are ordered; for IP, the layer with hits that is nearest to
1444  // the IP is first, while for HO, the one furthest from the IP is first.
1445 
1446  std::vector<std::vector<double>> padsPhiL, padsPhiR;
1447  std::vector<double> padsPhiC;
1448 
1449  // Loop on layers
1450  for (const std::vector<const Muon::sTgcPrepData*>& surfHits : pads) {
1451  // Loop on layer hits
1452  std::vector<double> surfPadsPhiL, surfPadsPhiR;
1453  for (const Muon::sTgcPrepData* prd : surfHits) {
1454  const Identifier id = prd->identify();
1455  const MuonGM::MuonPadDesign* design = prd->detectorElement()->getPadDesign(id);
1456  if (!design) {
1457  ATH_MSG_WARNING("No design available for " << m_idHelperSvc->toString(id));
1458  continue;
1459  }
1460 
1461  // Phi boundaries of this pad in local coordinates
1462  const double halfWidthX = 0.5 * design->channelWidth(prd->localPosition(), true);
1463  const double hitPadX = prd->localPosition().x(); // x is in the phi direction
1464 
1465  // Reject hit candidates on pads too close (in phi) to any pad kept so far
1466  // (pad fuzziness) to constrain the number of combinations.
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();
1470 
1471  if (samePhi) continue;
1472 
1473  // Store the new pad candidate
1474  surfPadsPhiL.push_back(hitPadX - halfWidthX);
1475  surfPadsPhiR.push_back(hitPadX + halfWidthX);
1476  padsPhiC.push_back(hitPadX);
1477  ATH_MSG_DEBUG(" keep pad id " << m_idHelperSvc->toString(id) << " local x: " << hitPadX << " width: " << halfWidthX);
1478  }
1479 
1480  padsPhiL.push_back(std::move(surfPadsPhiL));
1481  padsPhiR.push_back(std::move(surfPadsPhiR));
1482  }
1483 
1484  unsigned int nSurf = padsPhiR.size();
1485 
1486  // number of combinations we can make out of pads in different layers
1487  // we want to keep combinations of overlapping pads.
1488  unsigned int nCombos{1};
1489  for (const std::vector<double>& surfPadsPhiR : padsPhiR) {
1490  if (!surfPadsPhiR.empty()) nCombos *= surfPadsPhiR.size();
1491  }
1492 
1493  std::vector<std::pair<double, double>> phiOverlap;
1494  phiOverlap.reserve(nCombos);
1495 
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();
1501  N /= nSurfHits;
1502 
1503  for (unsigned int icombo{0}; icombo < nCombos; ++icombo) {
1504  // index of the pad that corresponds to this combination
1505  unsigned int padIdx = (icombo / N) % nSurfHits;
1506  if (isurf == 0) {
1507  // first surface: just add the range of each hit pad
1508  phiOverlap.emplace_back(padsPhiL[isurf][padIdx], padsPhiR[isurf][padIdx]);
1509  } else {
1510  // subsequent surfaces: use staggering to narrow the phi ranges
1511  phiOverlap[icombo].first = std::max(padsPhiL[isurf][padIdx], phiOverlap[icombo].first);
1512  phiOverlap[icombo].second = std::min(padsPhiR[isurf][padIdx], phiOverlap[icombo].second);
1513  }
1514  }
1515  }
1516 
1517  // delete bad combinations with xmin > xmax (indicates non overlapping pads)
1518  phiOverlap.erase(std::remove_if(phiOverlap.begin(), phiOverlap.end(),
1519  [](std::pair<double, double>& range) { return range.first >= range.second; }),
1520  phiOverlap.end());
1521  ATH_MSG_DEBUG("Pad seeding - #combinations initial: " << nCombos
1522  << ", after cleaning for non overlapping pads: " << phiOverlap.size());
1523 
1524  } else {
1525  // in case combinations are too many, store the phi ranges of individual pads
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]);
1530  }
1531  }
1532  ATH_MSG_DEBUG("Pad seeding - #combinations: " << nCombos << " is too large. Seeding from" << phiOverlap.size()
1533  << " individual pads.");
1534  }
1535 
1536  return phiOverlap;
1537  }

◆ hitsToTrack()

bool Muon::MuonNSWSegmentFinderTool::hitsToTrack ( const EventContext &  ctx,
const MeasVec etaHitVec,
const MeasVec phiHitVec,
const Trk::TrackParameters startpar,
TrackCollection segTrkColl 
) const
private

Definition at line 741 of file MuonNSWSegmentFinderTool.cxx.

745  {
746  // vector of hits for the fit
747  std::vector<const Trk::MeasurementBase*> vecFitPts;
748  unsigned int nHitsEta = etaHitVec.size();
749  unsigned int nHitsPhi = phiHitVec.size();
750  vecFitPts.reserve(nHitsEta + nHitsPhi + 2 + m_ipConstraint + m_caloConstraint);
751 
752  std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudoVtx{ipConstraint(ctx)},
753  pseudoVtxCalo{caloConstraint(startpar)},
754  pseudoPhi1{nullptr}, pseudoPhi2{nullptr};
755  // is chosen, add a pseudo measurement as vtx at the center of ATLAS
756  if (pseudoVtx) { vecFitPts.push_back(pseudoVtx.get()); }
757  if (pseudoVtxCalo) { vecFitPts.push_back(pseudoVtxCalo.get()); }
758 
759  if (!nHitsPhi) {
760  // generate two pseudo phi measurements for the fit,
761  // one on the first hit surface and one on the last hit surface.
762 
763  Amg::MatrixX cov(1, 1);
764  constexpr double pseudoPrecision = 100 * Gaudi::Units::micrometer;
765  cov(0, 0) = pseudoPrecision;
766  static const Trk::LocalParameters loc_pseudopars{Trk::DefinedParameter(0, Trk::locY)};
767  pseudoPhi1 = std::make_unique<Trk::PseudoMeasurementOnTrack>(Trk::LocalParameters(loc_pseudopars),
768  Amg::MatrixX(cov),
769  etaHitVec.front()->associatedSurface());
770  pseudoPhi2 = std::make_unique<Trk::PseudoMeasurementOnTrack>(Trk::LocalParameters(loc_pseudopars),
771  Amg::MatrixX(cov),
772  etaHitVec.back()->associatedSurface());
773 
774  // add the first pseudo phi hit, the hit vector, and the second pseudo phi hit
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");
779 
780  } else {
781  // sorted eta and sorted phi hits combined (sorted by their the z-coordinate)
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());
786  return z1 < z2;
787  });
788  ATH_MSG_DEBUG("Fitting a 3D-segment track with " << nHitsEta << " Eta hits and " << nHitsPhi << " Phi hits");
789  }
790 
791  // fit the hits and generate the Trk::Track
792  std::unique_ptr<Trk::Track> segtrack = fit(ctx, vecFitPts, startpar);
793  if (!segtrack) return false;
794  segTrkColl.push_back(std::move(segtrack));
795  return true;
796  }

◆ idHelper()

const IMuonIdHelperSvc * Muon::MuonNSWSegmentFinderTool::idHelper ( ) const

Definition at line 281 of file MuonNSWSegmentFinderTool.cxx.

281 { return m_idHelperSvc.get(); }

◆ initialize()

StatusCode Muon::MuonNSWSegmentFinderTool::initialize ( )
overridevirtual

Definition at line 262 of file MuonNSWSegmentFinderTool.cxx.

262  {
263  ATH_CHECK(m_slTrackFitter.retrieve());
264  ATH_CHECK(m_printer.retrieve());
265  ATH_CHECK(m_edmHelperSvc.retrieve());
266  ATH_CHECK(m_ambiTool.retrieve());
267  ATH_CHECK(m_trackToSegmentTool.retrieve());
268  ATH_CHECK(m_idHelperSvc.retrieve());
269  ATH_CHECK(m_trackCleaner.retrieve());
270  ATH_CHECK(m_trackSummary.retrieve());
271  ATH_CHECK(m_muonClusterCreator.retrieve());
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;
276  }
277  ATH_MSG_DEBUG(" Max cut " << m_maxClustDist);
278  return StatusCode::SUCCESS;
279  }

◆ inputHandles()

virtual std::vector<Gaudi::DataHandle*> AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

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.

22  {
23  static const InterfaceID IID_IMuonNSWSegmentFinderTool("Muon::IMuonNSWSegmentFinderTool", 1, 0);
24  return IID_IMuonNSWSegmentFinderTool;
25  }

◆ ipConstraint()

std::unique_ptr< Trk::PseudoMeasurementOnTrack > Muon::MuonNSWSegmentFinderTool::ipConstraint ( const EventContext &  ctx) const
private

creates the IP constraint

Beamspot constraint?

Definition at line 718 of file MuonNSWSegmentFinderTool.cxx.

718  {
719  if (!m_ipConstraint) return nullptr;
720  constexpr double errVtx{10.*Gaudi::Units::cm};
721  Amg::MatrixX covVtx(1, 1);
722  covVtx(0, 0) = errVtx * errVtx;
725  return std::make_unique<Trk::PseudoMeasurementOnTrack>(Trk::LocalParameters(Trk::DefinedParameter(0, Trk::locX)), std::move(covVtx),
726  std::move(perVtx));
727  }

◆ isPad()

bool Muon::MuonNSWSegmentFinderTool::isPad ( const Muon::MuonClusterOnTrack clust) const

Definition at line 728 of file MuonNSWSegmentFinderTool.cxx.

728  {
729  const Identifier id = clust->identify();
730  return m_idHelperSvc->issTgc(id) && m_idHelperSvc->stgcIdHelper().channelType(id) == sTgcIdHelper::Pad;
731  }

◆ isStrip()

bool Muon::MuonNSWSegmentFinderTool::isStrip ( const Muon::MuonClusterOnTrack clust) const

Definition at line 732 of file MuonNSWSegmentFinderTool.cxx.

732  {
733  const Identifier id = clust->identify();
734  return m_idHelperSvc->issTgc(id) && m_idHelperSvc->stgcIdHelper().channelType(id) == sTgcIdHelper::Strip;
735  }

◆ isWire()

bool Muon::MuonNSWSegmentFinderTool::isWire ( const Muon::MuonClusterOnTrack clust) const

Definition at line 736 of file MuonNSWSegmentFinderTool.cxx.

736  {
737  const Identifier id = clust->identify();
738  return m_idHelperSvc->issTgc(id) && m_idHelperSvc->stgcIdHelper().channelType(id) == sTgcIdHelper::Wire;
739  }

◆ layerNumber()

int Muon::MuonNSWSegmentFinderTool::layerNumber ( const Muon::MuonClusterOnTrack cluster) const

Definition at line 943 of file MuonNSWSegmentFinderTool.cxx.

943  {
944  // Internal logic. Initialize with 16 layers:
945  // [0-3] for the four sTGC IP layers
946  // [4-11] for the eight MM IP+HO layers (empty when phi hits are requested)
947  // [12-15] for the four sTGC HO layers
948  int layer{0};
949  if (m_idHelperSvc->isMM(cluster->identify())) layer = m_idHelperSvc->mmIdHelper().gasGap(cluster->identify());
950  if (m_idHelperSvc->issTgc(cluster->identify())) layer = m_idHelperSvc->stgcIdHelper().gasGap(cluster->identify());
951  return 4 * (wedgeNumber(cluster) - 1) + layer - 1;
952  }

◆ msg() [1/2]

MsgStream& AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24  {
25  return this->msgStream();
26  }

◆ msg() [2/2]

MsgStream& AthCommonMsg< AlgTool >::msg ( const MSG::Level  lvl) const
inlineinherited

Definition at line 27 of file AthCommonMsg.h.

27  {
28  return this->msgStream(lvl);
29  }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level  lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30  {
31  return this->msgLevel(lvl);
32  }

◆ outputHandles()

virtual std::vector<Gaudi::DataHandle*> AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

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.

1592  {
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);
1599  ++lay;
1600  }
1601  return sstr.str();
1602  }

◆ print() [2/3]

std::string Muon::MuonNSWSegmentFinderTool::print ( const MeasVec clusters) const

Definition at line 1585 of file MuonNSWSegmentFinderTool.cxx.

1585  {
1586  std::stringstream sstr{};
1587  for (const SeedMeasurement& cl : measurements){
1588  sstr<<" *** "<<print(cl)<<std::endl;
1589  }
1590  return sstr.str();
1591  }

◆ print() [3/3]

std::string Muon::MuonNSWSegmentFinderTool::print ( const SeedMeasurement meas) const

Definition at line 1578 of file MuonNSWSegmentFinderTool.cxx.

1578  {
1579  std::stringstream sstr{};
1580  sstr << m_idHelperSvc->toString(cl->identify()) << " at " <<to_string(cl.pos())
1581  <<" pointing to (" <<to_string(cl.dir())<<" cluster size: "<<clusterSize(cl);
1582 
1583  return sstr.str();
1584  }

◆ printSeed()

template<size_t N>
std::string Muon::MuonNSWSegmentFinderTool::printSeed ( const std::array< SeedMeasurement, N > &  seed) const

Definition at line 1570 of file MuonNSWSegmentFinderTool.cxx.

1570  {
1571  std::stringstream sstr{};
1572  sstr << std::endl;
1573  for (const SeedMeasurement& cl : seed) sstr << " *** " << print(cl) << std::endl;
1574  return sstr.str();
1575  }

◆ renounce()

std::enable_if_t<std::is_void_v<std::result_of_t<decltype(&T::renounce)(T)> > && !std::is_base_of_v<SG::VarHandleKeyArray, T> && std::is_base_of_v<Gaudi::DataHandle, T>, void> AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T &  h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381  {
382  h.renounce();
383  PBASE::renounce (h);
384  }

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364  {
365  handlesArray.renounce();
366  }

◆ resolveAmbiguities() [1/2]

MuonSegmentVec Muon::MuonNSWSegmentFinderTool::resolveAmbiguities ( const EventContext &  ctx,
const TrackCollection segColl,
const Trk::Segment::Author  a 
) const
private

Definition at line 544 of file MuonNSWSegmentFinderTool.cxx.

546  {
547  if (msgLvl(MSG::DEBUG)) {
548  ATH_MSG_DEBUG("Tracks before ambi solving: ");
549  for (const Trk::Track* trk : segTrkColl) {
550  ATH_MSG_DEBUG(m_printer->print(*trk));
551  const DataVector<const Trk::MeasurementBase>* meas = trk->measurementsOnTrack();
552  if (meas) ATH_MSG_DEBUG(m_printer->print(meas->stdcont()));
553  }
554  }
555 
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());
559 
560  // store the resolved segments
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(),
564  [this](const Trk::MeasurementBase* meas) {
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;
569  std::unique_ptr<MuonSegment> seg{m_trackToSegmentTool->convert(ctx, *trk)};
570  if (seg) {
571  ATH_MSG_DEBUG(" adding " << m_printer->print(*seg) << std::endl << m_printer->print(seg->containedMeasurements()));
572  seg->setAuthor(a);
573  segments.emplace_back(std::move(seg));
574  } else {
575  ATH_MSG_VERBOSE("Segment conversion failed, no segment created. ");
576  }
577  }
578  return segments;
579  }

◆ resolveAmbiguities() [2/2]

std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::resolveAmbiguities ( std::vector< NSWSeed > &&  unresolved) const
private

Definition at line 1414 of file MuonNSWSegmentFinderTool.cxx.

1414  {
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();
1419  });
1420  for (NSWSeed& seed : unresolved) {
1421  bool add_seed{true};
1422  for (NSWSeed& good : seeds) {
1423  NSWSeed::SeedOR ov = good.overlap(seed);
1424  if (ov == NSWSeed::SeedOR::SubSet) {
1425  std::swap(seed, good);
1426  add_seed = false;
1427  break;
1428  } else if (ov == NSWSeed::SeedOR::Same || ov == NSWSeed::SeedOR::SuperSet) {
1429  add_seed = false;
1430  break;
1431  }
1432  }
1433  if (add_seed) seeds.push_back(std::move(seed));
1434  }
1435  ATH_MSG_VERBOSE(seeds.size()<<" out of "<<unresolved.size()<<" passed the overlap removal");
1436  return seeds;
1437  }

◆ segmentSeedFromMM() [1/2]

std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::segmentSeedFromMM ( const LayerMeasVec orderedClusters) const
private

layers 12-15 contain stgcs and are not of interest...

Combinatorics debugging stream

Definition at line 1122 of file MuonNSWSegmentFinderTool.cxx.

1123  {
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;
1130 
1132  std::stringstream sstr{};
1133  for (int e4 = std::min(lastMMLay, orderedClusters.size() -1); e4 >= 3 ; --e4) {
1134  layers[3] = e4;
1135  for (int e3 = e4 -1 ; e3 >= 2; --e3) {
1136  layers[2] = e3;
1137  for (int e2 = 1 ; e2 < e3; ++e2) {
1138  layers[1] = e2;
1139  for (int e1= 0; e1< e2; ++e1) {
1140  layers[0] = e1;
1141  const unsigned int old_trials = trials;
1142  laySeeds = segmentSeedFromMM(orderedClusters,layers, trials);
1143  if (old_trials == trials) continue;
1144 
1145  used_layers += !laySeeds.empty();
1146  seeds.insert(seeds.end(), std::make_move_iterator(laySeeds.begin()),
1147  std::make_move_iterator(laySeeds.end()));
1148 
1149  if (msgLvl(MSG::VERBOSE)) {
1150  sstr<<" Attempts thus far "<<old_trials<<" attempts now "<<trials<<" --- "<<e1<<","<<e2<<","<<e3<<","<<e4<<std::endl;
1151  for (int lay : layers) {
1152  sstr<<"Layer: "<<lay<<" number of measurements "<<orderedClusters[lay].size()<<std::endl;
1153  for (const SeedMeasurement& meas : orderedClusters[lay] ){
1154  sstr<<" **** "<< print(meas)<<std::endl;
1155  }
1156  sstr<<std::endl<<std::endl<<std::endl;
1157  }
1158  }
1159  }
1160  }
1161  }
1162  }
1163  if (trials > 100000) {
1164  ATH_MSG_VERBOSE(sstr.str());
1165  }
1166  ATH_MSG_VERBOSE("Out of "<<trials<<" possible seeds, "<<seeds.size()<<" were finally built. Used in total "<<used_layers<<" layers");
1167  return resolveAmbiguities(std::move(seeds));
1168  }

◆ 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.

1175  {
1176  std::vector<NSWSeed> seeds{};
1177 
1178  std::array<unsigned int, 4> lay_ord{};
1179  for (size_t s = 0; s < selLayers.size(); ++s) {
1180  unsigned int lay = selLayers[s];
1181  const SeedMeasurement& seed = orderedClusters[lay].front();
1182  const Identifier id = seed->identify();
1183  if (!m_idHelperSvc->isMM(id)) return seeds;
1184  const MuonGM::MuonChannelDesign* design = getDesign(seed);
1186  if (!design->hasStereoAngle()) lay_ord[s] = 1;
1187  else if (design->stereoAngle() >0.) lay_ord[s] = 2;
1188  else lay_ord[s] = 3;
1189  }
1190  auto swap_strips = [&selLayers, &lay_ord] (unsigned int i, unsigned j){
1191  std::swap(lay_ord[i], lay_ord[j]);
1192  std::swap(selLayers[i],selLayers[j]);
1193  };
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);
1198  else {
1199  ATH_MSG_VERBOSE("Strips are all parallel.");
1200  return seeds;
1201  }
1202  }
1204  if (lay_ord[2] == lay_ord[3]) {
1205  // Check if the last hit can be exchanged by the first one.
1206  // But also ensure that the second and fourth are not the same
1207  if (lay_ord[3] != lay_ord[0] && lay_ord[3] != lay_ord[1]) swap_strips(3,0);
1208  else {
1209  ATH_MSG_VERBOSE("No way to rearrange the strips such that the latter two strips cross.");
1210  return seeds;
1211  }
1212  }
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();
1218  }
1219 
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());
1223 
1224  AmgSymMatrix(2) diamond{AmgSymMatrix(2)::Zero()};
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);
1227 
1228  if (std::abs(diamond.determinant()) < std::numeric_limits<float>::epsilon()) {
1229  ATH_MSG_VERBOSE(" The seed built from " << printSeed(base_seed) << " cannot constrain phi as " << std::endl
1230  << diamond << std::endl
1231  << " is singular " << diamond.determinant() << " with rank "
1232  << (Eigen::FullPivLU<AmgSymMatrix(2)>{diamond}.rank()));
1233 
1234  return seeds;
1235  }
1236  ATH_MSG_VERBOSE("The combination of " << printSeed(base_seed) << " to " << std::endl
1237  << diamond << std::endl
1238  << "May give a couple of stereo seeds " << diamond.determinant());
1239 
1241  const AmgSymMatrix(2) seed_builder = diamond.inverse();
1243  const double KmG = K-G;
1244  const double KmA = K-A;
1245  const double AmG = A-G;
1246 
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]);
1251 
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);
1257 
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())
1262  .block<2, 1>(0, 0);
1263 
1264  const AmgVector(2) sol_pars = seed_builder * centers;
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]};
1267  bool accept{true};
1268  ATH_MSG_VERBOSE("Check intersections of "<<printSeed(base_seed));
1269  constexpr double tolerance = 10.* Gaudi::Units::mm;
1270  std::optional<Amg::Vector3D> seg_pos{std::nullopt}, seg_dir{std::nullopt};
1271  for (unsigned int i = 0; i < base_seed.size(); ++i) {
1272  const MuonGM::MuonChannelDesign* design = getDesign(base_seed[i]);
1273  const double halfLength = design->channelHalfLength(channel(base_seed[i]), true);
1274  accept &= (halfLength + tolerance > std::abs(lengths[i]));
1275  if (msgLvl(MSG::VERBOSE)) {
1276  if (!seg_pos) {
1277  seg_pos = std::make_optional<Amg::Vector3D>(base_seed[0].pos() +
1278  lengths[0] * base_seed[0].dir());
1279  ATH_MSG_VERBOSE("Position "<<to_string(*seg_pos));
1280  }
1281  if (!seg_dir){
1282  seg_dir = std::make_optional<Amg::Vector3D>((base_seed[1].pos() +
1283  lengths[1] *base_seed[1].dir() - (*seg_pos)).unit());
1284  ATH_MSG_VERBOSE("Direction "<<to_string(*seg_dir));
1285  }
1286  std::optional<double> mu_crossing = Amg::intersect<3>(*seg_pos, *seg_dir, base_seed[i].pos(),base_seed[i].dir());
1287  ATH_MSG_VERBOSE(" ----- "<<(i+1)<<" at "<<to_string(base_seed[i].pos() + lengths[i]*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;
1291  }
1292  if (!accept) return std::nullopt;
1293  return std::make_optional<std::array<double,2>>({lengths[0], lengths[1]});
1294  };
1295 
1297  seeds.reserve(200);
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()};
1301 
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()};
1305 
1306  for (const SeedMeasurement& lay1 : orderedClusters[selLayers[0]]) {
1307  base_seed[0] = lay1;
1308  for (MeasVec::const_iterator lay2 = begin2; lay2 != end2; ++lay2) {
1309 
1310  base_seed[1] = *lay2;
1311  ChannelConstraint chCheck = compatiblyFromIP(lay1, *lay2);
1314  if (chCheck == ChannelConstraint::TooNarrow) {
1315  begin2 = lay2 + 1;
1316  continue;
1317  }
1319  else if (chCheck == ChannelConstraint::TooWide) {
1320  break;
1321  }
1323  for (MeasVec::const_iterator lay3 = begin3; lay3 != end3; ++lay3) {
1324  chCheck = compatiblyFromIP(lay1, *lay3);
1325  const ChannelConstraint chCheck1 = compatiblyFromIP(*lay2, *lay3);
1326  if (chCheck == ChannelConstraint::TooNarrow && chCheck1 == ChannelConstraint::TooNarrow) {
1327  begin3 = lay3 + 1;
1328  continue;
1329  } else if (chCheck == ChannelConstraint::TooWide && chCheck1 == ChannelConstraint::TooWide) {
1330  break;
1331  }
1332  base_seed[2] = *lay3;
1334  for (MeasVec::const_iterator lay4 = begin4 ; lay4 != end4; ++lay4) {
1335  chCheck = compatiblyFromIP(*lay3, *lay4);
1336  if (chCheck == ChannelConstraint::TooNarrow) {
1337  begin4 = lay4 + 1;
1338  continue;
1339  } else if (chCheck == ChannelConstraint::TooWide) {
1340  break;
1341  }
1342 
1343  base_seed[3] = (*lay4);
1344  std::optional<std::array<double, 2>> isects = estimate_muon();
1345  ++trial_counter;
1346  if (!isects) continue;
1347  NSWSeed seed{this, base_seed, *isects};
1348 
1349  if (seed.size() < 4) continue;
1350  if (m_ipConstraint) {
1351  const double eta = std::abs(seed.dir().eta());
1352  if (eta < minEtaNSW || eta > maxEtaNSW) {
1353  continue;
1354  }
1355  if (seed.dir().block<2,1>(0,0).dot(seed.pos().block<2,1>(0,0)) < 0.) continue;
1357  static const Muon::MuonSectorMapping sector_mapping{};
1358  const double deltaPhi = std::abs(seed.dir().deltaPhi(seed.pos()));
1359  if (deltaPhi > sector_mapping.sectorWidth(m_idHelperSvc->sector(base_seed[0]->identify()))) continue;
1360  }
1361  getClustersOnSegment(orderedClusters, seed, {selLayers[0], selLayers[1],selLayers[2], selLayers[3]});
1362  seeds.emplace_back(std::move(seed));
1363  }
1364  }
1365  }
1366  }
1367  return seeds;
1368  }

◆ segmentSeedFromPads()

std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::segmentSeedFromPads ( const LayerMeasVec orderedClusters,
const Muon::MuonSegment etaSeg 
) const
private

Do not run an empty container

Definition at line 985 of file MuonNSWSegmentFinderTool.cxx.

986  {
987  std::vector<NSWSeed> seeds;
989  if (orderedClusters.empty()) return seeds;
990 
991  std::vector<std::vector<const Muon::sTgcPrepData*>> sTgcIP(4); // IP: layers nearest to the IP will be added first
992  std::vector<std::vector<const Muon::sTgcPrepData*>> sTgcHO(4); // HO: layers furthest from the IP will be added first
993 
994  // Process clusters separately for each multilayer
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};
1000 
1001  // Loop on layers (reverse loop for HO)
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);
1007  }
1008  std::vector<const Muon::sTgcPrepData*>& matchedHits =
1009  (iml == 1) ? sTgcIP.at(nLayersWithHitMatch) : sTgcHO.at(nLayersWithHitMatch);
1010 
1011  // Loop on the hits on this layer. Find the one closest (in eta) to the segment intersection.
1012  for (const Muon::MuonClusterOnTrack* rio : orderedClusters[il]) {
1013  const sTgcPrepData* padHit = dynamic_cast<const sTgcPrepData*>(rio->prepRawData());
1014  if (!padHit) continue;
1015 
1016  // check the multilayer the hit is on
1017  if (m_idHelperSvc->stgcIdHelper().multilayer(padHit->identify()) != iml) continue;
1018 
1019  const MuonGM::MuonPadDesign* design = padHit->detectorElement()->getPadDesign(padHit->identify());
1020  if (!design) continue;
1021 
1022  // local position of the segment intersection with the plane
1023  const Trk::Surface& surf = padHit->detectorElement()->surface(padHit->identify());
1025  surf.straightLineIntersection(etaSeg.globalPosition(), etaSeg.globalDirection(), false, false);
1026  Amg::Vector2D segLocPosOnSurf{Amg::Vector2D::Zero()};
1027  surf.globalToLocal(intersect.position, intersect.position, segLocPosOnSurf);
1028 
1029  // eta distance between the hit and the segment intersection with the plane
1030  // check that it's no more than half of the pad eta-pitch.
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.");
1035 
1036  if (matchedHits.empty()) {
1037  // first hit
1038  matchedHits.push_back(padHit);
1039  ATH_MSG_DEBUG(" best etaDistance: " << etaDistance);
1040  } else if (std::abs(etaDistance - lastDistance) < 0.001) {
1041  // competing hit pad, keep both (all hit pads of the same eta row will be candidates)
1042  matchedHits.push_back(padHit);
1043  ATH_MSG_DEBUG(" added etaDistance: " << etaDistance << " size " << matchedHits.size());
1044  } else if (etaDistance < lastDistance) {
1045  // found a better hit; clear the old ones (possible only for clustered pad hits)
1046  matchedHits.clear();
1047  matchedHits.push_back(padHit);
1048  ATH_MSG_DEBUG(" replacing best etaDistance with: " << etaDistance);
1049  } else {
1050  continue;
1051  }
1052  lastDistance = etaDistance;
1053  } // end of loop on hits
1054 
1055  if (!matchedHits.empty()) ++nLayersWithHitMatch;
1056 
1057  } // end of loop on layers
1058 
1059  // need at least one hit in each multilayer to create a seed
1060  if (!nLayersWithHitMatch) return seeds;
1061 
1062  } // end of loop on multilayers
1063 
1064  // get refined phi ranges on each ml, by taking into account pad staggering
1065  std::vector<std::pair<double, double>> sTgcIP_phiRanges = getPadPhiOverlap(sTgcIP);
1066  std::vector<std::pair<double, double>> sTgcHO_phiRanges = getPadPhiOverlap(sTgcHO);
1067 
1068  // reference prds on the outermost hit surfaces
1069  const sTgcPrepData* prdL1 = sTgcIP.front().front();
1070  const sTgcPrepData* prdL2 = sTgcHO.front().front();
1071  const auto& surfPrdL1 = prdL1->detectorElement()->surface();
1072  const auto& surfPrdL2 = prdL2->detectorElement()->surface();
1073 
1074  // create a seed for each combination of IP and HO points
1075  for (const std::pair<double, double>& range1 : sTgcIP_phiRanges) {
1076  double midPhi1 = 0.5 * (range1.first + range1.second);
1077  Amg::Vector2D lp1(midPhi1, prdL1->localPosition().y());
1079  surfPrdL1.localToGlobal(lp1, gpL1, gpL1);
1080 
1081  Amg::Vector2D lp1_lowPhi{range1.first, prdL1->localPosition().y()};
1082  Amg::Vector2D lp1_highPhi{range1.second, prdL1->localPosition().y()};
1083 
1084  Amg::Vector3D gp1_lowPhi{Amg::Vector3D::Zero()};
1085  Amg::Vector3D gp1_highPhi{Amg::Vector3D::Zero()};
1086 
1087  surfPrdL1.localToGlobal(lp1_lowPhi, gp1_lowPhi, gp1_lowPhi);
1088  surfPrdL1.localToGlobal(lp1_highPhi, gp1_highPhi, gp1_highPhi);
1089 
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);
1092 
1093  Amg::Vector2D lpIntersect_lowPhi{Amg::Vector2D::Zero()};
1094  Amg::Vector2D lpIntersect_highPhi{Amg::Vector2D::Zero()};
1095 
1096  surfPrdL2.globalToLocal(intersect_lowPhi.position, intersect_lowPhi.position, lpIntersect_lowPhi);
1097  surfPrdL2.globalToLocal(intersect_highPhi.position, intersect_highPhi.position, lpIntersect_highPhi);
1098 
1099  for (const std::pair<double, double>& range2 : sTgcHO_phiRanges) {
1100  double midPhi2 = 0.5 * (range2.first + range2.second);
1101  // let's check that the phi ranges in the two multilayer overlap
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");
1104  continue;
1105  }
1106 
1107  Amg::Vector2D lp2(midPhi2, prdL2->localPosition().y());
1109  surfPrdL2.localToGlobal(lp2, gpL2, gpL2);
1110  // create the seed taking the average position (w.r.t. IP)
1111  // as global direction (as for an infinite momentum track).
1112  Amg::Vector3D gDir = (gpL2 + gpL1).unit();
1113  seeds.emplace_back(this, gpL1, gDir);
1114  }
1115  }
1116 
1117  ATH_MSG_DEBUG(" segmentSeedFromPads: seeds.size() " << seeds.size());
1118  return seeds;
1119  }

◆ segmentSeedFromStgc()

std::vector< NSWSeed > Muon::MuonNSWSegmentFinderTool::segmentSeedFromStgc ( const LayerMeasVec orderedClusters,
bool  usePhi 
) const
private

Reject

Definition at line 868 of file MuonNSWSegmentFinderTool.cxx.

869  {
870  std::vector<NSWSeed> seeds;
871 
872  // oderedClusters should contain either eta clusters (MM and sTGC)
873  // or sTGC phi hits. For MM phi, use the dedicated function.
874  if (orderedClusters.size() < 4) return seeds;
875 
876  // Create seeds using each pair of hits on the two most distant layers (that containing hits).
877  // m_nOfSeedLayers (default = 1) dictates whether we want to also use hits from inner layers.
878 
879  // Loop on layers to get the first seed point
880  int seedingLayersL{0};
881  for (unsigned int ilayerL{0}; (ilayerL < orderedClusters.size() && seedingLayersL < m_nOfSeedLayers); ++ilayerL) {
882  bool usedLayerL{false};
883  for (const SeedMeasurement& hitL : orderedClusters[ilayerL]) {
885  if (usePhi != m_idHelperSvc->measuresPhi(hitL->identify())) continue;
886  else if(m_idHelperSvc->isMM(hitL->identify())) break;
887 
888 
889  // For the second point, loop on layers in reverse to be as far as possible from the first.
890  int seedingLayersR{0};
891  for (unsigned int ilayerR = orderedClusters.size() - 1; (ilayerR > ilayerL && seedingLayersR < m_nOfSeedLayers);
892  --ilayerR) {
893  bool usedLayerR{false};
894  for (const SeedMeasurement& hitR : orderedClusters[ilayerR]) {
895  if (usePhi != m_idHelperSvc->measuresPhi(hitR->identify())) continue;
896  else if (m_idHelperSvc->isMM(hitR->identify())) break;
897  NSWSeed seed{this,hitL, hitR};
898  if (!usePhi && m_ipConstraint) {
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) {
901  continue;
902  }
903  } else if (usePhi && m_ipConstraint) {
904  // first make sure that the wires are in the same or neigbouring quads
905  if(std::abs(std::abs(m_idHelperSvc->stationEta(hitL->identify())) - std::abs(m_idHelperSvc->stationEta(hitR->identify()))) > 1) {
906  continue;
907  }
908  // project the hit in the first layer assuming the track comes from the IP
909  Trk::Intersection intersect = hitR->detectorElement()->surface(hitR->identify()).straightLineIntersection(hitL->globalPosition(),hitL->globalPosition().unit(), false, false);
910  Amg::Vector2D lpos_intersect{Amg::Vector2D::Zero()};
911  hitR->detectorElement()->surface(hitR->identify()).globalToLocal(intersect.position, intersect.position, lpos_intersect);
912 
913  Amg::Vector2D lPosR;
914  hitR->detectorElement()->surface(hitR->identify()).globalToLocal(hitR->globalPosition(), hitR->globalPosition(), lPosR);
915 
916 
917  if(std::abs(lpos_intersect.x() - lPosR.x()) > 87.5 ) continue; // reject seed if the projection is more than 2.5 wire groups away
918  }
919 
920  usedLayerR = true;
921  usedLayerL = true;
922  getClustersOnSegment(orderedClusters, seed, {ilayerL, ilayerR}, false);
923  seeds.emplace_back(std::move(seed));
924 
925  }
926  if (usedLayerR) ++seedingLayersR;
927  }
928  }
929  if (usedLayerL) ++seedingLayersL;
930  }
931 
932  return resolveAmbiguities(std::move(seeds));
933  }

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in DerivationFramework::CfAthAlgTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and asg::AsgMetadataTool.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase &  )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308  {
309  // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310  // << " size: " << m_vhka.size() << endmsg;
311  for (auto &a : m_vhka) {
312  std::vector<SG::VarHandleKey*> keys = a->keys();
313  for (auto k : keys) {
314  k->setOwner(this);
315  }
316  }
317  }

◆ 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.

1604  {
1605  if (clustInLay.size() < m_ocupMmNumPerBin || m_idHelperSvc->issTgc(clustInLay[0]->identify())) return clustInLay;
1611  MeasVec prunedMeas{};
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;
1617  const unsigned int nBins = deltaCh / m_ocupMmBinWidth + (deltaCh % m_ocupMmBinWidth > 0);
1618  ATH_MSG_VERBOSE("Clusters in layer "<<print(clustInLay)<<" lowest channel: "<<
1619  firstCh<<", highest channel: "<<lastCh<<" bin width: "<<m_ocupMmBinWidth<<" number of bins"<<nBins);
1620 
1621  LayerMeasVec occupancyHisto{};
1622  occupancyHisto.resize(nBins);
1623  for (MeasVec& bin : occupancyHisto) {
1624  bin.reserve(clustInLay.size());
1625  }
1626  ATH_MSG_VERBOSE("Clusters sorted into bins "<<print(occupancyHisto));
1628  for (SeedMeasurement& meas : clustInLay){
1629  unsigned int bin = (channel(meas) - firstCh) % nBins;
1630  occupancyHisto[bin].push_back(std::move(meas));
1631  }
1633  for (MeasVec& bin : occupancyHisto) {
1634  if(bin.size() >= m_ocupMmNumPerBin){
1635  ATH_MSG_VERBOSE("The micromegas are slobbering. Detected too many clusters "<<bin.size()<<std::endl<<print(bin));
1636  bin.clear();
1637  }
1638  }
1640  for (unsigned int i = 0; i < occupancyHisto.size() -1; ++i) {
1641  if (occupancyHisto[i].size() + occupancyHisto[i+1].size() >= m_ocupMmNumPerPair){
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();
1646  }
1647  }
1649  for (MeasVec& bin : occupancyHisto){
1650  std::copy(std::make_move_iterator(bin.begin()),
1651  std::make_move_iterator(bin.end()),
1652  std::back_inserter(prunedMeas));
1653  }
1654 
1655  ATH_MSG_VERBOSE("Number of measurements before pruning "<<clustInLay.size()<<" number of measurments survived the pruning "<<prunedMeas.size());
1656  return prunedMeas;
1657 
1658  }

◆ wedgeNumber()

int Muon::MuonNSWSegmentFinderTool::wedgeNumber ( const Muon::MuonClusterOnTrack cluster) const

Definition at line 936 of file MuonNSWSegmentFinderTool.cxx.

936  {
937  if (m_idHelperSvc->isMM(cluster->identify()))
938  return m_idHelperSvc->mmIdHelper().multilayer(cluster->identify()) + 1; // [IP:2, HO:3]
939  if (m_idHelperSvc->issTgc(cluster->identify()))
940  return 3 * (m_idHelperSvc->stgcIdHelper().multilayer(cluster->identify()) - 1) + 1; // [IP:1, HO:4];
941  return -1;
942  }

Member Data Documentation

◆ m_ambiTool

ToolHandle<Trk::ITrackAmbiguityProcessorTool> Muon::MuonNSWSegmentFinderTool::m_ambiTool
private
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

Use a virtual point at the calorimeter exit with same Z as constraint...

Definition at line 184 of file MuonNSWSegmentFinderTool.h.

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default)

Definition at line 393 of file AthCommonDataStore.h.

◆ m_edmHelperSvc

ServiceHandle<IMuonEDMHelperSvc> Muon::MuonNSWSegmentFinderTool::m_edmHelperSvc
private
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

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default)

Definition at line 390 of file AthCommonDataStore.h.

◆ m_idHelperSvc

ServiceHandle<IMuonIdHelperSvc> Muon::MuonNSWSegmentFinderTool::m_idHelperSvc
private
Initial value:
{
this,
"MuonIdHelperSvc",
"Muon::MuonIdHelperSvc/MuonIdHelperSvc",
}

Definition at line 136 of file MuonNSWSegmentFinderTool.h.

◆ m_ipConstraint

Gaudi::Property<bool> Muon::MuonNSWSegmentFinderTool::m_ipConstraint {this, "IPConstraint", true}
private

Definition at line 181 of file MuonNSWSegmentFinderTool.h.

◆ m_maxClustDist

Gaudi::Property<double> Muon::MuonNSWSegmentFinderTool::m_maxClustDist {this, "ClusterDistance", 5.}
private

Definition at line 185 of file MuonNSWSegmentFinderTool.h.

◆ m_maxInputPads

Gaudi::Property<uint> Muon::MuonNSWSegmentFinderTool::m_maxInputPads {this, "maxInputPads", 40, "Maximum number of pads per wedge layer."}
private

Definition at line 199 of file MuonNSWSegmentFinderTool.h.

◆ m_muonClusterCreator

ToolHandle<IMuonClusterOnTrackCreator> Muon::MuonNSWSegmentFinderTool::m_muonClusterCreator {this, "MuonClusterCreator", ""}
private

Definition at line 179 of file MuonNSWSegmentFinderTool.h.

◆ m_nOfSeedLayers

Gaudi::Property<int> Muon::MuonNSWSegmentFinderTool::m_nOfSeedLayers {this, "NOfSeedLayers", 1}
private

Definition at line 186 of file MuonNSWSegmentFinderTool.h.

◆ 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

PublicToolHandle<MuonEDMPrinterTool> Muon::MuonNSWSegmentFinderTool::m_printer
private
Initial value:
{
this,
"Printer",
"Muon::MuonEDMPrinterTool/MuonEDMPrinterTool",
}

Definition at line 163 of file MuonNSWSegmentFinderTool.h.

◆ m_slTrackFitter

ToolHandle<Trk::ITrackFitter> Muon::MuonNSWSegmentFinderTool::m_slTrackFitter
private
Initial value:
{
this,
"SLFitter",
"Trk::GlobalChi2Fitter/MCTBSLFitter",
}

Definition at line 153 of file MuonNSWSegmentFinderTool.h.

◆ m_trackCleaner

ToolHandle<IMuonTrackCleaner> Muon::MuonNSWSegmentFinderTool::m_trackCleaner
private
Initial value:
{
this,
"TrackCleaner",
"Muon::MuonTrackCleaner/MuonTrackCleaner",
}

Definition at line 168 of file MuonNSWSegmentFinderTool.h.

◆ m_trackSummary

ToolHandle<Trk::ITrackSummaryTool> Muon::MuonNSWSegmentFinderTool::m_trackSummary
private
Initial value:
{
this,
"TrackSummaryTool",
"Trk::TrackSummaryTool/MuidTrackSummaryTool",
}

Definition at line 173 of file MuonNSWSegmentFinderTool.h.

◆ m_trackToSegmentTool

ToolHandle<IMuonTrackToSegmentTool> Muon::MuonNSWSegmentFinderTool::m_trackToSegmentTool
private
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

Definition at line 189 of file MuonNSWSegmentFinderTool.h.

◆ m_usesTGCSeeding

Gaudi::Property<bool> Muon::MuonNSWSegmentFinderTool::m_usesTGCSeeding {this, "SeedWithsTGCS", true}
private

Definition at line 190 of file MuonNSWSegmentFinderTool.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files:
ReadFromCoolCompare.ov
ov
Definition: ReadFromCoolCompare.py:230
PlotCalibFromCool.il
il
Definition: PlotCalibFromCool.py:381
Muon::MuonNSWSegmentFinderTool::coveredRadii
std::pair< double, double > coveredRadii(const SeedMeasurement &meas) const
Returns the minimal & maximal radial distance of a measurement.
Definition: MuonNSWSegmentFinderTool.cxx:1404
Trk::LocalParameters
Definition: LocalParameters.h:98
Muon::MuonNSWSegmentFinderTool::printSeed
std::string printSeed(const std::array< SeedMeasurement, N > &seed) const
Definition: MuonNSWSegmentFinderTool.cxx:1570
Trk::PlaneSurface::globalToLocal
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...
Definition: PlaneSurface.cxx:209
Trk::PlaneSurface::localToGlobalDirection
void localToGlobalDirection(const Trk::LocalDirection &locdir, Amg::Vector3D &globdir) const
This method transforms a local direction wrt the plane to a global direction.
Definition: PlaneSurface.cxx:238
MuonGM::MuonPadDesign
Parameters defining the design of the readout sTGC pads.
Definition: MuonPadDesign.h:40
test_pyathena.eta
eta
Definition: test_pyathena.py:10
Muon::MuonNSWSegmentFinderTool::print
std::string print(const SeedMeasurement &meas) const
Definition: MuonNSWSegmentFinderTool.cxx:1578
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Muon::MuonNSWSegmentFinderTool::m_edmHelperSvc
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
Definition: MuonNSWSegmentFinderTool.h:141
Trk::Track::fitQuality
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:27
Trk::Intersection
Definition: Intersection.h:24
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
Muon::NSWSeed::SeedOR::SuperSet
@ SuperSet
Muon::MuonNSWSegmentFinderTool::getPadPhiOverlap
std::vector< std::pair< double, double > > getPadPhiOverlap(const std::vector< std::vector< const Muon::sTgcPrepData * >> &pads) const
Definition: MuonNSWSegmentFinderTool.cxx:1440
Muon::MuonNSWSegmentFinderTool::m_ocupMmNumPerPair
Gaudi::Property< unsigned int > m_ocupMmNumPerPair
Definition: MuonNSWSegmentFinderTool.h:197
Muon::MuonNSWSegmentFinderTool::Wire
@ Wire
Definition: MuonNSWSegmentFinderTool.h:230
Trk::locX
@ locX
Definition: ParamDefs.h:37
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:38
Muon::MuonNSWSegmentFinderTool::m_trackToSegmentTool
ToolHandle< IMuonTrackToSegmentTool > m_trackToSegmentTool
Definition: MuonNSWSegmentFinderTool.h:158
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
Trk::Surface::straightLineIntersection
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
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:352
egammaEnergyPositionAllSamples::e1
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
Muon::MuonNSWSegmentFinderTool::findStgcPrecisionSegments
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.
Definition: MuonNSWSegmentFinderTool.cxx:478
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:161
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
extractSporadic.c1
c1
Definition: extractSporadic.py:133
Muon::MuonNSWSegmentFinderTool::ChannelConstraint
ChannelConstraint
Definition: MuonNSWSegmentFinderTool.h:298
Muon::MuonNSWSegmentFinderTool::m_idHelperSvc
ServiceHandle< IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonNSWSegmentFinderTool.h:136
Muon::MuonNSWSegmentFinderTool::m_ocupMmNumPerBin
Gaudi::Property< unsigned int > m_ocupMmNumPerBin
Definition: MuonNSWSegmentFinderTool.h:195
Muon::MuonNSWSegmentFinderTool::m_printer
PublicToolHandle< MuonEDMPrinterTool > m_printer
Definition: MuonNSWSegmentFinderTool.h:163
module_driven_slicing.layers
layers
Definition: module_driven_slicing.py:113
python.SystemOfUnits.second
float second
Definition: SystemOfUnits.py:135
Muon::MuonNSWSegmentFinderTool::segmentSeedFromMM
std::vector< NSWSeed > segmentSeedFromMM(const LayerMeasVec &orderedClusters) const
Definition: MuonNSWSegmentFinderTool.cxx:1122
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:200
bin
Definition: BinsDiffFromStripMedian.h:43
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
StoreGateSvc_t m_evtStore
Pointer to StoreGate (event store by default)
Definition: AthCommonDataStore.h:390
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
std::vector< SG::VarHandleKeyArray * > m_vhka
Definition: AthCommonDataStore.h:398
sTgcIdHelper::Strip
@ Strip
Definition: sTgcIdHelper.h:190
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
Muon::MuonNSWSegmentFinderTool::hitsToTrack
bool hitsToTrack(const EventContext &ctx, const MeasVec &etaHitVec, const MeasVec &phiHitVec, const Trk::TrackParameters &startpar, TrackCollection &segTrkColl) const
Definition: MuonNSWSegmentFinderTool.cxx:741
Muon::MuonNSWSegmentFinderTool::Eta
@ Eta
Definition: MuonNSWSegmentFinderTool.h:230
Phi
@ Phi
Definition: RPCdef.h:8
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:9
exclude
std::set< std::string > exclude
list of directories to be excluded
Definition: hcg.cxx:95
Muon::MuonNSWSegmentFinderTool::cleanClusters
MeasVec cleanClusters(const std::vector< const Muon::MuonClusterOnTrack * > &MuonClusters, int hit_sel, int singleWedge) const
Definition: MuonNSWSegmentFinderTool.cxx:799
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
Muon::MuonNSWSegmentFinderTool::compatiblyFromIP
ChannelConstraint compatiblyFromIP(const SeedMeasurement &meas1, const SeedMeasurement &meas2) const
Checks whether the two measurements are compatible within the IP constraint
Definition: MuonNSWSegmentFinderTool.cxx:1370
Trk::Perigee
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
Definition: Tracking/TrkEvent/TrkParameters/TrkParameters/TrackParameters.h:33
MuonGM::MuonChannelDesign::hasStereoAngle
double hasStereoAngle() const
returns whether the stereo angle is non-zero
Definition: MuonChannelDesign.h:78
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:50
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
XMLtoHeader.count
count
Definition: XMLtoHeader.py:84
Trk::DefinedParameter
std::pair< double, ParamDefs > DefinedParameter
Definition: DefinedParameter.h:27
SG::VarHandleKeyArray::setOwner
virtual void setOwner(IDataHandleHolder *o)=0
IDTPMcnv.htype
htype
Definition: IDTPMcnv.py:29
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
AthCommonDataStore::declareGaudiProperty
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>
Definition: AthCommonDataStore.h:156
A
Muon::MuonNSWSegmentFinderTool::ipConstraint
std::unique_ptr< Trk::PseudoMeasurementOnTrack > ipConstraint(const EventContext &ctx) const
creates the IP constraint
Definition: MuonNSWSegmentFinderTool.cxx:718
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
Muon::MuonNSWSegmentFinderTool::classifyByLayer
LayerMeasVec classifyByLayer(const MeasVec &clusters, int hit_sel) const
Definition: MuonNSWSegmentFinderTool.cxx:819
AthCommonDataStore
Definition: AthCommonDataStore.h:52
Generate_dsid_ranseed.seed
seed
Definition: Generate_dsid_ranseed.py:10
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Muon::MuonNSWSegmentFinderTool::vetoBursts
MeasVec vetoBursts(MeasVec &&clustInLay) const
Removes clusters from high activity areas in the detector.
Definition: MuonNSWSegmentFinderTool.cxx:1604
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
lumiFormat.i
int i
Definition: lumiFormat.py:85
SG::OWN_ELEMENTS
@ OWN_ELEMENTS
this data object owns its elements
Definition: OwnershipPolicy.h:17
PixelAthClusterMonAlgCfg.e4
e4
Definition: PixelAthClusterMonAlgCfg.py:332
G
#define G(x, y, z)
Definition: MD5.cxx:113
python.SystemOfUnits.micrometer
float micrometer
Definition: SystemOfUnits.py:80
sTgcIdHelper::Wire
@ Wire
Definition: sTgcIdHelper.h:190
MuonR4::inverse
CalibratedSpacePoint::Covariance_t inverse(const CalibratedSpacePoint::Covariance_t &mat)
Inverts the parsed matrix.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:65
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AthCommonDataStore::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition: AthCommonDataStore.h:145
AmgVector
AmgVector(4) T2BSTrackFilterTool
Definition: T2BSTrackFilterTool.cxx:114
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
Muon::MuonNSWSegmentFinderTool::m_trackCleaner
ToolHandle< IMuonTrackCleaner > m_trackCleaner
Definition: MuonNSWSegmentFinderTool.h:168
Muon::MuonNSWSegmentFinderTool::Phi
@ Phi
Definition: MuonNSWSegmentFinderTool.h:230
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
test_pyathena.parent
parent
Definition: test_pyathena.py:15
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
Muon::MuonNSWSegmentFinderTool::m_nOfSeedLayers
Gaudi::Property< int > m_nOfSeedLayers
Definition: MuonNSWSegmentFinderTool.h:186
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Muon::MuonNSWSegmentFinderTool::channel
int channel(const Muon::MuonClusterOnTrack *cluster) const
Returns the channel of the measurement on the layer.
Definition: MuonNSWSegmentFinderTool.cxx:953
Trk::PlaneSurface::globalToLocalDirection
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
Definition: PlaneSurface.cxx:256
Muon::MuonNSWSegmentFinderTool::m_ocupMmBinWidth
Gaudi::Property< unsigned int > m_ocupMmBinWidth
Protection against slobbering Micromega events.
Definition: MuonNSWSegmentFinderTool.h:193
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
StoreGateSvc_t m_detStore
Pointer to StoreGate (detector store by default)
Definition: AthCommonDataStore.h:393
Trk::Intersection::position
Amg::Vector3D position
Definition: Intersection.h:25
DataVector< Trk::Track >
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
Trk::LocalDirection
represents the three-dimensional global direction with respect to a planar surface frame.
Definition: LocalDirection.h:81
MuonGM::MuonPadDesign::channelWidth
double channelWidth(const Amg::Vector2D &pos, bool measPhi, bool preciseMeas=false) const
calculate local channel width
Definition: MuonPadDesign.h:142
Muon::MuonNSWSegmentFinderTool::m_maxClustDist
Gaudi::Property< double > m_maxClustDist
Definition: MuonNSWSegmentFinderTool.h:185
Muon::MuonNSWSegmentFinderTool::ChannelConstraint::TooNarrow
@ TooNarrow
AthAlgTool::AthAlgTool
AthAlgTool()
Default constructor:
beamspotman.dir
string dir
Definition: beamspotman.py:621
Muon::MuonNSWSegmentFinderTool::m_trackSummary
ToolHandle< Trk::ITrackSummaryTool > m_trackSummary
Definition: MuonNSWSegmentFinderTool.h:173
SG::VarHandleKeyArray::renounce
virtual void renounce()=0
SG::HandleClassifier::type
std::conditional< std::is_base_of< SG::VarHandleKeyArray, T >::value, VarHandleKeyArrayType, type2 >::type type
Definition: HandleClassifier.h:54
lumiFormat.array
array
Definition: lumiFormat.py:91
tolerance
Definition: suep_shower.h:17
Muon::MuonNSWSegmentFinderTool::findStereoSegments
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.
Definition: MuonNSWSegmentFinderTool.cxx:393
Trk::MeasurementBase
Definition: MeasurementBase.h:58
Muon::MuonNSWSegmentFinderTool::LayerMeasVec
std::vector< MeasVec > LayerMeasVec
Definition: MuonNSWSegmentFinderTool.h:204
Muon::MuonNSWSegmentFinderTool::m_ambiTool
ToolHandle< Trk::ITrackAmbiguityProcessorTool > m_ambiTool
Tool for ambiguity solving.
Definition: MuonNSWSegmentFinderTool.h:148
Muon::MuonNSWSegmentFinderTool::segmentSeedFromStgc
std::vector< NSWSeed > segmentSeedFromStgc(const LayerMeasVec &orderedClusters, bool usePhi) const
Definition: MuonNSWSegmentFinderTool.cxx:868
Trk::Track::perigeeParameters
const Perigee * perigeeParameters() const
return Perigee.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:163
dumpTgcDigiJitter.nBins
list nBins
Definition: dumpTgcDigiJitter.py:29
Muon::MuonNSWSegmentFinderTool::ChannelConstraint::InWindow
@ InWindow
Muon::MuonNSWSegmentFinderTool::m_maxInputPads
Gaudi::Property< uint > m_maxInputPads
Definition: MuonNSWSegmentFinderTool.h:199
merge_scale_histograms.doc
string doc
Definition: merge_scale_histograms.py:9
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:82
Trk::nonInteracting
@ nonInteracting
Definition: ParticleHypothesis.h:28
Trk::PrepRawDataType::sTgcPrepData
@ sTgcPrepData
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::PlaneSurface::straightLineIntersection
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...
Definition: PlaneSurface.cxx:219
Muon::MuonNSWSegmentFinderTool::segmentSeedFromPads
std::vector< NSWSeed > segmentSeedFromPads(const LayerMeasVec &orderedClusters, const Muon::MuonSegment &etaSeg) const
Definition: MuonNSWSegmentFinderTool.cxx:985
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
Muon::MuonNSWSegmentFinderTool::ChannelConstraint::TooWide
@ TooWide
MuonGM::MuonChannelDesign::channelHalfLength
double channelHalfLength(int st, bool left) const
STRIPS ONLY: calculate channel length on the given side of the x axis (for MM stereo strips)
Definition: MuonChannelDesign.h:376
Muon::MuonNSWSegmentFinderTool::m_slTrackFitter
ToolHandle< Trk::ITrackFitter > m_slTrackFitter
Definition: MuonNSWSegmentFinderTool.h:153
DataVector::stdcont
const PtrVector & stdcont() const
Return the underlying std::vector of the container.
MuonGM::MuonChannelDesign::rightEdge
bool rightEdge(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the right edge of the strip.
Definition: MuonChannelDesign.h:493
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
MuonGM::MuonChannelDesign
Definition: MuonChannelDesign.h:24
python.DataFormatRates.c2
c2
Definition: DataFormatRates.py:123
ReadBchFromCool.good
good
Definition: ReadBchFromCool.py:433
a
TList * a
Definition: liststreamerinfos.cxx:10
columnar::empty
bool empty() const noexcept
Definition: ObjectRange.h:163
h
Trk::Surface::globalToLocal
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...
egammaEnergyPositionAllSamples::e2
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
Amg::intersect
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.
Definition: GeoPrimitivesHelpers.h:347
std::sort
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.
Definition: DVL_algorithms.h:623
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::PlaneSurface
Definition: PlaneSurface.h:64
sTgcIdHelper::Pad
@ Pad
Definition: sTgcIdHelper.h:190
Muon::NSWSeed::SeedOR
SeedOR
Definition: MuonNSWSegmentFinderTool.h:89
unit
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
Definition: AmgMatrixBasePlugin.h:21
DeMoScan.first
bool first
Definition: DeMoScan.py:534
Trk::RIO_OnTrack::identify
Identifier identify() const
return the identifier -extends MeasurementBase
Definition: RIO_OnTrack.h:152
DEBUG
#define DEBUG
Definition: page_access.h:11
MuonGM::MuonChannelDesign::stereoAngle
double stereoAngle() const
returns the stereo angle
Definition: MuonChannelDesign.h:73
Muon::MuonNSWSegmentFinderTool::layerNumber
int layerNumber(const Muon::MuonClusterOnTrack *cluster) const
Definition: MuonNSWSegmentFinderTool.cxx:943
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
Muon::MuonNSWSegmentFinderTool::wedgeNumber
int wedgeNumber(const Muon::MuonClusterOnTrack *cluster) const
Definition: MuonNSWSegmentFinderTool.cxx:936
python.utility.LHE.merge
def merge(input_file_pattern, output_file)
Merge many input LHE files into a single output file.
Definition: LHE.py:29
Muon::MuonNSWSegmentFinderTool::find3DSegments
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
Definition: MuonNSWSegmentFinderTool.cxx:581
SG::VarHandleBase::vhKey
SG::VarHandleKey & vhKey()
Return a non-const reference to the HandleKey.
Definition: StoreGate/src/VarHandleBase.cxx:629
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
Muon::NSWSeed::SeedOR::Same
@ Same
Muon::MuonNSWSegmentFinderTool::getClustersOnSegment
int getClustersOnSegment(const LayerMeasVec &orderedclusters, NSWSeed &seed, const std::set< unsigned int > &exclude, bool useStereo=true) const
Definition: MuonNSWSegmentFinderTool.cxx:960
Pad
Definition: Pad.h:10
Trk::FitQuality::chiSquared
double chiSquared() const
returns the of the overall track fit
Definition: FitQuality.h:56
Muon::MuonNSWSegmentFinderTool::SeedMeasurement
NSWSeed::SeedMeasurement SeedMeasurement
Definition: MuonNSWSegmentFinderTool.h:202
Muon::MuonNSWSegmentFinderTool::m_muonClusterCreator
ToolHandle< IMuonClusterOnTrackCreator > m_muonClusterCreator
Definition: MuonNSWSegmentFinderTool.h:179
Muon::MuonSectorMapping
Definition: MuonSectorMapping.h:20
Muon::MuonNSWSegmentFinderTool::caloConstraint
std::unique_ptr< Trk::PseudoMeasurementOnTrack > caloConstraint(const Trk::TrackParameters &startpar) const
Definition: MuonNSWSegmentFinderTool.cxx:701
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801
Trk::FitQuality::numberDoF
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition: FitQuality.h:60
ReadBchFromCool.nBad
nBad
Definition: ReadBchFromCool.py:455
Muon::MuonSegment::globalPosition
virtual const Amg::Vector3D & globalPosition() const override final
global position
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:157
Muon::MuonNSWSegmentFinderTool::m_ipConstraint
Gaudi::Property< bool > m_ipConstraint
Definition: MuonNSWSegmentFinderTool.h:181
Muon::MuonNSWSegmentFinderTool::fit
std::unique_ptr< Trk::Track > fit(const EventContext &ctx, const std::vector< const Trk::MeasurementBase * > &fit_meas, const Trk::TrackParameters &perigee) const
Definition: MuonNSWSegmentFinderTool.cxx:447
Trk::Segment::NswQuadAlign
@ NswQuadAlign
Definition: Tracking/TrkEvent/TrkSegment/TrkSegment/Segment.h:79
calibdata.copy
bool copy
Definition: calibdata.py:26
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
Trk::PlaneSurface::localToGlobal
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.
Definition: PlaneSurface.cxx:198
Trk::Segment::NswStgcSeeded
@ NswStgcSeeded
Definition: Tracking/TrkEvent/TrkSegment/TrkSegment/Segment.h:77
Muon::MuonNSWSegmentFinderTool::m_caloConstraint
Gaudi::Property< bool > m_caloConstraint
Use a virtual point at the calorimeter exit with same Z as constraint...
Definition: MuonNSWSegmentFinderTool.h:184
Muon::MuonNSWSegmentFinderTool::m_usesTGCSeeding
Gaudi::Property< bool > m_usesTGCSeeding
Definition: MuonNSWSegmentFinderTool.h:190
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:79
Muon::sTgcPrepData
Class to represent sTgc measurements.
Definition: sTgcPrepData.h:20
Muon::MuonNSWSegmentFinderTool::getCalibratedClusters
MeasVec getCalibratedClusters(NSWSeed &seed) const
Definition: MuonNSWSegmentFinderTool.cxx:1540
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:25
Muon::MuonNSWSegmentFinderTool::resolveAmbiguities
std::vector< NSWSeed > resolveAmbiguities(std::vector< NSWSeed > &&unresolved) const
Definition: MuonNSWSegmentFinderTool.cxx:1414
Muon::MuonNSWSegmentFinderTool::m_useStereoSeeding
Gaudi::Property< bool > m_useStereoSeeding
Definition: MuonNSWSegmentFinderTool.h:189
Eta
@ Eta
Definition: RPCdef.h:8
Muon::MuonClusterOnTrack
Base class for Muon cluster RIO_OnTracks.
Definition: MuonClusterOnTrack.h:34
fitman.k
k
Definition: fitman.py:528
Muon::MuonSegment::globalDirection
const Amg::Vector3D & globalDirection() const
global direction
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:163
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
MuonGM::MuonChannelDesign::leftEdge
bool leftEdge(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the left edge of the strip.
Definition: MuonChannelDesign.h:486
Identifier
Definition: IdentifierFieldParser.cxx:14
Muon::MuonNSWSegmentFinderTool::MeasVec
NSWSeed::MeasVec MeasVec
Definition: MuonNSWSegmentFinderTool.h:203
Muon::NSWSeed::SeedOR::SubSet
@ SubSet