ATLAS Offline Software
Loading...
Searching...
No Matches
Muon::MSVertexRecoTool Class Reference

#include <MSVertexRecoTool.h>

Inheritance diagram for Muon::MSVertexRecoTool:
Collaboration diagram for Muon::MSVertexRecoTool:

Classes

struct  TrkCluster

Public Member Functions

 MSVertexRecoTool (const std::string &type, const std::string &name, const IInterface *parent)
virtual ~MSVertexRecoTool ()=default
virtual StatusCode initialize (void) override
StatusCode findMSvertices (const std::vector< Tracklet > &tracklets, std::vector< std::unique_ptr< MSVertex > > &vertices, const EventContext &ctx) const override
 DeclareInterfaceID (Muon::IMSVertexRecoTool, 1, 0)
 access to tool interface
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
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.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

std::vector< TrkClusterfindTrackClusters (const std::vector< Tracklet > &tracklets) const
std::optional< TrkClusterClusterizeTracks (std::vector< Tracklet > &tracks) const
void MSVxFinder (const std::vector< Tracklet > &tracklets, std::unique_ptr< MSVertex > &vtx, const EventContext &ctx) const
void MSStraightLineVx (const std::vector< Tracklet > &trks, std::unique_ptr< MSVertex > &vtx, const EventContext &ctx) const
void MSStraightLineVx_oldMethod (const std::vector< Tracklet > &trks, std::unique_ptr< MSVertex > &vtx, const EventContext &ctx) const
std::vector< TrackletRemoveBadTrk (const std::vector< Tracklet > &tracklets, const Amg::Vector3D &Vx) const
bool EndcapHasBadTrack (const std::vector< Tracklet > &tracklets, const Amg::Vector3D &Vx) const
void HitCounter (MSVertex *MSRecoVx, const EventContext &ctx) const
double vxPhiFinder (const double theta, const double phi, const EventContext &ctx) const
std::vector< TrackletgetTracklets (const std::vector< Tracklet > &trks, const std::set< int > &tracklet_subset) const
void dressVtxHits (xAOD::Vertex *xAODVx, const std::vector< SG::AuxElement::Accessor< int > > &accs, const std::vector< int > &hits) const
StatusCode FillOutputContainer (const std::vector< std::unique_ptr< MSVertex > > &, SG::WriteHandle< xAOD::VertexContainer > &xAODVxContainer) const
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Static Private Member Functions

static Amg::Vector3D VxMinQuad (const std::vector< Tracklet > &tracks)

Private Attributes

SG::WriteHandleKey< xAOD::VertexContainerm_xAODContainerKey {this, "xAODVertexContainer", "MSDisplacedVertex"}
SG::ReadHandleKey< Muon::RpcPrepDataContainerm_rpcTESKey {this, "RPCKey", "RPC_Measurements"}
SG::ReadHandleKey< Muon::TgcPrepDataContainerm_tgcTESKey {this, "TGCKey", "TGC_Measurements"}
SG::ReadHandleKey< Muon::MdtPrepDataContainerm_mdtTESKey {this, "MDTKey", "MDT_DriftCircles"}
const std::vector< std::string > m_accMDT_str = {"nMDT", "nMDT_inwards", "nMDT_I", "nMDT_E", "nMDT_M", "nMDT_O"}
const std::vector< std::string > m_accRPC_str = {"nRPC", "nRPC_inwards", "nRPC_I", "nRPC_E", "nRPC_M", "nRPC_O"}
const std::vector< std::string > m_accTGC_str = {"nTGC", "nTGC_inwards", "nTGC_I", "nTGC_E", "nTGC_M", "nTGC_O"}
std::vector< SG::AuxElement::Accessor< int > > m_nMDT_accs
std::vector< SG::AuxElement::Accessor< int > > m_nRPC_accs
std::vector< SG::AuxElement::Accessor< int > > m_nTGC_accs
ServiceHandle< Muon::IMuonIdHelperSvcm_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
ServiceHandle< IAthRNGSvcm_rndmSvc {this, "RndmSvc", "AthRNGSvc", "Random Number Service"}
ToolHandle< Trk::IExtrapolatorm_extrapolator {this, "MyExtrapolator", "Trk::Extrapolator/AtlasExtrapolator"}
Gaudi::Property< unsigned int > m_maxGlobalTracklets {this, "MaxGlobalTracklets", 40, "maximal number of tracklets in an event"}
Gaudi::Property< unsigned int > m_maxClusterTracklets {this, "MaxClusterTracklets", 50, "maximal number of tracklets in a cluster"}
Gaudi::Property< double > m_ChamberOccupancyMin {this, "MinimumHighOccupancy", 0.25, "minimum occupancy to be considered 'high occupancy'"}
Gaudi::Property< int > m_minHighOccupancyChambers {this, "MinimumNumberOfHighOccupancy", 2, "number of high occupancy chambers required to be signal like"}
Gaudi::Property< double > m_ClusterdEta {this, "ClusterdEta", 0.7, "eta extend of cluster"}
Gaudi::Property< double > m_ClusterdPhi {this, "ClusterdPhi", M_PI / 3.*Gaudi::Units::radian, "phi extend of cluster"}
Gaudi::Property< bool > m_doSystematics {this, "DoSystematicUncertainty", false, "find vertex systematic uncertainty"}
Gaudi::Property< double > m_BarrelTrackletUncert {this, "BarrelTrackletUncertainty", 0.1, "probability of considering a barrel tracklet in the clustering for the systematics reconstruction"}
Gaudi::Property< double > m_EndcapTrackletUncert {this, "EndcapTrackletUncertainty", 0.1, "probability of considering a endcap tracklet in the clustering for the systematics reconstruction"}
Gaudi::Property< double > m_TrackPhiAngle {this, "TrackPhiAngle", 0.0*Gaudi::Units::radian, "nominal phi angle for tracklets in rad"}
Gaudi::Property< double > m_TrackPhiRotation {this, "TrackPhiRotation", 0.2*Gaudi::Units::radian, "angle to rotate tracklets by for uncertainty estimate in rad"}
Gaudi::Property< double > m_MaxTrackUncert {this, "MaxTrackUncert", 200.*Gaudi::Units::millimeter, "maximal tracklet uncertainty in mm"}
Gaudi::Property< double > m_VxChi2ProbCUT {this, "VxChi2ProbabilityCut", 0.05, "chi^2 probability cut"}
Gaudi::Property< double > m_VertexMinRadialPlane {this, "VertexMinRadialPlane", 3500.*Gaudi::Units::millimeter, "position of first radial plane in mm"}
Gaudi::Property< double > m_VertexMaxRadialPlane {this, "VertexMaxRadialPlane", 7000.*Gaudi::Units::millimeter, "position of last radial plane in mm"}
Gaudi::Property< double > m_VxPlaneDist {this, "VertexPlaneDist", 200.*Gaudi::Units::millimeter, "distance between two adjacent planes in mm"}
Gaudi::Property< double > m_MaxTollDist {this, "MaxTollDist", 300.*Gaudi::Units::millimeter, "maximal distance between tracklet and endcap vertex in mm"}
Gaudi::Property< bool > m_useOldMSVxEndcapMethod {this, "UseOldMSVxEndcapMethod", false, "use old vertex reconstruction in the endcaps "}
Gaudi::Property< double > m_nMDTHitsEta {this, "nMDTHitsEta", 0.6, "max eta extend between vertex and MDT hit"}
Gaudi::Property< double > m_nMDTHitsPhi {this, "nMDTHitsPhi", 0.6*Gaudi::Units::radian, "max phi extend between vertex and MDT hit"}
Gaudi::Property< double > m_nTrigHitsdR {this, "nTrigHitsdR", 0.6*Gaudi::Units::radian, "max delta R between vertex and trigger chamber (RPC or TGC) hit"}
Gaudi::Property< int > m_MinMDTHits {this, "MinMDTHits", 250, "minimal number of MDT hits"}
Gaudi::Property< int > m_MinTrigHits {this, "MinTrigHits", 200, "minimal number of trigger chamber (RPC+TGC) hits"}
Gaudi::Property< double > m_MaxLxyEndcap {this, "MaxLxyEndcap", 10000*Gaudi::Units::millimeter, "maximal transverse distance for endcap vertex in mm"}
Gaudi::Property< double > m_MinZEndcap {this, "MinZEndcap", 8000*Gaudi::Units::millimeter, "minimal longitudinal distance for endcap vertex in mm"}
Gaudi::Property< double > m_MaxZEndcap {this, "MaxZEndcap", 14000*Gaudi::Units::millimeter, "maximal longitudinal distance for endcap vertex in mm"}
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default)
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default)
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

Definition at line 41 of file MSVertexRecoTool.h.

Member Typedef Documentation

◆ StoreGateSvc_t

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

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ MSVertexRecoTool()

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

Definition at line 29 of file MSVertexRecoTool.cxx.

29 :
30 AthAlgTool(type, name, parent) {
31 declareInterface<IMSVertexRecoTool>(this);
32 }
AthAlgTool()
Default constructor:

◆ ~MSVertexRecoTool()

virtual Muon::MSVertexRecoTool::~MSVertexRecoTool ( )
virtualdefault

Member Function Documentation

◆ ClusterizeTracks()

std::optional< Muon::MSVertexRecoTool::TrkCluster > Muon::MSVertexRecoTool::ClusterizeTracks ( std::vector< Tracklet > & tracks) const
private

Definition at line 178 of file MSVertexRecoTool.cxx.

