ATLAS Offline Software
Loading...
Searching...
No Matches
CscClusterOnTrackCreator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <cmath>
6
8
17#include "TrkSurfaces/Surface.h"
18
20using Amg::Vector3D;
24
25namespace Muon {
26
27 CscClusterOnTrackCreator::CscClusterOnTrackCreator(const std::string& ty, const std::string& na, const IInterface* pa) :
28 AthAlgTool(ty, na, pa) {
29 // algtool interface - necessary!
30 declareInterface<IMuonClusterOnTrackCreator>(this);
31 declareInterface<IRIO_OnTrackCreator>(this);
32 }
33
35
38 ATH_CHECK(m_idHelperSvc.retrieve());
39 if (!m_idHelperSvc->hasCSC()) {
40 ATH_MSG_ERROR("The given detector layout does not contain any CSC chamber, "<<
41 "there must be something wrong in the configuration,"
42 <<" since the CscClusterOnTrackCreator cannot be needed.");
43 return StatusCode::FAILURE;
44 }
45
46 // get error scaling tool
47 //
48 ATH_CHECK(m_cscErrorScalingKey.initialize(!m_cscErrorScalingKey.key().empty()));
49 ATH_CHECK(m_stripFitter.retrieve());
50 ATH_CHECK(m_clusterFitter.retrieve());
51 ATH_CHECK(m_clusterUtilTool.retrieve());
52 return StatusCode::SUCCESS;
53 }
54
57 MuonClusterOnTrack* MClT = nullptr;
58
59 // check whether PrepRawData has detector element, if not there print warning
61 if (!EL) {
62 ATH_MSG_WARNING("RIO does not have associated detectorElement!, cannot produce ROT");
63 return nullptr;
64 }
65
66 // MuClusterOnTrack production
67 //
68 // in RIO_OnTrack the local param and cov should have the same dimension
70 if (RIO.localCovariance().cols() > 1) {
71 ATH_MSG_VERBOSE("Making 2-dim local parameters");
72 } else {
73 Trk::DefinedParameter radiusPar(RIO.localPosition().x(), Trk::locX);
74 locpar = Trk::LocalParameters(radiusPar);
75 ATH_MSG_VERBOSE("Making 1-dim local parameters");
76 }
77
79 double positionAlongStrip = 0;
80
81 if (!EL->surface(RIO.identify()).globalToLocal(GP, GP, lp)) {
82 Amg::Vector3D lpos = RIO.detectorElement()->surface(RIO.identify()).transform().inverse() * GP;
83 ATH_MSG_WARNING("Extrapolated GlobalPosition not on detector surface! Distance " << lpos.z());
84 lp[Trk::locX] = lpos.x();
85 lp[Trk::locY] = lpos.y();
86 }
87 positionAlongStrip = lp[Trk::locY];
88
89 // Error matrix production - expect more intelligent code here.
90 //
91 Amg::MatrixX loce = RIO.localCovariance();
92
93 if (m_idHelperSvc->isCsc(RIO.identify()) && !m_cscErrorScalingKey.key().empty()) {
96 *error_scaling)
97 ->getScaledCovariance(std::move(loce), Trk::distPhi);
98 ATH_MSG_VERBOSE("CSC: new cov(0,0) is " << loce(0, 0));
99 }
100
101 if (m_idHelperSvc->isCsc(RIO.identify())) {
102 // cast to CscPrepData
103 const CscPrepData* MClus = dynamic_cast<const CscPrepData*>(&RIO);
104 if (!MClus) {
105 ATH_MSG_WARNING("RIO not of type CscPrepData, cannot create ROT");
106 return nullptr;
107 }
108
109 // current not changing CscClusterStatus but passing status of RIO
110 MClT = new CscClusterOnTrack(MClus, std::move(locpar), std::move(loce),
111 positionAlongStrip, MClus->status(), MClus->timeStatus(), MClus->time());
112 }
113
114 return MClT;
115 }
116
118
120 const Amg::Vector3D& GP,
121 const Amg::Vector3D& GD) const {
122 if (!m_idHelperSvc->isCsc(RIO.identify())) {
123 ATH_MSG_WARNING("CscClusterOnTrackCreator::createRIO_OnTrack is called by the other muon tech");
124 return nullptr;
125 }
126
127 MuonClusterOnTrack* MClT = nullptr;
128 // check whether PrepRawData has detector element, if not there print warning
130 if (!EL) {
131 ATH_MSG_WARNING("RIO does not have associated detectorElement!, cannot produce ROT");
132 return MClT;
133 }
134 // cast to CscPrepData : Moved to the front to avoid any memory allocation before return;
135 const CscPrepData* MClus = dynamic_cast<const CscPrepData*>(&RIO);
136 if (!MClus) {
137 ATH_MSG_WARNING("RIO not of type CscPrepData, cannot create ROT");
138 return MClT;
139 }
140
141 // MuClusterOnTrack production
142 //
143 // in RIO_OnTrack the local param and cov should have the same dimension
145 if (RIO.localCovariance().cols() > 1 ||
146 (m_idHelperSvc->isTgc(RIO.identify()) && m_idHelperSvc->tgcIdHelper().isStrip(RIO.identify()))) {
147 ATH_MSG_VERBOSE("Making 2-dim local parameters");
148 } else {
149 Trk::DefinedParameter radiusPar(RIO.localPosition().x(), Trk::locX);
150 locpar = Trk::LocalParameters(radiusPar);
151 ATH_MSG_VERBOSE("Making 1-dim local parameters");
152 }
153
154 Amg::Vector2D lp{Amg::Vector2D::Zero()};
155 double positionAlongStrip = 0;
156
157 if (!EL->surface(RIO.identify()).globalToLocal(GP, GP, lp)) {
158 Amg::Vector3D lpos = RIO.detectorElement()->surface(RIO.identify()).transform().inverse() * GP;
159 ATH_MSG_WARNING("Extrapolated GlobalPosition not on detector surface! Distance " << lpos.z());
160 lp[Trk::locX] = lpos.x();
161 lp[Trk::locY] = lpos.y();
162 }
163 positionAlongStrip = lp[Trk::locY];
164
165 // Error matrix production - expect more intelligent code here.
166 //
167 Amg::MatrixX loce = RIO.localCovariance();
168
169 if (m_idHelperSvc->isCsc(RIO.identify()) && !m_cscErrorScalingKey.key().empty()) {
172 *error_scaling)
173 ->getScaledCovariance(std::move(loce), Trk::distPhi);
174 ATH_MSG_VERBOSE("CSC: new cov(0,0) is " << loce(0, 0));
175 }
176
177 // postion Error is re-estimate only for precision fit cluster (eta)
179 // current not changing CscClusterStatus but passing status of RIO
180 MClT = new CscClusterOnTrack(MClus, std::move(locpar), std::move(loce), positionAlongStrip, MClus->status(), MClus->timeStatus(), MClus->time());
181
182 } else {
183 const MuonGM::CscReadoutElement* ele = MClus->detectorElement();
184 Transform3D globalToLocal = ele->transform(MClus->identify()).inverse();
185 Vector3D d(globalToLocal * GD);
186 double tantheta = d.x() / d.z();
187
188 std::vector<ICscClusterFitter::Result> results, results0;
189 results = m_clusterUtilTool->getRefitCluster(MClus, tantheta);
190 results0 = m_clusterUtilTool->getRefitCluster(MClus, 0);
191
192 if (results.empty() || results0.empty()) {
193 ATH_MSG_VERBOSE("No fit result");
194 return new CscClusterOnTrack(MClus, std::move(locpar), std::move(loce),
195 positionAlongStrip, MClus->status(), MClus->timeStatus(), MClus->time());
196 }
198 res = results[0];
199 res0 = results0[0]; // result at normal angle to make error blown correctly in case of cosmic
200 int fitresult = res.fitStatus;
201 if (fitresult) {
202 ATH_MSG_VERBOSE(" Precision fit failed which was succeeded: return="
203 << "cluStatus: " << res.clusterStatus << "fitStatus: " << res.fitStatus);
204 return new CscClusterOnTrack(MClus, std::move(locpar), std::move(loce),
205 positionAlongStrip, MClus->status(), MClus->timeStatus(), MClus->time());
206 } else {
207 ATH_MSG_VERBOSE(" Precision fit succeeded");
208 }
209
210 ATH_MSG_VERBOSE(" Angle from Segment: "
211 << " :: tanangle : " << tantheta);
212
213 // in case that we need to scale errors for cosmic/data we want to scale only for normal part
214 // v0 only scaling up intrinsic term...
215 // double errorCorrected = sqrt(res.dposition*res.dposition - res0.dposition*res0.dposition
216 // + m_errorScaler*m_errorScaler*res0.dposition*res0.dposition);
217 // v1 scaling up total uncertainty and add up misalignment term....like sqrt( sigma_nominal^2 * alpha^2 + beta^2)
218 double nominal_error = res.dposition;
219 double errorCorrected =
220 std::sqrt(nominal_error * nominal_error * m_errorScaler * m_errorScaler + m_errorScalerBeta * m_errorScalerBeta);
221 if (errorCorrected < m_minimumError) errorCorrected = m_minimumError;
222
223 Amg::MatrixX newloce(Amg::MatrixX(1, 1));
224 newloce.setIdentity();
225 newloce *= errorCorrected * errorCorrected;
226 if (!m_cscErrorScalingKey.key().empty()) {
228 newloce =
230 *error_scaling)
231 ->getScaledCovariance(std::move(newloce), Trk::distPhi);
232 }
233
234 ATH_MSG_VERBOSE("All: new err matrix is " << newloce);
235 ATH_MSG_VERBOSE(" dpos changed ====> " << Amg::error(newloce, Trk::loc1));
236
237 MClT = new CscClusterOnTrack(MClus, std::move(locpar), std::move(newloce),
238 positionAlongStrip, MClus->status(), MClus->timeStatus(), MClus->time());
239 ATH_MSG_VERBOSE("global postion of MClT :::: " << MClT->globalPosition());
240 }
241
242 return MClT;
243 }
244
246 MuonClusterOnTrack* CscClusterOnTrackCreator::correct(const Trk::PrepRawData& RIO, const Trk::TrackParameters& TP, const EventContext& /*ctx*/) const {
247 return createRIO_OnTrack(RIO, TP.position(), TP.momentum().unit());
248 }
249
252 return createRIO_OnTrack(RIO, GP, GD);
253 }
254
256 const ToolHandle<ICscStripFitter>& CscClusterOnTrackCreator::GetICscStripFitter() const { return m_stripFitter; }
257 const ToolHandle<ICscClusterFitter>& CscClusterOnTrackCreator::GetICscClusterFitter() const { return m_clusterFitter; }
258 const ToolHandle<ICscClusterUtilTool>& CscClusterOnTrackCreator::GetICscClusterUtilTool() const { return m_clusterUtilTool; }
259
260} // namespace Muon
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
std::pair< std::vector< unsigned int >, bool > res
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
Gaudi::Property< double > m_minimumError
virtual MuonClusterOnTrack * createRIO_OnTrack(const Trk::PrepRawData &RIO, const Amg::Vector3D &GP) const override
Create new Muon::MuonClusterOnTrack from a Trk::PrepRawData and a predicted Trk::TrackParameter.
virtual MuonClusterOnTrack * correct(const Trk::PrepRawData &RIO, const Trk::TrackParameters &TP, const EventContext &) const override
Create new Muon::MuonClusterOnTrack from a Trk::PrepRawData and the predicted Trk::TrackParameter at ...
Gaudi::Property< double > m_errorScalerBeta
SG::ReadCondHandleKey< RIO_OnTrackErrorScaling > m_cscErrorScalingKey
ToolHandle< ICscStripFitter > m_stripFitter
ToolHandle< ICscClusterFitter > m_clusterFitter
virtual const ToolHandle< ICscClusterUtilTool > & GetICscClusterUtilTool() const override
Gaudi::Property< double > m_errorScaler
CscClusterOnTrackCreator(const std::string &, const std::string &, const IInterface *)
virtual StatusCode initialize() override
virtual const ToolHandle< ICscStripFitter > & GetICscStripFitter() const override
These functions are provided from the interface.
virtual const ToolHandle< ICscClusterFitter > & GetICscClusterFitter() const override
ToolHandle< ICscClusterUtilTool > m_clusterUtilTool
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Class to represent the calibrated clusters created from CSC strips.
Class representing clusters from the CSC.
Definition CscPrepData.h:39
CscTimeStatus timeStatus() const
Returns the Csc time status flag.
virtual const MuonGM::CscReadoutElement * detectorElement() const override final
Return the detector element corresponding to this PRD.
double time() const
Returns the time.
CscClusterStatus status() const
Returns the Csc status (position measurement) flag.
Class representing the raw data of one CSC strip (for clusters look at Muon::CscPrepData).
Base class for Muon cluster RIO_OnTracks.
virtual const Amg::Vector3D & globalPosition() const override
Returns global position.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
This is the base class for all tracking detector elements with read-out relevant information.
virtual const Surface & surface() const =0
Return surface associated with this detector element.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
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
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
This module defines the arguments passed from the BATCH driver to the BATCH worker.
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
MuonPrepDataCollection< CscStripPrepData > CscStripPrepDataCollection
MuonPrepDataContainerT< CscStripPrepData > CscStripPrepDataContainer
@ CscStatusUnspoiled
Clean cluster with precision fit.
@ CscStatusSplitUnspoiled
Clean cluster with precision fit after split cluster.
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ distPhi
Definition ParamDefs.h:50
@ loc1
Definition ParamDefs.h:34
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
ParametersBase< TrackParametersDim, Charged > TrackParameters
const T_res * ErrorScalingCast(const T_src *src)