ATLAS Offline Software
MuonTrackToSegmentTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <set>
8 
19 #include "TrkTrack/Track.h"
20 #include "CxxUtils/trapping_fp.h"
21 
22 namespace Muon {
23  MuonTrackToSegmentTool::MuonTrackToSegmentTool(const std::string& t, const std::string& n, const IInterface* p) : AthAlgTool(t, n, p) {
24  declareInterface<IMuonTrackToSegmentTool>(this);
25  }
26 
28  ATH_CHECK(m_propagator.retrieve());
29  ATH_CHECK(m_idHelperSvc.retrieve());
30  ATH_CHECK(m_edmHelperSvc.retrieve());
31  ATH_CHECK(m_printer.retrieve());
33  return StatusCode::SUCCESS;
34  }
35 
36  MuonSegment* MuonTrackToSegmentTool::convert(const EventContext& ctx, const Trk::Track& track) const {
37  // Avoids FPE with clang.
41  ATH_MSG_DEBUG(" creating MuonSegment from track ");
42 
43  const Trk::Perigee* perigee = track.perigeeParameters();
44  if (!perigee) {
45  ATH_MSG_WARNING(" was expecting a perigee here... ");
46  return nullptr;
47  }
48 
49  const Trk::FitQuality* fq = track.fitQuality();
50  if (!fq) {
51  ATH_MSG_WARNING(" was expecting a FitQuality here... ");
52  return nullptr;
53  }
54 
55  std::set<Identifier> chIds;
56 
57  // copy rots, get surface
59  rots.reserve(track.measurementsOnTrack()->size());
60 
61  // loop over TSOS
62  const Trk::TrackStates* states = track.trackStateOnSurfaces();
63  if (!states) {
64  ATH_MSG_WARNING(" track without states, discarding track ");
65  return nullptr;
66  }
67  // track direction vector
68  const Amg::Vector3D dir = perigee->momentum().unit();
69 
70  const Amg::Transform3D* surfaceTransform = nullptr;
71  const Amg::Transform3D* backupTransform = nullptr;
72  std::unique_ptr<Amg::Transform3D> surfaceTransformToBeDeleted;
73  double weightedDistanceSquared{0}, weightSquared{0};
74  for (const Trk::TrackStateOnSurface* tsos : *states) {
75  // require TrackParameters
76  const Trk::TrackParameters* pars = tsos->trackParameters();
77  if (!pars) continue;
78 
79  // check whether state is a measurement
80  const Trk::MeasurementBase* meas = tsos->measurementOnTrack();
81  if (!meas || tsos->type(Trk::TrackStateOnSurface::Outlier)) continue;
82  rots.push_back(meas->clone());
83 
84  // only consider eta hits
85  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
86  if (!id.is_valid() || m_idHelperSvc->measuresPhi(id)) continue;
87 
88  double distance = (pars->position() - perigee->position()).dot(dir);
89  double weight = 1. / meas->localCovariance()(Trk::locX, Trk::locX);
90  ATH_MSG_VERBOSE(" distance " << distance << " error " << Amg::error(meas->localCovariance(), Trk::locX) << " weight " << weight
91  << " " << m_idHelperSvc->toString(id));
92  weightedDistanceSquared += distance * weight;
93  weightSquared += weight;
94  if (m_idHelperSvc->isMdt(id)) {
95  chIds.insert(m_idHelperSvc->chamberId(id));
96  if (!surfaceTransform) {
97  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
98  if (mdt) {
99  // create new surface using AMDB reference frame
100  surfaceTransformToBeDeleted = std::make_unique<Amg::Transform3D>(mdt->detectorElement()->AmdbLRSToGlobalTransform().rotation());
101  surfaceTransformToBeDeleted->pretranslate(mdt->detectorElement()->center());
102  surfaceTransform = surfaceTransformToBeDeleted.get();
103  }
104  }
105  } else if ((m_idHelperSvc->isMM(id) || m_idHelperSvc->isCsc(id)) && !surfaceTransform) {
106  surfaceTransform = &(meas)->associatedSurface().transform();
107  } else if (!surfaceTransform && !backupTransform) {
108  backupTransform = &(meas)->associatedSurface().transform();
109  }
110  }
111  if (!surfaceTransform) surfaceTransform = backupTransform;
112  // calculate distance new reference point, shift it 100 mm towards the start of the segment
113  double refDistance = (weightSquared > 0 ? weightedDistanceSquared / weightSquared : 1) - 100;
114  ATH_MSG_DEBUG(" weighted distance " << refDistance);
115 
116  const Amg::Vector3D refPos = perigee->position() + refDistance * dir;
117 
118  // find closest measured parameters
119  double minDist = -1e6;
120  const Trk::TrackParameters* closestPars = nullptr;
121  for (const Trk::TrackStateOnSurface* tsos : *states) {
122  // require TrackParameters
123  const Trk::TrackParameters* pars = tsos->trackParameters();
124  if (!pars || !pars->covariance()) continue;
125 
126  // look for the closest measured parameters to the reference point
127  double distance = (pars->position() - refPos).dot(dir);
128  if (distance < 0 && std::abs(distance) < std::abs(minDist)) {
129  minDist = distance;
130  closestPars = pars;
131  }
132  }
133 
134  if (!surfaceTransform) {
135  ATH_MSG_DEBUG(" failed to create a PlaneSurface for the track, cannot make segment!!! " << std::endl
136  << m_printer->print(track)
137  << std::endl
138  << m_printer->printStations(track));
139  return nullptr;
140  }
141 
142  if (!closestPars) {
143  closestPars = perigee;
144  minDist = (perigee->position() - refPos).dot(dir);
145  }
146 
147  Amg::Transform3D transform(surfaceTransform->rotation());
148  transform.pretranslate(refPos);
149  constexpr double surfDim = 500.;
150  std::unique_ptr<Trk::PlaneSurface> surf = std::make_unique<Trk::PlaneSurface>(transform, surfDim, surfDim);
151  std::unique_ptr<Trk::TrackParameters> exPars = m_propagator->propagate(ctx, *closestPars, *surf, minDist > 0 ? Trk::oppositeMomentum : Trk::alongMomentum, false,
153  if (!exPars || !exPars->covariance()) {
154  ATH_MSG_VERBOSE("First trial reaching the surface failed. This is presumably due to a too large momentum. Let's try with a dummy 1 GeV momentum");
155  std::unique_ptr<Trk::TrackParameters> cloned_pars {closestPars->clone()};
156  constexpr double OneOverGeV = 1./ Gaudi::Units::GeV;
157  cloned_pars->parameters()[Trk::qOverP] = cloned_pars->charge() *OneOverGeV;
158  exPars = m_propagator->propagate(ctx, *cloned_pars, *surf, Trk::anyDirection, false,
160 
161  if (!exPars){
162  ATH_MSG_DEBUG(" propagation failed!!! "<<*cloned_pars<<std::endl<<std::endl<<*surf);
163  return nullptr;
164  }
165  exPars->parameters()[Trk::qOverP] = closestPars->parameters()[Trk::qOverP];
166  }
168  if (!surf->globalToLocal(exPars->position(), exPars->momentum(), locPos)) {
169  ATH_MSG_WARNING(" localToGlobal failed!!! ");
170  return nullptr;
171  }
173  surf->globalToLocalDirection(exPars->momentum(), locDir);
174 
175  // convert errors on global angles theta/phi to errors on local angles angleYZ/angleXZ
176  Trk::JacobianPhiThetaLocalAngles globalToLocalMeasAnglesJacobian(exPars->parameters()[Trk::phi], exPars->parameters()[Trk::theta],
177  exPars->associatedSurface().transform().rotation().inverse());
178 
179  // make the Jacobian to convert all in one go from global to local
180  // so that the correlations are calculated correctly
181  AmgSymMatrix(5) globalToLocalMeasJacobian{AmgSymMatrix(5)::Zero()};
182  globalToLocalMeasJacobian(Trk::locX, Trk::locX) = 1.0;
183  globalToLocalMeasJacobian(Trk::locY, Trk::locY) = 1.0;
184  globalToLocalMeasJacobian(Trk::phi, Trk::phi) = globalToLocalMeasAnglesJacobian(0, 0);
185  globalToLocalMeasJacobian(Trk::theta, Trk::theta) = globalToLocalMeasAnglesJacobian(1, 1);
186  globalToLocalMeasJacobian(Trk::theta, Trk::phi) = globalToLocalMeasAnglesJacobian(0, 1); // also fills (Trk::phi,Trk::theta)
187  globalToLocalMeasJacobian(Trk::phi, Trk::theta) = globalToLocalMeasJacobian(Trk::theta, Trk::phi); // also fills (Trk::theta,Trk::phi)
188  globalToLocalMeasJacobian(Trk::qOverP, Trk::qOverP) = 1.0;
189 
190  AmgSymMatrix(5) cov = exPars->covariance()->similarity(globalToLocalMeasJacobian);
191 
192  Trk::FitQuality* quality = nullptr;
193  if (!chIds.empty()) {
194  // calculate holes
195  std::vector<Identifier> holes;
196  for (const Identifier& chid : chIds) {
197  std::vector<Identifier> holesChamber = calculateHoles(ctx, chid, *exPars, rots.stdcont());
198  holes.insert(holes.end(), holesChamber.begin(), holesChamber.end());
199  }
200  quality = new MuonSegmentQuality(fq->chiSquared(), fq->numberDoF(), holes);
201 
202  } else {
203  quality = new Trk::FitQuality(fq->chiSquared(), fq->numberDoF());
204  }
205  MuonSegment* seg = new MuonSegment(
206  locPos, locDir, cov, surf.release(), std::move(rots), quality);
207  return seg;
208  }
209 
210  std::vector<Identifier> MuonTrackToSegmentTool::calculateHoles(const EventContext& ctx, const Identifier& chid,
211  const Trk::TrackParameters& pars,
212  const MuonTrackToSegmentTool::MeasVec& measurements) const {
214  if (!InterSectSvc.isValid()) {
215  ATH_MSG_ERROR("Failed to retrieve chamber intersection service");
216  }
217 
218  const MuonStationIntersect intersect = InterSectSvc->tubesCrossedByTrack(chid, pars.position(), pars.momentum().unit());
219  const MuonGM::MuonDetectorManager* MuonDetMgr = InterSectSvc->detMgr();
220 
221  // set to identify the hit on the segment
222  std::set<Identifier> hitsOnSegment;
223  for (const Trk::MeasurementBase* mit : measurements) {
224  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(mit);
225  if (mdt) hitsOnSegment.insert(mdt->identify());
226  }
227 
228  // clear hole vector
229  std::vector<Identifier> holes;
230  for (unsigned int ii = 0; ii < intersect.tubeIntersects().size(); ++ii) {
231  const MuonTubeIntersect& tint = intersect.tubeIntersects()[ii];
232 
233  // skip hole check if there is a hit in this tube
234  if (hitsOnSegment.count(tint.tubeId)) continue;
235 
236  // if track goes through a tube which did not have a hit count as hole
237  if (std::abs(tint.rIntersect) < MuonDetMgr->getMdtReadoutElement(tint.tubeId)->innerTubeRadius() && tint.xIntersect < -200.) {
238  holes.push_back(tint.tubeId);
239  }
240  }
241  return holes;
242  }
243 
244 } // namespace Muon
DataVector::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
Muon::MuonSegmentQuality
Definition: MuonSegmentQuality.h:34
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
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:213
CXXUTILS_TRAPPING_FP
#define CXXUTILS_TRAPPING_FP
Definition: trapping_fp.h:24
MdtReadoutElement.h
MuonGM::MuonReadoutElement::AmdbLRSToGlobalTransform
virtual Amg::Transform3D AmdbLRSToGlobalTransform() const
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonReadoutElement.cxx:145
Muon::MuonTrackToSegmentTool::m_propagator
ToolHandle< Trk::IPropagator > m_propagator
Definition: MuonTrackToSegmentTool.h:69
Trk::MeasurementBase::clone
virtual MeasurementBase * clone() const =0
Pseudo-Constructor.
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
Muon::MuonTubeIntersect
Definition: MuonTubeIntersect.h:12
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Trk::MagneticFieldProperties
Definition: MagneticFieldProperties.h:31
Trk::locX
@ locX
Definition: ParamDefs.h:43
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:44
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
MuonGM::MdtReadoutElement::center
virtual const Amg::Vector3D & center(const Identifier &) const override final
Return the center of the surface associated with this identifier In the case of silicon it returns th...
MuonGM::MdtReadoutElement::innerTubeRadius
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
MuonTrackToSegmentTool.h
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
Trk::oppositeMomentum
@ oppositeMomentum
Definition: PropDirection.h:21
Trk::ParametersBase::associatedSurface
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
InDetDD::holes
@ holes
Definition: InDetDD_Defs.h:17
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
Muon::MuonTrackToSegmentTool::MuonTrackToSegmentTool
MuonTrackToSegmentTool(const std::string &, const std::string &, const IInterface *)
default AlgTool constructor
Definition: MuonTrackToSegmentTool.cxx:23
EventPrimitivesHelpers.h
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
Trk::alongMomentum
@ alongMomentum
Definition: PropDirection.h:20
MuonSegmentQuality.h
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Muon::MdtDriftCircleOnTrack::detectorElement
virtual const MuonGM::MdtReadoutElement * detectorElement() const override final
Returns the detector element, assoicated with the PRD of this class.
Definition: MdtDriftCircleOnTrack.h:268
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MdtDriftCircleOnTrack.h
Muon
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:49
xAOD::MuonSegment
MuonSegment_v1 MuonSegment
Reference the current persistent version:
Definition: Event/xAOD/xAODMuon/xAODMuon/MuonSegment.h:13
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
MMClusterOnTrack.h
Trk::TrackStateOnSurface::Outlier
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
Definition: TrackStateOnSurface.h:122
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
Track.h
MagneticFieldProperties.h
Muon::MuonTrackToSegmentTool::convert
MuonSegment * convert(const EventContext &ctx, const Trk::Track &track) const
convert track to segment
Definition: MuonTrackToSegmentTool.cxx:36
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
MuonGM::MuonDetectorManager::getMdtReadoutElement
const MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonDetectorManager.cxx:204
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
beamspotman.n
n
Definition: beamspotman.py:731
Trk::theta
@ theta
Definition: ParamDefs.h:72
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
urldecode::states
states
Definition: urldecode.h:39
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
CscClusterOnTrack.h
Muon::MuonTrackToSegmentTool::m_chamberGeoKey
SG::ReadCondHandleKey< Muon::MuonIntersectGeoData > m_chamberGeoKey
Definition: MuonTrackToSegmentTool.h:71
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::MeasurementBase::type
virtual bool type(MeasurementBaseType::Type type) const =0
Interface method checking the type.
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:260
Muon::MuonTrackToSegmentTool::m_printer
PublicToolHandle< MuonEDMPrinterTool > m_printer
Definition: MuonTrackToSegmentTool.h:67
Trk::FitQuality
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition: FitQuality.h:97
Trk::ParametersBase
Definition: ParametersBase.h:55
DataVector< const Trk::MeasurementBase >
Trk::LocalDirection
represents the three-dimensional global direction with respect to a planar surface frame.
Definition: LocalDirection.h:81
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
Trk::MeasurementBase::localCovariance
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Definition: MeasurementBase.h:138
beamspotman.dir
string dir
Definition: beamspotman.py:623
trapping_fp.h
Tell the compiler to optimize assuming that FP may trap.
Trk::MeasurementBase
Definition: MeasurementBase.h:58
Muon::MuonTrackToSegmentTool::m_edmHelperSvc
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
Definition: MuonTrackToSegmentTool.h:63
Muon::MuonTubeIntersect::tubeId
Identifier tubeId
Definition: MuonTubeIntersect.h:14
Trk::NoField
@ NoField
Field is set to 0., 0., 0.,.
Definition: MagneticFieldMode.h:18
Muon::MuonTrackToSegmentTool::MeasVec
std::vector< const Trk::MeasurementBase * > MeasVec
Definition: MuonTrackToSegmentTool.h:42
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
JacobianPhiThetaLocalAngles.h
Amg::error
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 ...
Definition: EventPrimitivesHelpers.h:40
Muon::MdtDriftCircleOnTrack
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
Definition: MdtDriftCircleOnTrack.h:37
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
python.copyTCTOutput.locDir
locDir
Definition: copyTCTOutput.py:113
Muon::MuonStationIntersect
Definition: MuonStationIntersect.h:12
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
Muon::MuonTubeIntersect::xIntersect
double xIntersect
Definition: MuonTubeIntersect.h:16
Trk::JacobianPhiThetaLocalAngles
Definition: JacobianPhiThetaLocalAngles.h:32
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the closest approach of two lines.
Definition: GeoPrimitivesHelpers.h:302
MuonGM::MuonDetectorManager
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:49
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:73
Trk::RIO_OnTrack::identify
virtual Identifier identify() const final
return the identifier -extends MeasurementBase
Definition: RIO_OnTrack.h:155
Muon::MuonTrackToSegmentTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonTrackToSegmentTool.h:62
Muon::MuonTubeIntersect::rIntersect
double rIntersect
Definition: MuonTubeIntersect.h:15
Trk::FitQuality::chiSquared
double chiSquared() const
returns the of the overall track fit
Definition: FitQuality.h:56
MuonSegment.h
Trk::phi
@ phi
Definition: ParamDefs.h:81
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
LocalDirection.h
Muon::MuonTrackToSegmentTool::initialize
StatusCode initialize()
initialize method, method taken from bass-class AlgTool
Definition: MuonTrackToSegmentTool.cxx:27
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
Muon::MuonSegment
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:45
AthAlgTool
Definition: AthAlgTool.h:26
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
python.Dumpers.FitQuality
FitQuality
Definition: Dumpers.py:63
Muon::MuonTrackToSegmentTool::calculateHoles
std::vector< Identifier > calculateHoles(const EventContext &ctx, const Identifier &chid, const Trk::TrackParameters &pars, const MeasVec &measurements) const
calculate holes
Definition: MuonTrackToSegmentTool.cxx:210
Trk::ParametersBase::clone
virtual ParametersBase< DIM, T > * clone() const override=0
clone method for polymorphic deep copy
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32