178 {
179 // returns the best cluster of tracklets and removes them from the input vector for the next iteration
180
181 if (tracks.size() > m_maxClusterTracklets) {
182 ATH_MSG_DEBUG("Too many tracks found, returning empty cluster");
183 return std::nullopt;
184 }
185
186 std::vector<TrkCluster> trkClu;
187 std::vector<TrkCluster> trkClu0;
188 // use each tracklet as a seed for the clusters
189 int ncluster = 0;
190 for (const Tracklet& trk : tracks) {
191 TrkCluster clu;
192 clu.eta = trk.globalPosition().eta();
193 clu.phi = trk.globalPosition().phi();
194
195 trkClu.push_back(clu);
196 trkClu0.push_back(clu);
197 ++ncluster;
198 if (ncluster >= 99) {
199 return std::nullopt;
200 }
201 }
202
203 // loop on the clusters and let the center move to find the optimal cluster centers
204 for (TrkCluster& clu : trkClu) {
205 // add tracklets to the cluster and update it
206 int ntracks = 0;
207 for (const TrkCluster& trk : trkClu0) {
208 double dEta = clu.eta - trk.eta;
209 double dPhi = xAOD::P4Helpers::deltaPhi(clu.phi , trk.phi);
210 if (std::abs(dEta) < m_ClusterdEta && std::abs(dPhi) < m_ClusterdPhi) {
211 ++ntracks;
212 clu.eta = clu.eta - dEta / ntracks;
213 clu.phi = xAOD::P4Helpers::deltaPhi(clu.phi - dPhi / ntracks, 0);
214 }
215 }
216
217 // the updated cluster position might cause tracklets considered near the start of the loop to now lie inside or outside the cluster
218 // run over all tracklets again to check is any more tracklets are picked up. Is so, do this at most 5 times
219 // *_best store the centre of the cluster containing the most tracklets
220 double eta_best = clu.eta;
221 double phi_best = clu.phi;
222 int nitr = 0;
223 bool improvement = true;
224 while (improvement) {
225 unsigned int ntracks_new = 0;
226 double eta_new = 0.0;
227 double phi_new = 0.0;
228 double cosPhi_new = 0.0;
229 double sinPhi_new = 0.0;
230
231 for (const TrkCluster& trk : trkClu0) {
232 double dEta = clu.eta - trk.eta;
233 double dPhi = xAOD::P4Helpers::deltaPhi(clu.phi , trk.phi);
234 if (std::abs(dEta) < m_ClusterdEta && std::abs(dPhi) < m_ClusterdPhi) {
235 eta_new += trk.eta;
236 cosPhi_new += std::cos(trk.phi);
237 sinPhi_new += std::sin(trk.phi);
238 ++ntracks_new;
239 }
240 }
241
242 eta_new = eta_new / ntracks_new;
243 phi_new = std::atan2(sinPhi_new / ntracks_new, cosPhi_new / ntracks_new);
244
245 if (ntracks_new > clu.ntrks) {
246 // better cluster found - update the centre and number of tracklets
247 eta_best = clu.eta; // not eta_new in case the iteration threshold was exceeded
248 phi_best = clu.phi;
249 clu.ntrks = ntracks_new;
250 if (nitr < 6) {
251 // update the cluster for the next improvement iteration
252 clu.eta = eta_new;
253 clu.phi = phi_new;
254 }
255 else
256 break;
257 }
258 else {
259 clu.eta = eta_best;
260 clu.phi = phi_best;
261 improvement = false;
262 }
263 ++nitr;
264 } // end while loop to check for cluster improvements
265 } // end loop over clusters
266
267 // find the best cluster as the one containing the most tracklets
268 TrkCluster& BestCluster = trkClu[0];
269 for (const TrkCluster& clu : trkClu) {
270 if (clu.ntrks > BestCluster.ntrks) BestCluster = clu;
271 }
272
273 // store the tracks inside the cluster
274 std::vector<Tracklet> unusedTracks;
275 for (const Tracklet& trk : tracks) {
276 double dEta = BestCluster.eta - trk.globalPosition().eta();
277 double dPhi = xAOD::P4Helpers::deltaPhi(BestCluster.phi , trk.globalPosition().phi());
278 if (std::abs(dEta) < m_ClusterdEta && std::abs(dPhi) < m_ClusterdPhi)
279 BestCluster.tracks.push_back(trk);
280 else
281 unusedTracks.push_back(trk);
282 }
283 // return the best cluster and the unused tracklets
284 tracks = std::move(unusedTracks);
285 return BestCluster;
286 }
#define ATH_MSG_DEBUG(x)
Gaudi::Property< unsigned int > m_maxClusterTracklets
Gaudi::Property< double > m_ClusterdPhi
Gaudi::Property< double > m_ClusterdEta
bool dPhi(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
bool dEta(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[

◆ declareGaudiProperty()

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 {
160 hndl.value(),
161 hndl.documentation());
162
163 }
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

◆ DeclareInterfaceID()

Muon::IMSVertexRecoTool::DeclareInterfaceID ( Muon::IMSVertexRecoTool ,
1 ,
0  )
inherited

access to tool interface

◆ declareProperty()

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 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

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

◆ dressVtxHits()

void Muon::MSVertexRecoTool::dressVtxHits ( xAOD::Vertex * xAODVx,
const std::vector< SG::AuxElement::Accessor< int > > & accs,
const std::vector< int > & hits ) const
private

Definition at line 798 of file MSVertexRecoTool.cxx.

798 {
799 unsigned int i{0};
800 for (const SG::AuxElement::Accessor<int> &acc : accs) {
801 acc(*xAODVx) = hits[i];
802 ++i;
803 }
804
805 return;
806 }
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572

◆ EndcapHasBadTrack()

bool Muon::MSVertexRecoTool::EndcapHasBadTrack ( const std::vector< Tracklet > & tracklets,
const Amg::Vector3D & Vx ) const
private

Definition at line 782 of file MSVertexRecoTool.cxx.

782 {
783 if (Vx.x() == 0 && Vx.z() == 0) return true;
784 // return true a track is further away from the vertex than m_MaxTollDist
785 for (const Tracklet &track : tracks) {
786 double TrkSlope = std::tan(track.getML1seg().alpha());
787 double TrkInter = track.getML1seg().globalPosition().perp() - track.getML1seg().globalPosition().z() * TrkSlope;
788 double dist = std::abs((TrkSlope * Vx.z() - Vx.x() + TrkInter) / std::hypot(TrkSlope, 1));
789 if (dist > m_MaxTollDist) { return true; }
790 }
791
792 // No tracks found that are too far, so it is okay.
793 return false;
794 }
Gaudi::Property< double > m_MaxTollDist

◆ evtStore()

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.

◆ 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

◆ FillOutputContainer()

StatusCode Muon::MSVertexRecoTool::FillOutputContainer ( const std::vector< std::unique_ptr< MSVertex > > & vertices,
SG::WriteHandle< xAOD::VertexContainer > & xAODVxContainer ) const
private

Definition at line 810 of file MSVertexRecoTool.cxx.

811 {
812 for (const std::unique_ptr<MSVertex> &vtx : vertices){
813 xAOD::Vertex* xAODVx = new xAOD::Vertex();
814 xAODVx->makePrivateStore();
816 xAODVx->setPosition(vtx->getPosition());
817 xAODVx->setFitQuality(vtx->getChi2(), vtx->getNTracks() - 1);
818
819 // link TrackParticle to vertex
820 for (const xAOD::TrackParticle *trk : *(vtx->getTracks())) {
821 ElementLink<xAOD::TrackParticleContainer> link_trk(*(dynamic_cast<const xAOD::TrackParticleContainer *>(trk->container())), trk->index());
822 if (link_trk.isValid()) xAODVx->addTrackAtVertex(link_trk);
823 }
824
825 // store the new xAOD vertex
826 xAODVxContainer->push_back(xAODVx);
827
828 // dress the vertex with the hit counts
829 dressVtxHits(xAODVx, m_nMDT_accs, vtx->getNMDT_all());
830 dressVtxHits(xAODVx, m_nRPC_accs, vtx->getNRPC_all());
831 dressVtxHits(xAODVx, m_nTGC_accs, vtx->getNTGC_all());
832 }
833
834 return StatusCode::SUCCESS;
835 }
void dressVtxHits(xAOD::Vertex *xAODVx, const std::vector< SG::AuxElement::Accessor< int > > &accs, const std::vector< int > &hits) const
std::vector< SG::AuxElement::Accessor< int > > m_nRPC_accs
std::vector< SG::AuxElement::Accessor< int > > m_nMDT_accs
std::vector< SG::AuxElement::Accessor< int > > m_nTGC_accs
void makePrivateStore()
Create a new (empty) private store for this object.
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
void setVertexType(VxType::VertexType vType)
Set the type of the vertex.
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
@ SecVtx
Secondary vertex.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".

◆ findMSvertices()

StatusCode Muon::MSVertexRecoTool::findMSvertices ( const std::vector< Tracklet > & tracklets,
std::vector< std::unique_ptr< MSVertex > > & vertices,
const EventContext & ctx ) const
overridevirtual

Implements Muon::IMSVertexRecoTool.

Definition at line 55 of file MSVertexRecoTool.cxx.

56 {
57 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
58 rngWrapper->setSeed(name(), ctx);
59 CLHEP::HepRandomEngine* rndmEngine = rngWrapper->getEngine(ctx);
60
61 SG::WriteHandle<xAOD::VertexContainer> xAODVxContainer(m_xAODContainerKey, ctx);
62 ATH_CHECK(xAODVxContainer.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()));
63
64 if (tracklets.size() < 3) {
65 ATH_MSG_DEBUG("Fewer than 3 tracks found, vertexing not possible. Exiting...");
66 return StatusCode::SUCCESS;
67 }
68
69 if (tracklets.size() > m_maxGlobalTracklets) {
70 ATH_MSG_DEBUG("Too many tracklets found globally. Exiting...");
71 return StatusCode::SUCCESS;
72 }
73
74 // group the tracks
75 std::vector<Tracklet> BarrelTracklets;
76 std::vector<Tracklet> EndcapTracklets;
77 for (const Tracklet &tracklet : tracklets){
78 if (m_idHelperSvc->mdtIdHelper().isBarrel(tracklet.muonIdentifier()))
79 BarrelTracklets.push_back(tracklet);
80 else if (m_idHelperSvc->mdtIdHelper().isEndcap(tracklet.muonIdentifier()))
81 EndcapTracklets.push_back(tracklet);
82 }
83
84 if (BarrelTracklets.size() > m_maxClusterTracklets || EndcapTracklets.size() > m_maxClusterTracklets) {
85 ATH_MSG_DEBUG("Too many tracklets found in barrel or endcap for clustering. Exiting...");
86 return StatusCode::SUCCESS;
87 }
88
89 ATH_MSG_DEBUG("Running on event with " << BarrelTracklets.size() << " barrel tracklets, " << EndcapTracklets.size()
90 << " endcap tracklets.");
91
92 // find any clusters of tracks & decide if tracks are from single muon
93 std::vector<Muon::MSVertexRecoTool::TrkCluster> BarrelClusters = findTrackClusters(BarrelTracklets);
94 std::vector<Muon::MSVertexRecoTool::TrkCluster> EndcapClusters = findTrackClusters(EndcapTracklets);
95
96 // if doSystematics, remove tracklets according to the tracklet reco uncertainty and rerun the cluster finder
97 if (m_doSystematics) {
98 std::vector<Tracklet> BarrelSystTracklets, EndcapSystTracklets;
99 for (const Tracklet &BarrelTracklet : BarrelTracklets) {
100 double prob = CLHEP::RandFlat::shoot(rndmEngine, 0, 1);
101 if (prob > m_BarrelTrackletUncert) BarrelSystTracklets.push_back(BarrelTracklet);
102 }
103 if (BarrelSystTracklets.size() >= 3) {
104 std::vector<Muon::MSVertexRecoTool::TrkCluster> BarrelSystClusters = findTrackClusters(BarrelSystTracklets);
105 for (Muon::MSVertexRecoTool::TrkCluster &BarrelSystCluster : BarrelSystClusters) {
106 BarrelSystCluster.isSystematic = true;
107 BarrelClusters.push_back(BarrelSystCluster);
108 }
109 }
110
111 for (const Tracklet &EndcapTracklet : EndcapTracklets) {
112 double prob = CLHEP::RandFlat::shoot(rndmEngine, 0, 1);
113 if (prob > m_EndcapTrackletUncert) EndcapSystTracklets.push_back(EndcapTracklet);
114 }
115 if (EndcapSystTracklets.size() >= 3) {
116 std::vector<Muon::MSVertexRecoTool::TrkCluster> EndcapSystClusters = findTrackClusters(EndcapSystTracklets);
117 for (Muon::MSVertexRecoTool::TrkCluster &EndcapSystCluster : EndcapSystClusters) {
118 EndcapSystCluster.isSystematic = true;
119 EndcapClusters.push_back(EndcapSystCluster);
120 }
121 }
122 }
123
125 // find vertices in the barrel MS (vertices using barrel tracklets)
126 for (const Muon::MSVertexRecoTool::TrkCluster &BarrelCluster : BarrelClusters) {
127 if (BarrelCluster.ntrks < 3) continue;
128 ATH_MSG_DEBUG("Attempting to build vertex from " << BarrelCluster.ntrks << " tracklets in the barrel");
129 std::unique_ptr<MSVertex> barvertex(nullptr);
130 MSVxFinder(BarrelCluster.tracks, barvertex, ctx);
131 if (!barvertex) continue;
132 // barrel minimum good vertex criteria
133 if (barvertex->getChi2Probability() > m_VxChi2ProbCUT) {
134 HitCounter(barvertex.get(), ctx);
135 if (barvertex->getNMDT() > m_MinMDTHits && (barvertex->getNRPC() + barvertex->getNTGC()) > m_MinTrigHits) {
136 ATH_MSG_DEBUG("Vertex found in the barrel with n_trk = " << barvertex->getNTracks() << " located at (eta,phi) = ("
137 << barvertex->getPosition().eta() << ", "
138 << barvertex->getPosition().phi() << ")");
139 if (BarrelCluster.isSystematic) barvertex->setAuthor(3);
140 vertices.push_back(std::move(barvertex));
141 }
142 }
143 }
144
145 // find vertices in the endcap MS (vertices using endcap tracklets)
146 for (const Muon::MSVertexRecoTool::TrkCluster &EndcapCluster : EndcapClusters) {
147 if (EndcapCluster.ntrks < 3) continue;
148 ATH_MSG_DEBUG("Attempting to build vertex from " << EndcapCluster.ntrks << " tracklets in the endcap");
149
150 std::unique_ptr<MSVertex> endvertex(nullptr);
152 MSStraightLineVx_oldMethod(EndcapCluster.tracks, endvertex, ctx);
153 else
154 MSStraightLineVx(EndcapCluster.tracks, endvertex, ctx);
155
156 if (!endvertex) continue;
157 // endcap minimum good vertex criteria
158 if (endvertex->getPosition().perp() < m_MaxLxyEndcap && std::abs(endvertex->getPosition().z()) < m_MaxZEndcap &&
159 std::abs(endvertex->getPosition().z()) > m_MinZEndcap && endvertex->getNTracks() >= 3) {
160 HitCounter(endvertex.get(), ctx);
161 if (endvertex->getNMDT() > m_MinMDTHits && (endvertex->getNRPC() + endvertex->getNTGC()) > m_MinTrigHits) {
162 ATH_MSG_DEBUG("Vertex found in the endcap with n_trk = " << endvertex->getNTracks() << " located at (eta,phi) = ("
163 << endvertex->getPosition().eta() << ", "
164 << endvertex->getPosition().phi() << ")");
165 if (EndcapCluster.isSystematic) endvertex->setAuthor(4);
166 vertices.push_back(std::move(endvertex));
167 }
168 }
169
170 } // end loop on endcap tracklet clusters
171
172 ATH_CHECK(FillOutputContainer(vertices, xAODVxContainer));
173 return StatusCode::SUCCESS;
174 } // end find vertices
#define ATH_CHECK
Evaluate an expression and check for errors.
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
Gaudi::Property< bool > m_useOldMSVxEndcapMethod
Gaudi::Property< double > m_MaxZEndcap
Gaudi::Property< int > m_MinTrigHits
StatusCode FillOutputContainer(const std::vector< std::unique_ptr< MSVertex > > &, SG::WriteHandle< xAOD::VertexContainer > &xAODVxContainer) const
void MSStraightLineVx(const std::vector< Tracklet > &trks, std::unique_ptr< MSVertex > &vtx, const EventContext &ctx) const
Gaudi::Property< double > m_MinZEndcap
Gaudi::Property< double > m_VxChi2ProbCUT
Gaudi::Property< double > m_EndcapTrackletUncert
void MSVxFinder(const std::vector< Tracklet > &tracklets, std::unique_ptr< MSVertex > &vtx, const EventContext &ctx) const
void HitCounter(MSVertex *MSRecoVx, const EventContext &ctx) const
Gaudi::Property< unsigned int > m_maxGlobalTracklets
Gaudi::Property< double > m_MaxLxyEndcap
Gaudi::Property< bool > m_doSystematics
void MSStraightLineVx_oldMethod(const std::vector< Tracklet > &trks, std::unique_ptr< MSVertex > &vtx, const EventContext &ctx) const
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
SG::WriteHandleKey< xAOD::VertexContainer > m_xAODContainerKey
Gaudi::Property< double > m_BarrelTrackletUncert
Gaudi::Property< int > m_MinMDTHits
std::vector< TrkCluster > findTrackClusters(const std::vector< Tracklet > &tracklets) const

◆ findTrackClusters()

std::vector< Muon::MSVertexRecoTool::TrkCluster > Muon::MSVertexRecoTool::findTrackClusters ( const std::vector< Tracklet > & tracklets) const
private

Definition at line 290 of file MSVertexRecoTool.cxx.

290 {
291 // only clusters with 3 or more tracklets are returned
292 std::vector<Tracklet> trks = tracks;
293 std::vector<TrkCluster> clusters;
294 // keep making clusters until there are no more possible
295 while (true) {
296 if (trks.size() < 3) break;
297 std::optional<TrkCluster> clust = ClusterizeTracks(trks);
298 if (clust && clust->ntrks>=3) clusters.push_back(clust.value());
299 else break;
300 }
301
302 return clusters;
303 }
std::optional< TrkCluster > ClusterizeTracks(std::vector< Tracklet > &tracks) const

◆ getTracklets()

std::vector< Tracklet > Muon::MSVertexRecoTool::getTracklets ( const std::vector< Tracklet > & trks,
const std::set< int > & tracklet_subset ) const
private

Definition at line 770 of file MSVertexRecoTool.cxx.

770 {
771 std::vector<Tracklet> returnVal;
772 for (std::set<int>::const_iterator itr = tracklet_subset.cbegin(); itr != tracklet_subset.cend(); ++itr) {
773 if ((unsigned int)*itr > trks.size()) ATH_MSG_ERROR("ERROR - Index out of bounds in getTracklets");
774 returnVal.push_back(trks.at(*itr));
775 }
776
777 return returnVal;
778 }
#define ATH_MSG_ERROR(x)

◆ HitCounter()

void Muon::MSVertexRecoTool::HitCounter ( MSVertex * MSRecoVx,
const EventContext & ctx ) const
private

Definition at line 932 of file MSVertexRecoTool.cxx.

932 {
933 // count the hits (MDT, RPC & TGC) around the vertex and split them by layer
934 int nHighOccupancy(0);
935 int stationRegion(-1);
936 // Amg::Vector3D.eta() will crash via floating point exception if both x() and y() are zero (eta=inf)
937 // thus, check it manually here:
938 const Amg::Vector3D msVtxPos = MSRecoVx->getPosition();
939 if (msVtxPos.x() == 0 && msVtxPos.y() == 0 && msVtxPos.z() != 0) {
940 ATH_MSG_WARNING("given MSVertex has position x=y=0 and z!=0, eta() method will cause FPE, returning...");
941 return;
942 }
943
944 // MDTs -- count the number around the vertex
945 SG::ReadHandle<Muon::MdtPrepDataContainer> mdtTES(m_mdtTESKey, ctx);
946 if (!mdtTES.isValid()) ATH_MSG_ERROR("Unable to retrieve the MDT hits");
947 int nmdt(0), nmdt_inwards(0), nmdt_I(0), nmdt_E(0), nmdt_M(0), nmdt_O(0);
948 // loop on the MDT collections, a collection corresponds to a chamber
949 for(const Muon::MdtPrepDataCollection* MDT_coll : *mdtTES){
950 if (MDT_coll->empty()) continue;
951 Muon::MdtPrepDataCollection::const_iterator mdtItr = MDT_coll->begin();
952 Amg::Vector3D ChamberCenter = (*mdtItr)->detectorElement()->center();
953 double deta = msVtxPos.eta() - ChamberCenter.eta();
954 if (std::abs(deta) > m_nMDTHitsEta) continue;
955 double dphi = xAOD::P4Helpers::deltaPhi(msVtxPos.phi(),ChamberCenter.phi());
956 if (std::abs(dphi) > m_nMDTHitsPhi) continue;
957
958 Identifier id = (*mdtItr)->identify();
959 stationRegion = m_idHelperSvc->mdtIdHelper().stationRegion(id);
960 auto [tubeLayerMin, tubeLayerMax] = m_idHelperSvc->mdtIdHelper().tubeLayerMinMax(id);
961 auto [tubeMin, tubeMax] = m_idHelperSvc->mdtIdHelper().tubeMinMax(id);
962 double nTubes = (tubeLayerMax - tubeLayerMin + 1) * (tubeMax - tubeMin + 1);
963
964 int nChHits(0), nChHits_inwards(0);
965 // loop on the MDT hits in the chamber
966 for (const Muon::MdtPrepData* mdt : *MDT_coll){
967 if (mdt->adc() < 50) continue;
968 if (mdt->status() != 1) continue;
969 if (mdt->localPosition()[Trk::locR] == 0.) continue;
970 ++nChHits;
971 if (mdt->globalPosition().mag() < msVtxPos.mag()) ++nChHits_inwards;
972 }
973 nmdt += nChHits;
974 nmdt_inwards += nChHits_inwards;
975 double ChamberOccupancy = nChHits / nTubes;
976 if (ChamberOccupancy > m_ChamberOccupancyMin) ++nHighOccupancy;
977
978 if (stationRegion == 0) nmdt_I += nChHits;
979 else if (stationRegion == 1) nmdt_E += nChHits;
980 else if (stationRegion == 2) nmdt_M += nChHits;
981 else if (stationRegion == 3) nmdt_O += nChHits;
982 }
983 ATH_MSG_DEBUG("Found " << nHighOccupancy << " chambers near the MS vertex with occupancy greater than " << m_ChamberOccupancyMin);
984 if (nHighOccupancy < m_minHighOccupancyChambers) return;
985
986 // RPC -- count the number around the vertex
987 SG::ReadHandle<Muon::RpcPrepDataContainer> rpcTES(m_rpcTESKey, ctx);
988 if (!rpcTES.isValid()) ATH_MSG_ERROR("Unable to retrieve the RPC hits");
989 int nrpc(0), nrpc_inwards(0), nrpc_I(0), nrpc_E(0), nrpc_M(0), nrpc_O(0);
990 for (const Muon::RpcPrepDataCollection* RPC_coll : *rpcTES){
991 Muon::RpcPrepDataCollection::const_iterator rpcItr = RPC_coll->begin();
992 stationRegion = m_idHelperSvc->rpcIdHelper().stationRegion((*rpcItr)->identify());
993 int nChHits(0), nChHits_inwards(0);
994 for (const Muon::RpcPrepData* rpc : *RPC_coll){
995 double rpcEta = rpc->globalPosition().eta();
996 double rpcPhi = rpc->globalPosition().phi();
997 double DR = xAOD::P4Helpers::deltaR(msVtxPos.eta(), msVtxPos.phi(), rpcEta, rpcPhi);
998 if (DR < m_nTrigHitsdR) {
999 ++nChHits;
1000 if (rpc->globalPosition().mag() < msVtxPos.mag()) ++nChHits_inwards;
1001 }
1002 if (DR > 1.2) break;
1003 }
1004 nrpc += nChHits;
1005 nrpc_inwards += nChHits_inwards;
1006 if (stationRegion == 0) nrpc_I += nChHits;
1007 else if (stationRegion == 1) nrpc_E += nChHits;
1008 else if (stationRegion == 2) nrpc_M += nChHits;
1009 else if (stationRegion == 3) nrpc_O += nChHits;
1010 }
1011
1012 // TGC -- count the number around the vertex
1013 SG::ReadHandle<Muon::TgcPrepDataContainer> tgcTES(m_tgcTESKey, ctx);
1014 if (!tgcTES.isValid()) ATH_MSG_ERROR("Unable to retrieve the TGC hits");
1015 int ntgc(0), ntgc_inwards(0), ntgc_I(0), ntgc_E(0), ntgc_M(0), ntgc_O(0);
1016 for (const Muon::TgcPrepDataCollection* TGC_coll : *tgcTES){
1017 Muon::TgcPrepDataCollection::const_iterator tgcItr = TGC_coll->begin();
1018 stationRegion = m_idHelperSvc->tgcIdHelper().stationRegion((*tgcItr)->identify());
1019 int nChHits(0), nChHits_inwards(0);
1020 for (const Muon::TgcPrepData* tgc : *TGC_coll){
1021 double tgcEta = tgc->globalPosition().eta();
1022 double tgcPhi = tgc->globalPosition().phi();
1023 double DR = xAOD::P4Helpers::deltaR(msVtxPos.eta(), msVtxPos.phi(), tgcEta, tgcPhi);
1024 if (DR < m_nTrigHitsdR) {
1025 ++nChHits;
1026 if (tgc->globalPosition().mag() < msVtxPos.mag()) ++nChHits_inwards;
1027 }
1028 if (DR > 1.2) break;
1029 }
1030 ntgc += nChHits;
1031 ntgc_inwards += nChHits_inwards;
1032 if (stationRegion == 0) ntgc_I += nChHits;
1033 else if (stationRegion == 1) ntgc_E += nChHits;
1034 else if (stationRegion == 2) ntgc_M += nChHits;
1035 else if (stationRegion == 3) ntgc_O += nChHits;
1036 }
1037
1038 // store the hit counts in the MSVertex object
1039 MSRecoVx->setNMDT(nmdt, nmdt_inwards, nmdt_I, nmdt_E, nmdt_M, nmdt_O);
1040 MSRecoVx->setNRPC(nrpc, nrpc_inwards, nrpc_I, nrpc_E, nrpc_M, nrpc_O);
1041 MSRecoVx->setNTGC(ntgc, ntgc_inwards, ntgc_I, ntgc_E, ntgc_M, ntgc_O);
1042 }
#define ATH_MSG_WARNING(x)
double tubeMax
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const Amg::Vector3D & getPosition() const
Definition MSVertex.cxx:28
void setNRPC(const int, const int, const int, const int, const int, const int)
Definition MSVertex.cxx:54
void setNMDT(const int, const int, const int, const int, const int, const int)
Definition MSVertex.cxx:45
void setNTGC(const int, const int, const int, const int, const int, const int)
Definition MSVertex.cxx:63
Gaudi::Property< double > m_ChamberOccupancyMin
Gaudi::Property< double > m_nMDTHitsPhi
Gaudi::Property< int > m_minHighOccupancyChambers
Gaudi::Property< double > m_nMDTHitsEta
SG::ReadHandleKey< Muon::MdtPrepDataContainer > m_mdtTESKey
SG::ReadHandleKey< Muon::RpcPrepDataContainer > m_rpcTESKey
SG::ReadHandleKey< Muon::TgcPrepDataContainer > m_tgcTESKey
Gaudi::Property< double > m_nTrigHitsdR
Eigen::Matrix< double, 3, 1 > Vector3D
MuonPrepDataCollection< TgcPrepData > TgcPrepDataCollection
MuonPrepDataCollection< MdtPrepData > MdtPrepDataCollection
MuonPrepDataCollection< RpcPrepData > RpcPrepDataCollection
@ locR
Definition ParamDefs.h:44
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi

◆ initialize()

StatusCode Muon::MSVertexRecoTool::initialize ( void )
overridevirtual

Definition at line 36 of file MSVertexRecoTool.cxx.

36 {
37 ATH_CHECK(m_idHelperSvc.retrieve());
38 ATH_CHECK(m_rndmSvc.retrieve());
39
40 ATH_CHECK(m_extrapolator.retrieve());
41 ATH_CHECK(m_xAODContainerKey.initialize());
42 ATH_CHECK(m_rpcTESKey.initialize());
43 ATH_CHECK(m_tgcTESKey.initialize());
44 ATH_CHECK(m_mdtTESKey.initialize());
45
46 for (const std::string& str : m_accMDT_str) m_nMDT_accs.push_back(SG::AuxElement::Accessor<int>(str));
47 for (const std::string& str : m_accRPC_str) m_nRPC_accs.push_back(SG::AuxElement::Accessor<int>(str));
48 for (const std::string& str : m_accTGC_str) m_nTGC_accs.push_back(SG::AuxElement::Accessor<int>(str));
49
50 return StatusCode::SUCCESS;
51 }
const std::vector< std::string > m_accMDT_str
const std::vector< std::string > m_accTGC_str
ToolHandle< Trk::IExtrapolator > m_extrapolator
const std::vector< std::string > m_accRPC_str

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

◆ msg()

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

Definition at line 24 of file AthCommonMsg.h.

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

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

◆ MSStraightLineVx()

void Muon::MSVertexRecoTool::MSStraightLineVx ( const std::vector< Tracklet > & trks,
std::unique_ptr< MSVertex > & vtx,
const EventContext & ctx ) const
private

Definition at line 607 of file MSVertexRecoTool.cxx.

608 {
609 // Running set of all vertices found. The inner set is the indices of trks that are used to make the vertex
610 std::set<std::set<int> > prelim_vx;
611
612 // We don't consider all 3-tracklet combinations when a high number of tracklets is found
613 // Faster method is used for > 40 tracklets
614 if (trks.size() > 40) {
615 MSStraightLineVx_oldMethod(trks, vtx, ctx);
616 return;
617 }
618
619 // Okay, if we get here then we know there's 40 or fewer tracklets in the cluster.
620 // Make a list of all 3-tracklet combinations that make vertices
621 for (unsigned int i = 0; i < trks.size() - 2; ++i) {
622 for (unsigned int j = i + 1; j < trks.size() - 1; ++j) {
623 for (unsigned int k = j + 1; k < trks.size(); ++k) {
624 std::set<int> tmpTracks;
625 tmpTracks.insert(i);
626 tmpTracks.insert(j);
627 tmpTracks.insert(k);
628
629 Amg::Vector3D MyVx;
630 MyVx = VxMinQuad(getTracklets(trks, tmpTracks));
631 if (MyVx.perp() < 10000 && std::abs(MyVx.z()) > 7000 && std::abs(MyVx.z()) < 15000 &&
632 !EndcapHasBadTrack(getTracklets(trks, tmpTracks), MyVx))
633 prelim_vx.insert(tmpTracks);
634 }
635 }
636 }
637
638 // If no preliminary vertices were found from 3 tracklets, then there is no vertex and we are done.
639 if (prelim_vx.empty()) return;
640
641 // The remaining algorithm is very time consuming for large numbers of tracklets. To control this,
642 // we run the old algorithm when there are too many tracklets and a vertex is found.
643 if (trks.size() <= 20) {
644 std::set<std::set<int> > new_prelim_vx = prelim_vx;
645 std::set<std::set<int> > old_prelim_vx;
646
647 int foundNewVx = true;
648 while (foundNewVx) {
649 foundNewVx = false;
650
651 old_prelim_vx = new_prelim_vx;
652 new_prelim_vx.clear();
653
654 for (std::set<std::set<int> >::iterator itr = old_prelim_vx.begin(); itr != old_prelim_vx.end(); ++itr) {
655 for (unsigned int i_trks = 0; i_trks < trks.size(); ++i_trks) {
656 std::set<int> tempCluster = *itr;
657 if (tempCluster.insert(i_trks).second) {
658 Amg::Vector3D MyVx = VxMinQuad(getTracklets(trks, tempCluster));
659 if (MyVx.perp() < 10000 && std::abs(MyVx.z()) > 7000 && std::abs(MyVx.z()) < 15000 &&
660 !EndcapHasBadTrack(getTracklets(trks, tempCluster), MyVx)) {
661 new_prelim_vx.insert(tempCluster);
662 prelim_vx.insert(tempCluster);
663 foundNewVx = true;
664 }
665 }
666 }
667 }
668 }
669 } else {
670 // Since there are 20 or more tracklets, we're going to use the old MSVx finding method. Note that
671 // if the old method fails, we do not return here; in this case a 3-tracklet vertex that was found
672 // earlier in this algorithm will be returned
673 MSStraightLineVx_oldMethod(trks, vtx, ctx);
674 if (vtx) return;
675 }
676
677 // Find the preliminary vertex with the maximum number of tracklets - that is the final vertex. If
678 // multiple preliminary vertices with same number of tracklets, the first one found is returned
679 std::set<std::set<int> >::iterator prelim_vx_max = prelim_vx.begin();
680 for (std::set<std::set<int> >::iterator itr = prelim_vx.begin(); itr != prelim_vx.end(); ++itr) {
681 if ((*itr).size() > (*prelim_vx_max).size()) prelim_vx_max = itr;
682 }
683
684 std::vector<Tracklet> tracklets = getTracklets(trks, *prelim_vx_max);
685 // use tracklets to estimate the line of flight of decaying particle
686 double aveX(0);
687 double aveY(0);
688 for (const Tracklet &trk : tracklets) {
689 aveX += trk.globalPosition().x();
690 aveY += trk.globalPosition().y();
691 }
692
693 Amg::Vector3D MyVx = VxMinQuad(tracklets);
694 double vxtheta = std::atan2(MyVx.x(), MyVx.z());
695 double tracklet_vxphi = std::atan2(aveY, aveX);
696 double vxphi = vxPhiFinder(std::abs(vxtheta), tracklet_vxphi, ctx);
697
698 Amg::Vector3D vxpos(MyVx.x() * std::cos(vxphi), MyVx.x() * std::sin(vxphi), MyVx.z());
699
700 std::vector<const xAOD::TrackParticle*> vxTrackParticles;
701 for (const Tracklet &trk : tracklets) vxTrackParticles.push_back(trk.getTrackParticle());
702
703 vtx = std::make_unique<MSVertex>(2, vxpos, vxTrackParticles, 1, vxTrackParticles.size(), 0, 0, 0);
704 }
double vxPhiFinder(const double theta, const double phi, const EventContext &ctx) const
bool EndcapHasBadTrack(const std::vector< Tracklet > &tracklets, const Amg::Vector3D &Vx) const
std::vector< Tracklet > getTracklets(const std::vector< Tracklet > &trks, const std::set< int > &tracklet_subset) const
static Amg::Vector3D VxMinQuad(const std::vector< Tracklet > &tracks)

◆ MSStraightLineVx_oldMethod()

void Muon::MSVertexRecoTool::MSStraightLineVx_oldMethod ( const std::vector< Tracklet > & trks,
std::unique_ptr< MSVertex > & vtx,
const EventContext & ctx ) const
private

Definition at line 709 of file MSVertexRecoTool.cxx.

710 {
711 // find the line of flight
712 double aveX(0), aveY(0);
713 for (const Tracklet &trk : trks) {
714 aveX += trk.globalPosition().x();
715 aveY += trk.globalPosition().y();
716 }
717 double vxphi = std::atan2(aveY, aveX);
718
719 Amg::Vector3D MyVx(0, 0, 0);
720 std::vector<Tracklet> tracks = RemoveBadTrk(trks, MyVx);
721 if (tracks.size() < 2) return;
722
723 // remove back tracks one by one until non are considered bad (large distance from the vertex)
724 while (true) {
725 MyVx = VxMinQuad(tracks);
726 std::vector<Tracklet> Tracks = RemoveBadTrk(tracks, MyVx);
727 if (tracks.size() == Tracks.size()) break;
728 tracks = std::move(Tracks);
729 }
730
731 if (tracks.size() >= 3 && MyVx.x() > 0) {
732 double vxtheta = std::atan2(MyVx.x(), MyVx.z());
733 vxphi = vxPhiFinder(std::abs(vxtheta), vxphi, ctx);
734 Amg::Vector3D vxpos(MyVx.x() * std::cos(vxphi), MyVx.x() * std::sin(vxphi), MyVx.z());
735
736 std::vector<const xAOD::TrackParticle*> vxTrackParticles;
737 for (const Tracklet &trk : tracks) vxTrackParticles.push_back(trk.getTrackParticle());
738
739 vtx = std::make_unique<MSVertex>(2, vxpos, vxTrackParticles, 1, (double)vxTrackParticles.size(), 0, 0, 0);
740 }
741 }
std::vector< Tracklet > RemoveBadTrk(const std::vector< Tracklet > &tracklets, const Amg::Vector3D &Vx) const

◆ MSVxFinder()

void Muon::MSVertexRecoTool::MSVxFinder ( const std::vector< Tracklet > & tracklets,
std::unique_ptr< MSVertex > & vtx,
const EventContext & ctx ) const
private

Definition at line 307 of file MSVertexRecoTool.cxx.

308 {
309 int nTrkToVertex(0);
310 double NominalAngle(m_TrackPhiAngle.value()), RotationAngle(m_TrackPhiAngle.value() + m_TrackPhiRotation.value());
311
312 Amg::Vector3D aveTrkPos(0, 0, 0);
313 for (const Tracklet &trk : tracklets) aveTrkPos += trk.globalPosition();
314 aveTrkPos /= tracklets.size();
315
316 // calculate the two angles (theta & phi)
317 double avePhi = aveTrkPos.phi();
318 double LoF = std::atan2(aveTrkPos.perp(), aveTrkPos.z()); // Line of Flight (theta)
319 avePhi = vxPhiFinder(std::abs(LoF), avePhi, ctx);
320
321 // find the positions of the radial planes
322 std::vector<double> Rpos;
324 double LoFdist = std::abs(RadialDist / std::sin(LoF));
325 int nplanes = LoFdist / m_VxPlaneDist + 1;
326 double PlaneSpacing = std::abs(m_VxPlaneDist / std::cos(LoF));
327 for (int k = 0; k < nplanes; ++k) Rpos.push_back(m_VertexMinRadialPlane + PlaneSpacing * k);
328
329 // loop on barrel tracklets and create two types of track parameters -- nominal and phi shifted tracklets
330 std::array< std::vector<std::unique_ptr<Trk::TrackParameters>>, MAXPLANES> TracksForVertexing{}; // vector of tracklets to be used at each vertex plane
331 std::array< std::vector<std::unique_ptr<Trk::TrackParameters>>, MAXPLANES> TracksForErrors{}; // vector of tracklets to be used for uncertainty at each vertex plane
332 std::array< std::vector<bool>, MAXPLANES> isNeutralTrack{};
333
334 for (const Tracklet &trk : tracklets) {
335 if (m_idHelperSvc->isEndcap(trk.muonIdentifier())) continue;
336 ++nTrkToVertex;
337 // coordinate transform variables
338 Amg::Vector3D trkgpos(trk.globalPosition().perp() * std::cos(avePhi),
339 trk.globalPosition().perp() * std::sin(avePhi),
340 trk.globalPosition().z());
341 double x0 = trkgpos.x();
342 double y0 = trkgpos.y();
343 double r0 = trkgpos.perp();
344
345 // decide which way the tracklet gets rotated -- positive or negative phi
346 double anglesign = xAOD::P4Helpers::deltaPhi(trk.globalPosition().phi(), avePhi) < 0 ? -1.0 : 1.0;
347 double NominalTrkAng = anglesign * NominalAngle; // in case there is a nominal tracklet angle
348 double MaxTrkAng = anglesign * RotationAngle; // the rotated tracklet phi position
349
350 // loop over the radial planes
351 for (int k = 0; k < nplanes; ++k) {
352 // only use tracklets that start AFTER the vertex plane
353 if (Rpos[k] > trk.globalPosition().perp()) break;
354
355 // nominal tracks for vertexing
356 double Xp = Rpos[k] * std::cos(avePhi);
357 double Yp = Rpos[k] * std::sin(avePhi);
358 // in case there is a nominal opening angle, calculate tracklet direction
359 // the tracklet must cross the candidate vertex plane at the correct phi
360 double DelR = std::hypot(x0 - Xp, y0 - Yp) / std::cos(NominalAngle);
361 double X1 = DelR * std::cos(NominalTrkAng + avePhi) + Xp;
362 double Y1 = DelR * std::sin(NominalTrkAng + avePhi) + Yp;
363 double R1 = std::hypot(X1, Y1);
364 double Norm = r0 / R1;
365 X1 = X1 * Norm;
366 Y1 = Y1 * Norm;
367 double Dirmag = std::hypot(X1 - Xp, Y1 - Yp);
368 double Xdir = (X1 - Xp) / Dirmag;
369 double Ydir = (Y1 - Yp) / Dirmag;
370 double trkpx = Xdir * trk.momentum().perp();
371 double trkpy = Ydir * trk.momentum().perp();
372 double trkpz = trk.momentum().z();
373
374 // check if the tracklet has a charge & momentum measurement -- if not, set charge=1 so extrapolator will work
375 double charge = trk.charge();
376 if (std::abs(charge) < 0.1) {
377 charge = 1; // for "straight" tracks, set charge = 1
378 isNeutralTrack[k].push_back(true);
379 } else
380 isNeutralTrack[k].push_back(false);
381
382 // store the tracklet as a Trk::Perigee
383 Amg::Vector3D trkmomentum(trkpx, trkpy, trkpz);
384 Amg::Vector3D trkgpos(X1, Y1, trk.globalPosition().z());
385 AmgSymMatrix(5) covariance = AmgSymMatrix(5)(trk.errorMatrix());
386 TracksForVertexing[k].push_back(std::make_unique<Trk::Perigee>(0., 0., trkmomentum.phi(), trkmomentum.theta(), charge / trkmomentum.mag(), Trk::PerigeeSurface(trkgpos), covariance));
387
388 // tracks for errors -- rotate the plane & recalculate the tracklet parameters
389 double xp = Rpos[k] * std::cos(avePhi);
390 double yp = Rpos[k] * std::sin(avePhi);
391 double delR = std::hypot(x0 - xp, y0 - yp) / std::cos(RotationAngle);
392 double x1 = delR * std::cos(MaxTrkAng + avePhi) + xp;
393 double y1 = delR * std::sin(MaxTrkAng + avePhi) + yp;
394 double r1 = std::hypot(x1, y1);
395 double norm = r0 / r1;
396 x1 = x1 * norm;
397 y1 = y1 * norm;
398 double dirmag = std::hypot(x1 - xp, y1 - yp);
399 double xdir = (x1 - xp) / dirmag;
400 double ydir = (y1 - yp) / dirmag;
401 double errpx = xdir * trk.momentum().perp();
402 double errpy = ydir * trk.momentum().perp();
403 double errpz = trk.momentum().z();
404
405 // store the tracklet as a Trk::Perigee
406 AmgSymMatrix(5) covariance2 = AmgSymMatrix(5)(trk.errorMatrix());
407 Amg::Vector3D trkerrmom(errpx, errpy, errpz);
408 Amg::Vector3D trkerrpos(x1, y1, trk.globalPosition().z());
409 TracksForErrors[k].push_back(std::make_unique<Trk::Perigee>(0., 0., trkerrmom.phi(), trkerrmom.theta(), charge / trkerrmom.mag(), Trk::PerigeeSurface(trkerrpos), covariance2));
410 } // end loop on vertex planes
411 } // end loop on tracks
412
413 // return if there are not enough tracklets
414 if (nTrkToVertex < 3) return;
415
416 // calculate the tracklet positions and uncertainty on each surface
417 bool boundaryCheck = true;
418 std::array<std::vector<double>, MAXPLANES> ExtrapZ{}; // extrapolated z position
419 std::array<std::vector<double>, MAXPLANES> dlength{}; // extrapolated z position uncertainty
420 std::array<std::vector<std::pair<unsigned int, unsigned int>>, MAXPLANES> UsedTracks{};
421 std::array<std::vector<bool>, MAXPLANES> ExtrapSuc{}; // did the extrapolation succeed?
422 std::vector<std::unique_ptr<MSVertex>> vertices; vertices.reserve(nplanes);
423 std::array<std::vector<double>, MAXPLANES> sigmaZ{}; // total uncertainty at each plane
424 std::array<std::vector<Amg::Vector3D>, MAXPLANES> pAtVx{}; // tracklet momentum expressed at the plane
425
426 // extrapolate tracklates and store results at each radial plane
427 for (int k = 0; k < nplanes; ++k) { // loop on planes
428 double rpos = Rpos[k];
429 for (unsigned int i = 0; i < TracksForVertexing[k].size(); ++i) { // loop on tracklets
430 // at least three tracklets per plane are needed
431 if (TracksForVertexing[k].size() < 3) break;
432
433 Amg::Transform3D surfaceTransformMatrix;
434 surfaceTransformMatrix.setIdentity();
435 Trk::CylinderSurface cyl(surfaceTransformMatrix, rpos, 10000.); // create the surface
436 // extrapolate to the surface
437 std::unique_ptr<const Trk::TrackParameters> extrap_par(
438 m_extrapolator->extrapolate(ctx,
439 *TracksForVertexing[k].at(i), cyl, Trk::anyDirection, boundaryCheck, Trk::muon));
440
441 const Trk::AtaCylinder* extrap = dynamic_cast<const Trk::AtaCylinder*>(extrap_par.get());
442
443 if (extrap) {
444 // if the track is neutral just store the uncertainty due to angular uncertainty of the orignal tracklet
445 if (isNeutralTrack[k].at(i)) {
446 double pTot = std::hypot(TracksForVertexing[k].at(i)->momentum().perp(), TracksForVertexing[k].at(i)->momentum().z());
447 double dirErr = Amg::error(*TracksForVertexing[k].at(i)->covariance(), Trk::theta);
448 double extrapRdist = TracksForVertexing[k].at(i)->position().perp() - Rpos[k];
449 double sz = std::abs(20 * dirErr * extrapRdist * std::pow(pTot,2) / std::pow(TracksForVertexing[k].at(i)->momentum().perp(), 2));
450 double ExtrapErr = sz;
451 if (ExtrapErr > m_MaxTrackUncert)
452 ExtrapSuc[k].push_back(false);
453 else {
454 ExtrapSuc[k].push_back(true);
455 std::pair<unsigned int, unsigned int> trkmap(ExtrapZ[k].size(), i);
456 UsedTracks[k].push_back(trkmap);
457 ExtrapZ[k].push_back(extrap->localPosition().y());
458 sigmaZ[k].push_back(sz);
459 pAtVx[k].push_back(extrap->momentum());
460 dlength[k].push_back(0);
461 }
462 } // end neutral tracklets
463 // if the tracklet has a momentum measurement
464 else {
465 // now extrapolate taking into account the extra path length & differing magnetic field
466 Amg::Transform3D srfTransMat2;
467 srfTransMat2.setIdentity();
468 Trk::CylinderSurface cyl2(srfTransMat2, rpos, 10000.);
469 std::unique_ptr<const Trk::TrackParameters> extrap_par2(
470 m_extrapolator->extrapolate(ctx,
471 *TracksForErrors[k].at(i), cyl, Trk::anyDirection, boundaryCheck, Trk::muon));
472 const Trk::AtaCylinder* extrap2 = dynamic_cast<const Trk::AtaCylinder*>(extrap_par2.get());
473
474 if (extrap2) {
475 double sz = Amg::error(*extrap->covariance(), Trk::locY);
476 double zdiff = extrap->localPosition().y() - extrap2->localPosition().y();
477 double ExtrapErr = std::hypot(sz, zdiff);
478 if (ExtrapErr > m_MaxTrackUncert)
479 ExtrapSuc[k].push_back(false);
480 else {
481 // iff both extrapolations succeed && error is acceptable, store the information
482 ExtrapSuc[k].push_back(true);
483 std::pair<unsigned int, unsigned int> trkmap(ExtrapZ[k].size(), i);
484 UsedTracks[k].push_back(trkmap);
485 ExtrapZ[k].push_back(extrap->localPosition().y());
486 sigmaZ[k].push_back(sz);
487 pAtVx[k].push_back(extrap->momentum());
488 dlength[k].push_back(zdiff);
489 }
490 } else
491 ExtrapSuc[k].push_back(false); // not possible to calculate the uncertainty -- do not use tracklet in vertex
492 }
493 }
494 // not possible to extrapolate the tracklet
495 else
496 ExtrapSuc[k].push_back(false);
497 } // loop on tracklets
498 } // loop on radial planes
499
500
501 // perform the vertex fit
502 std::array<std::vector<Amg::Vector3D>, MAXPLANES> trkp{}; // tracklet momentum
503 // loop on planes
504 for (int k = 0; k < nplanes; ++k) {
505 if (ExtrapZ[k].size() < 3) continue; // require at least 3 tracklets to build a vertex
506 // initialize the variables used in the routine
507 double zLoF = Rpos[k] / std::tan(LoF);
508 double dzLoF(10);
509 double aveZpos(0), posWeight(0);
510 for (unsigned int i = 0; i < ExtrapZ[k].size(); ++i) {
511 double ExtrapErr = std::hypot(sigmaZ[k][i], dlength[k][i], dzLoF);
512 if (isNeutralTrack[k][i]) ExtrapErr = std::hypot(sigmaZ[k][i], dzLoF);
513 aveZpos += ExtrapZ[k][i] / std::pow(ExtrapErr,2);
514 posWeight += 1. / std::pow(ExtrapErr,2);
515 }
516 // calculate the weighted average position of the tracklets
517 zLoF = aveZpos / posWeight;
518 double zpossigma(dzLoF), Chi2(0), Chi2Prob(-1);
519 unsigned int Nitr(0);
520 std::vector<unsigned int> vxtracks; // tracklets to be used in the vertex routine
521 std::vector<bool> blocklist(ExtrapZ[k].size(), false); // tracklets that do not belong to the vertex
522
523 // minimum chi^2 iterative fit
524 while (true) {
525 vxtracks.clear(); trkp[k].clear();
526 int tmpnTrks(0);
527 double tmpzLoF(0), tmpzpossigma(0), tmpchi2(0), posWeight(0), worstdelz(0);
528 unsigned int iworst(0); // tracklet index contributing to the vertex chi2 the most
529 // loop on the tracklets, find the chi^2 contribution from each tracklet
530 for (unsigned int i = 0; i < ExtrapZ[k].size(); ++i) {
531 if (blocklist[i]) continue;
532 trkp[k].push_back(pAtVx[k][i]);
533 double delz = zLoF - ExtrapZ[k][i];
534 double ExtrapErr = std::hypot(sigmaZ[k][i], dlength[k][i], dzLoF);
535 double trkchi2 = std::pow(delz,2) / std::pow(ExtrapErr,2);
536 if (trkchi2 > worstdelz) {
537 iworst = i;
538 worstdelz = trkchi2;
539 }
540 tmpzLoF += ExtrapZ[k][i] / std::pow(ExtrapErr,2);
541 posWeight += 1. / std::pow(ExtrapErr,2);
542 tmpzpossigma += std::pow(delz,2);
543 tmpchi2 += trkchi2;
544 ++tmpnTrks;
545 }
546
547 if (tmpnTrks < 3) break; // stop searching for a vertex at this plane
548 tmpzpossigma = std::sqrt(tmpzpossigma / (double)tmpnTrks);
549 zLoF = tmpzLoF / posWeight;
550 zpossigma = tmpzpossigma;
551 double testChi2 = TMath::Prob(tmpchi2, tmpnTrks - 1);
552 if (testChi2 < m_VxChi2ProbCUT)
553 blocklist[iworst] = true;
554 else {
555 Chi2 = tmpchi2;
556 Chi2Prob = testChi2;
557 // loop on the tracklets and find all that belong to the vertex
558 for (unsigned int i = 0; i < ExtrapZ[k].size(); ++i) {
559 double delz = zLoF - ExtrapZ[k][i];
560 double ExtrapErr = std::hypot(sigmaZ[k][i], dlength[k][i], dzLoF);
561 double trkErr = std::hypot(ExtrapErr, zpossigma) + 0.001;
562 double trkNsigma = std::abs(delz / trkErr);
563 if (trkNsigma < 3) vxtracks.push_back(i);
564 }
565 break; // found a vertex, stop removing tracklets! Break chi^2 iterative fit at this radial plane
566 }
567 if (Nitr >= (ExtrapZ[k].size() - 3)) break; // stop searching for a vertex at this plane
568 ++Nitr;
569 } // end while
570
571 if (vxtracks.size() < 3) continue;
572
573 // create TrackParticle vector for all tracklets used in the vertex fit
574 std::vector<const xAOD::TrackParticle*> vxTrackParticles;
575 vxTrackParticles.reserve(vxtracks.size());
576 for (std::vector<unsigned int>::iterator vxtrk = vxtracks.begin(); vxtrk != vxtracks.end(); ++vxtrk) {
577 for (unsigned int i = 0; i < UsedTracks[k].size(); ++i) {
578 if ((*vxtrk) != UsedTracks[k].at(i).first) continue;
579 const Tracklet& trklt = tracklets.at(UsedTracks[k].at(i).second);
580 vxTrackParticles.push_back(trklt.getTrackParticle());
581 break; // found the tracklet used for the vertex reconstruction in the tracklet collection. Hence can stop looking
582 }
583 }
584 Amg::Vector3D position(Rpos[k] * std::cos(avePhi), Rpos[k] * std::sin(avePhi), zLoF);
585 vertices.push_back(std::make_unique<MSVertex>(1, position, vxTrackParticles, Chi2Prob, Chi2, 0, 0, 0));
586 } // end loop on Radial planes
587
588 if (vertices.empty()) return;
589
590 // loop on the vertex candidates and select the best based on max n(tracks) and max chi^2 probability
591
592 unsigned int bestVx(0);
593 for (unsigned int k = 1; k < vertices.size(); ++k) {
594 if (vertices[k]->getChi2Probability() < m_VxChi2ProbCUT || vertices[k]->getNTracks() < 3) continue;
595 if (vertices[k]->getNTracks() < vertices[bestVx]->getNTracks()) continue;
596 if (vertices[k]->getNTracks() == vertices[bestVx]->getNTracks() &&
597 vertices[k]->getChi2Probability() < vertices[bestVx]->getChi2Probability())
598 continue;
599 bestVx = k;
600 }
601 vtx = std::make_unique<MSVertex>(*vertices[bestVx]);
602 vertices.clear(); // cleanup
603 }
Scalar perp() const
perp method - perpendicular length
Scalar phi() const
phi method
Scalar theta() const
theta method
Scalar mag() const
mag method
double charge(const T &p)
Definition AtlasPID.h:997
#define AmgSymMatrix(dim)
static Double_t sz
if(febId1==febId2)
Eigen::Matrix< double, 3, 1 > Vector3D
#define z
Gaudi::Property< double > m_VertexMaxRadialPlane
Gaudi::Property< double > m_TrackPhiRotation
Gaudi::Property< double > m_TrackPhiAngle
Gaudi::Property< double > m_MaxTrackUncert
Gaudi::Property< double > m_VertexMinRadialPlane
Gaudi::Property< double > m_VxPlaneDist
const xAOD::TrackParticle * getTrackParticle() const
Definition Tracklet.cxx:44
const Amg::Vector3D & momentum() const
Access method for the momentum.
Amg::Vector2D localPosition() const
Access method for the local coordinates, local parameter definitions differ for each surface type.
void Norm(TH1 *h, double scale)
Definition computils.cxx:67
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Affine3d Transform3D
const double r0
electron radius{cm}
@ anyDirection
@ locY
local cartesian
Definition ParamDefs.h:38
@ theta
Definition ParamDefs.h:66
ParametersT< TrackParametersDim, Charged, CylinderSurface > AtaCylinder

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

◆ RemoveBadTrk()

std::vector< Tracklet > Muon::MSVertexRecoTool::RemoveBadTrk ( const std::vector< Tracklet > & tracklets,
const Amg::Vector3D & Vx ) const
private

Definition at line 745 of file MSVertexRecoTool.cxx.

745 {
746 // Removes at most one track with the largest distance to the vertex above the predefined threshold set by m_MaxTollDist
747 // check for default vertex
748 if (Vx.x() == 0 && Vx.z() == 0) return tracks;
749
750 double WorstTrkDist = m_MaxTollDist;
751 unsigned int iWorstTrk = -1;
752 for (unsigned int i = 0; i < tracks.size(); ++i) {
753 double TrkSlope = std::tan(tracks.at(i).getML1seg().alpha());
754 double TrkInter = tracks.at(i).getML1seg().globalPosition().perp() - tracks.at(i).getML1seg().globalPosition().z() * TrkSlope;
755 double dist = std::abs((TrkSlope * Vx.z() - Vx.x() + TrkInter) / std::hypot(TrkSlope, 1));
756 if (dist > m_MaxTollDist && dist > WorstTrkDist) {
757 iWorstTrk = i;
758 WorstTrkDist = dist;
759 }
760 }
761
762 // Remove the worst track from the list
763 std::vector<Tracklet> Tracks;
764 for (unsigned int i = 0; i < tracks.size(); ++i) {
765 if (i != iWorstTrk) Tracks.push_back(tracks.at(i));
766 }
767 return Tracks;
768 }

◆ 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();
384 }
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)

◆ 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 {
366 }

◆ 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 asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and DerivationFramework::CfAthAlgTool.

◆ 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) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

◆ VxMinQuad()

Amg::Vector3D Muon::MSVertexRecoTool::VxMinQuad ( const std::vector< Tracklet > & tracks)
staticprivate

Definition at line 840 of file MSVertexRecoTool.cxx.

840 {
841 double s(0.), sx(0.), sy(0.), sxy(0.), sxx(0.), d(0.);
842 double sigma = 1.;
843 for (const Tracklet &track : tracks) {
844 double TrkSlope = std::tan(track.getML1seg().alpha());
845 double TrkInter = track.getML1seg().globalPosition().perp() - track.getML1seg().globalPosition().z() * TrkSlope;
846 s += 1. / std::pow(sigma,2);
847 sx += TrkSlope / std::pow(sigma,2);
848 sxx += std::pow(TrkSlope,2) / std::pow(sigma,2);
849 sy += TrkInter / std::pow(sigma,2);
850 sxy += (TrkSlope * TrkInter) / std::pow(sigma,2);
851 }
852 d = s * sxx - std::pow(sx,2);
853 if (d == 0.) {
854 Amg::Vector3D MyVx(0., 0., 0.); // return 0, no vertex was found.
855 return MyVx;
856 }
857
858 double Rpos = (sxx * sy - sx * sxy) / d;
859 double Zpos = (sx * sy - s * sxy) / d;
860
861 Amg::Vector3D MyVx(Rpos, 0, Zpos);
862
863 return MyVx;
864 }

◆ vxPhiFinder()

double Muon::MSVertexRecoTool::vxPhiFinder ( const double theta,
const double phi,
const EventContext & ctx ) const
private

Definition at line 869 of file MSVertexRecoTool.cxx.

869 {
870 double nmeas(0), sinphi(0), cosphi(0);
871 if (theta == 0) {
872 ATH_MSG_WARNING("vxPhiFinder() called with theta=" << theta << " and phi=" << phi << ", return 0");
873 return 0;
874 } else if (theta > M_PI) {
875 ATH_MSG_WARNING("vxPhiFinder() called with theta=" << std::setprecision(15) << theta << " and phi=" << phi
876 << ", (theta>M_PI), return 0");
877 return 0;
878 }
879 double tanThetaHalf = std::tan(0.5 * theta);
880 if (tanThetaHalf <= 0) {
881 ATH_MSG_WARNING("vxPhiFinder() called with theta=" << std::setprecision(15) << theta << " and phi=" << phi
882 << ", resulting in tan(0.5*theta)<=0, return 0");
883 return 0;
884 }
885 double eta = -std::log(tanThetaHalf);
886 if (std::abs(eta) < 1.5) {
887 SG::ReadHandle<Muon::RpcPrepDataContainer> rpcTES(m_rpcTESKey, ctx);
888 if (!rpcTES.isValid()) {
889 ATH_MSG_WARNING("No RpcPrepDataContainer found in SG!");
890 return 0;
891 }
892 for (const Muon::RpcPrepDataCollection* RPC_coll : *rpcTES){
893 for (const Muon::RpcPrepData* rpc : *RPC_coll){
894 if (!m_idHelperSvc->rpcIdHelper().measuresPhi(rpc->identify())) continue;
895 double rpcEta = rpc->globalPosition().eta();
896 double rpcPhi = rpc->globalPosition().phi();
897 double DR = xAOD::P4Helpers::deltaR(eta, phi, rpcEta, rpcPhi);
898 if (DR >= 0.6) continue;
899 sinphi += std::sin(rpcPhi);
900 cosphi += std::cos(rpcPhi);
901 ++nmeas;
902 }
903 }
904 }
905 if (std::abs(eta) > 0.5) {
906 SG::ReadHandle<Muon::TgcPrepDataContainer> tgcTES(m_tgcTESKey, ctx);
907 if (!tgcTES.isValid()) {
908 ATH_MSG_WARNING("No TgcPrepDataContainer found in SG!");
909 return 0;
910 }
911 for (const Muon::TgcPrepDataCollection* TGC_coll : *tgcTES){
912 for (const Muon::TgcPrepData* tgc : *TGC_coll){
913 if (!m_idHelperSvc->tgcIdHelper().isStrip(tgc->identify())) continue;
914 double tgcEta = tgc->globalPosition().eta();
915 double tgcPhi = tgc->globalPosition().phi();
916 double DR = xAOD::P4Helpers::deltaR(eta, phi, tgcEta, tgcPhi);
917 if (DR >= 0.6) continue;
918 sinphi += std::sin(tgcPhi);
919 cosphi += std::cos(tgcPhi);
920 ++nmeas;
921 }
922 }
923 }
924
925 double vxphi = phi;
926 if (nmeas > 0) vxphi = std::atan2(sinphi / nmeas, cosphi / nmeas);
927 return vxphi;
928 }
#define M_PI
Scalar eta() const
pseudorapidity method

Member Data Documentation

◆ m_accMDT_str

const std::vector<std::string> Muon::MSVertexRecoTool::m_accMDT_str = {"nMDT", "nMDT_inwards", "nMDT_I", "nMDT_E", "nMDT_M", "nMDT_O"}
private

Definition at line 69 of file MSVertexRecoTool.h.

69{"nMDT", "nMDT_inwards", "nMDT_I", "nMDT_E", "nMDT_M", "nMDT_O"};

◆ m_accRPC_str

const std::vector<std::string> Muon::MSVertexRecoTool::m_accRPC_str = {"nRPC", "nRPC_inwards", "nRPC_I", "nRPC_E", "nRPC_M", "nRPC_O"}
private

Definition at line 70 of file MSVertexRecoTool.h.

70{"nRPC", "nRPC_inwards", "nRPC_I", "nRPC_E", "nRPC_M", "nRPC_O"};

◆ m_accTGC_str

const std::vector<std::string> Muon::MSVertexRecoTool::m_accTGC_str = {"nTGC", "nTGC_inwards", "nTGC_I", "nTGC_E", "nTGC_M", "nTGC_O"}
private

Definition at line 71 of file MSVertexRecoTool.h.

71{"nTGC", "nTGC_inwards", "nTGC_I", "nTGC_E", "nTGC_M", "nTGC_O"};

◆ m_BarrelTrackletUncert

Gaudi::Property<double> Muon::MSVertexRecoTool::m_BarrelTrackletUncert {this, "BarrelTrackletUncertainty", 0.1, "probability of considering a barrel tracklet in the clustering for the systematics reconstruction"}
private

Definition at line 93 of file MSVertexRecoTool.h.

93{this, "BarrelTrackletUncertainty", 0.1, "probability of considering a barrel tracklet in the clustering for the systematics reconstruction"};

◆ m_ChamberOccupancyMin

Gaudi::Property<double> Muon::MSVertexRecoTool::m_ChamberOccupancyMin {this, "MinimumHighOccupancy", 0.25, "minimum occupancy to be considered 'high occupancy'"}
private

Definition at line 86 of file MSVertexRecoTool.h.

86{this, "MinimumHighOccupancy", 0.25, "minimum occupancy to be considered 'high occupancy'"};

◆ m_ClusterdEta

Gaudi::Property<double> Muon::MSVertexRecoTool::m_ClusterdEta {this, "ClusterdEta", 0.7, "eta extend of cluster"}
private

Definition at line 89 of file MSVertexRecoTool.h.

89{this, "ClusterdEta", 0.7, "eta extend of cluster"};

◆ m_ClusterdPhi

Gaudi::Property<double> Muon::MSVertexRecoTool::m_ClusterdPhi {this, "ClusterdPhi", M_PI / 3.*Gaudi::Units::radian, "phi extend of cluster"}
private

Definition at line 90 of file MSVertexRecoTool.h.

90{this, "ClusterdPhi", M_PI / 3.*Gaudi::Units::radian, "phi extend of cluster"};

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

Gaudi::Property<bool> Muon::MSVertexRecoTool::m_doSystematics {this, "DoSystematicUncertainty", false, "find vertex systematic uncertainty"}
private

Definition at line 92 of file MSVertexRecoTool.h.

92{this, "DoSystematicUncertainty", false, "find vertex systematic uncertainty"};

◆ m_EndcapTrackletUncert

Gaudi::Property<double> Muon::MSVertexRecoTool::m_EndcapTrackletUncert {this, "EndcapTrackletUncertainty", 0.1, "probability of considering a endcap tracklet in the clustering for the systematics reconstruction"}
private

Definition at line 94 of file MSVertexRecoTool.h.

94{this, "EndcapTrackletUncertainty", 0.1, "probability of considering a endcap tracklet in the clustering for the systematics reconstruction"};

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

ToolHandle<Trk::IExtrapolator> Muon::MSVertexRecoTool::m_extrapolator {this, "MyExtrapolator", "Trk::Extrapolator/AtlasExtrapolator"}
private

Definition at line 79 of file MSVertexRecoTool.h.

79{this, "MyExtrapolator", "Trk::Extrapolator/AtlasExtrapolator"};

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> Muon::MSVertexRecoTool::m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
private

Definition at line 77 of file MSVertexRecoTool.h.

77{this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};

◆ m_maxClusterTracklets

Gaudi::Property<unsigned int> Muon::MSVertexRecoTool::m_maxClusterTracklets {this, "MaxClusterTracklets", 50, "maximal number of tracklets in a cluster"}
private

Definition at line 84 of file MSVertexRecoTool.h.

84{this, "MaxClusterTracklets", 50, "maximal number of tracklets in a cluster"}; // check if this makes sense to be large than m_maxGlobalTracklets

◆ m_maxGlobalTracklets

Gaudi::Property<unsigned int> Muon::MSVertexRecoTool::m_maxGlobalTracklets {this, "MaxGlobalTracklets", 40, "maximal number of tracklets in an event"}
private

Definition at line 83 of file MSVertexRecoTool.h.

83{this, "MaxGlobalTracklets", 40, "maximal number of tracklets in an event"};

◆ m_MaxLxyEndcap

Gaudi::Property<double> Muon::MSVertexRecoTool::m_MaxLxyEndcap {this, "MaxLxyEndcap", 10000*Gaudi::Units::millimeter, "maximal transverse distance for endcap vertex in mm"}
private

Definition at line 112 of file MSVertexRecoTool.h.

112{this, "MaxLxyEndcap", 10000*Gaudi::Units::millimeter, "maximal transverse distance for endcap vertex in mm"};

◆ m_MaxTollDist

Gaudi::Property<double> Muon::MSVertexRecoTool::m_MaxTollDist {this, "MaxTollDist", 300.*Gaudi::Units::millimeter, "maximal distance between tracklet and endcap vertex in mm"}
private

Definition at line 103 of file MSVertexRecoTool.h.

103{this, "MaxTollDist", 300.*Gaudi::Units::millimeter, "maximal distance between tracklet and endcap vertex in mm"};

◆ m_MaxTrackUncert

Gaudi::Property<double> Muon::MSVertexRecoTool::m_MaxTrackUncert {this, "MaxTrackUncert", 200.*Gaudi::Units::millimeter, "maximal tracklet uncertainty in mm"}
private

Definition at line 98 of file MSVertexRecoTool.h.

98{this, "MaxTrackUncert", 200.*Gaudi::Units::millimeter, "maximal tracklet uncertainty in mm"};

◆ m_MaxZEndcap

Gaudi::Property<double> Muon::MSVertexRecoTool::m_MaxZEndcap {this, "MaxZEndcap", 14000*Gaudi::Units::millimeter, "maximal longitudinal distance for endcap vertex in mm"}
private

Definition at line 114 of file MSVertexRecoTool.h.

114{this, "MaxZEndcap", 14000*Gaudi::Units::millimeter, "maximal longitudinal distance for endcap vertex in mm"};

◆ m_mdtTESKey

SG::ReadHandleKey<Muon::MdtPrepDataContainer> Muon::MSVertexRecoTool::m_mdtTESKey {this, "MDTKey", "MDT_DriftCircles"}
private

Definition at line 66 of file MSVertexRecoTool.h.

66{this, "MDTKey", "MDT_DriftCircles"};

◆ m_minHighOccupancyChambers

Gaudi::Property<int> Muon::MSVertexRecoTool::m_minHighOccupancyChambers {this, "MinimumNumberOfHighOccupancy", 2, "number of high occupancy chambers required to be signal like"}
private

Definition at line 87 of file MSVertexRecoTool.h.

87{this, "MinimumNumberOfHighOccupancy", 2, "number of high occupancy chambers required to be signal like"};

◆ m_MinMDTHits

Gaudi::Property<int> Muon::MSVertexRecoTool::m_MinMDTHits {this, "MinMDTHits", 250, "minimal number of MDT hits"}
private

Definition at line 110 of file MSVertexRecoTool.h.

110{this, "MinMDTHits", 250, "minimal number of MDT hits"};

◆ m_MinTrigHits

Gaudi::Property<int> Muon::MSVertexRecoTool::m_MinTrigHits {this, "MinTrigHits", 200, "minimal number of trigger chamber (RPC+TGC) hits"}
private

Definition at line 111 of file MSVertexRecoTool.h.

111{this, "MinTrigHits", 200, "minimal number of trigger chamber (RPC+TGC) hits"};

◆ m_MinZEndcap

Gaudi::Property<double> Muon::MSVertexRecoTool::m_MinZEndcap {this, "MinZEndcap", 8000*Gaudi::Units::millimeter, "minimal longitudinal distance for endcap vertex in mm"}
private

Definition at line 113 of file MSVertexRecoTool.h.

113{this, "MinZEndcap", 8000*Gaudi::Units::millimeter, "minimal longitudinal distance for endcap vertex in mm"};

◆ m_nMDT_accs

std::vector<SG::AuxElement::Accessor<int> > Muon::MSVertexRecoTool::m_nMDT_accs
private

Definition at line 73 of file MSVertexRecoTool.h.

◆ m_nMDTHitsEta

Gaudi::Property<double> Muon::MSVertexRecoTool::m_nMDTHitsEta {this, "nMDTHitsEta", 0.6, "max eta extend between vertex and MDT hit"}
private

Definition at line 106 of file MSVertexRecoTool.h.

106{this, "nMDTHitsEta", 0.6, "max eta extend between vertex and MDT hit"};

◆ m_nMDTHitsPhi

Gaudi::Property<double> Muon::MSVertexRecoTool::m_nMDTHitsPhi {this, "nMDTHitsPhi", 0.6*Gaudi::Units::radian, "max phi extend between vertex and MDT hit"}
private

Definition at line 107 of file MSVertexRecoTool.h.

107{this, "nMDTHitsPhi", 0.6*Gaudi::Units::radian, "max phi extend between vertex and MDT hit"};

◆ m_nRPC_accs

std::vector<SG::AuxElement::Accessor<int> > Muon::MSVertexRecoTool::m_nRPC_accs
private

Definition at line 74 of file MSVertexRecoTool.h.

◆ m_nTGC_accs

std::vector<SG::AuxElement::Accessor<int> > Muon::MSVertexRecoTool::m_nTGC_accs
private

Definition at line 75 of file MSVertexRecoTool.h.

◆ m_nTrigHitsdR

Gaudi::Property<double> Muon::MSVertexRecoTool::m_nTrigHitsdR {this, "nTrigHitsdR", 0.6*Gaudi::Units::radian, "max delta R between vertex and trigger chamber (RPC or TGC) hit"}
private

Definition at line 108 of file MSVertexRecoTool.h.

108{this, "nTrigHitsdR", 0.6*Gaudi::Units::radian, "max delta R between vertex and trigger chamber (RPC or TGC) hit"};

◆ m_rndmSvc

ServiceHandle<IAthRNGSvc> Muon::MSVertexRecoTool::m_rndmSvc {this, "RndmSvc", "AthRNGSvc", "Random Number Service"}
private

Definition at line 78 of file MSVertexRecoTool.h.

78{this, "RndmSvc", "AthRNGSvc", "Random Number Service"}; // Random number service

◆ m_rpcTESKey

SG::ReadHandleKey<Muon::RpcPrepDataContainer> Muon::MSVertexRecoTool::m_rpcTESKey {this, "RPCKey", "RPC_Measurements"}
private

Definition at line 64 of file MSVertexRecoTool.h.

64{this, "RPCKey", "RPC_Measurements"};

◆ m_tgcTESKey

SG::ReadHandleKey<Muon::TgcPrepDataContainer> Muon::MSVertexRecoTool::m_tgcTESKey {this, "TGCKey", "TGC_Measurements"}
private

Definition at line 65 of file MSVertexRecoTool.h.

65{this, "TGCKey", "TGC_Measurements"};

◆ m_TrackPhiAngle

Gaudi::Property<double> Muon::MSVertexRecoTool::m_TrackPhiAngle {this, "TrackPhiAngle", 0.0*Gaudi::Units::radian, "nominal phi angle for tracklets in rad"}
private

Definition at line 96 of file MSVertexRecoTool.h.

96{this, "TrackPhiAngle", 0.0*Gaudi::Units::radian, "nominal phi angle for tracklets in rad"};

◆ m_TrackPhiRotation

Gaudi::Property<double> Muon::MSVertexRecoTool::m_TrackPhiRotation {this, "TrackPhiRotation", 0.2*Gaudi::Units::radian, "angle to rotate tracklets by for uncertainty estimate in rad"}
private

Definition at line 97 of file MSVertexRecoTool.h.

97{this, "TrackPhiRotation", 0.2*Gaudi::Units::radian, "angle to rotate tracklets by for uncertainty estimate in rad"};

◆ m_useOldMSVxEndcapMethod

Gaudi::Property<bool> Muon::MSVertexRecoTool::m_useOldMSVxEndcapMethod {this, "UseOldMSVxEndcapMethod", false, "use old vertex reconstruction in the endcaps "}
private

Definition at line 104 of file MSVertexRecoTool.h.

104{this, "UseOldMSVxEndcapMethod", false, "use old vertex reconstruction in the endcaps "};

◆ m_varHandleArraysDeclared

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

Definition at line 399 of file AthCommonDataStore.h.

◆ m_VertexMaxRadialPlane

Gaudi::Property<double> Muon::MSVertexRecoTool::m_VertexMaxRadialPlane {this, "VertexMaxRadialPlane", 7000.*Gaudi::Units::millimeter, "position of last radial plane in mm"}
private

Definition at line 101 of file MSVertexRecoTool.h.

101{this, "VertexMaxRadialPlane", 7000.*Gaudi::Units::millimeter, "position of last radial plane in mm"};

◆ m_VertexMinRadialPlane

Gaudi::Property<double> Muon::MSVertexRecoTool::m_VertexMinRadialPlane {this, "VertexMinRadialPlane", 3500.*Gaudi::Units::millimeter, "position of first radial plane in mm"}
private

Definition at line 100 of file MSVertexRecoTool.h.

100{this, "VertexMinRadialPlane", 3500.*Gaudi::Units::millimeter, "position of first radial plane in mm"};

◆ m_vhka

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

Definition at line 398 of file AthCommonDataStore.h.

◆ m_VxChi2ProbCUT

Gaudi::Property<double> Muon::MSVertexRecoTool::m_VxChi2ProbCUT {this, "VxChi2ProbabilityCut", 0.05, "chi^2 probability cut"}
private

Definition at line 99 of file MSVertexRecoTool.h.

99{this, "VxChi2ProbabilityCut", 0.05, "chi^2 probability cut"};

◆ m_VxPlaneDist

Gaudi::Property<double> Muon::MSVertexRecoTool::m_VxPlaneDist {this, "VertexPlaneDist", 200.*Gaudi::Units::millimeter, "distance between two adjacent planes in mm"}
private

Definition at line 102 of file MSVertexRecoTool.h.

102{this, "VertexPlaneDist", 200.*Gaudi::Units::millimeter, "distance between two adjacent planes in mm"};

◆ m_xAODContainerKey

SG::WriteHandleKey<xAOD::VertexContainer> Muon::MSVertexRecoTool::m_xAODContainerKey {this, "xAODVertexContainer", "MSDisplacedVertex"}
private

Definition at line 62 of file MSVertexRecoTool.h.

62{this, "xAODVertexContainer", "MSDisplacedVertex"};

The documentation for this class was generated from the following files: