7#include "GaudiKernel/MsgStream.h"
24 declareInterface<IMuonSegmentInOverlapResolvingTool>(
this);
38 return StatusCode::SUCCESS;
50 double road_dz = lphiDir.z();
51 double seg_dy = lsegDir.y();
52 double seg_dz = lsegDir.z();
53 if (road_dz * seg_dz < 0) {
57 if (std::abs(seg_dz) < 1e-6) {
59 ATH_MSG_DEBUG(
" Unexpected local direction of segment " << lsegDir);
61 double scale = road_dz / seg_dz;
70 double&
phi,
double& stereoangle)
const
101 Amg::Vector3D lDiro12 = gToLocal1.linear() * (gToGlobal2.linear() * segLocDiro);
103 Amg::Vector3D lDiro21 = gToLocal2.linear() * (gToGlobal1.linear() * segLocDiro);
105 stereoangle = std::acos(lDiro12.x());
112 double b = lDir1.y() * lDir12.z() - lDir1.z() * lDir12.y();
113 double a = lDir1.y() * lDiro12.z() - lDir1.z() * lDiro12.y();
114 double dxn = lDir12.x();
115 double dyn = lDir12.y();
116 double dzn = lDir12.z();
117 if (std::abs(
a) > 1e-2) {
118 dxn = lDir12.x() - b * lDiro12.x() /
a;
119 dyn = lDir12.y() - b * lDiro12.y() /
a;
120 dzn = lDir12.z() - b * lDiro12.z() /
a;
122 double norm = std::hypot(dxn, dyn, dzn);
127 if (dxn * lDir1.x() + dyn * lDir1.y() + dzn * lDir1.z() < 0) norm = -norm;
141 double theta = gDirn.theta();
151 double res21 = (lPos2.y() - lPos21.y()) * lDirn2.z() - (lPos2.z() - lPos21.z()) * lDirn2.y();
153 double step = (lDiro21.y() * lDirn2.z() - lDiro21.z() * lDirn2.y());
154 if (std::abs(step) > 1e-5) {
155 localx1 = res21 / step;
157 ATH_MSG_DEBUG(
" localx1 " << localx1 <<
" res21 " << res21 <<
" step " << step);
160 Amg::Vector3D lPosn1(lPos1.x() + localx1, lPos1.y(), lPos1.z());
163 double res12 = (lPos1.y() - lPos12.y()) * lDirn1.z() - (lPos1.z() - lPos12.z()) * lDirn1.y();
164 step = (lDiro12.y() * lDirn1.z() - lDiro12.z() * lDirn1.y());
166 if (std::abs(step) > 1e-5) {
167 localx2 = res12 / step;
169 ATH_MSG_DEBUG(
" localx2 " << localx2 <<
" res12 " << res12 <<
" step " << step);
172 Amg::Vector3D lPosn2(lPos2.x() + localx2, lPos2.y(), lPos2.z());
175 << lPos1 <<
" new " << lPosn1 << std::endl
176 <<
" segment 1 global position " << gPos1 <<
" new " << gPosn1 << std::endl
177 <<
" segment 2 local position " << lPos2 <<
" new " << lPosn2 << std::endl
178 <<
" segment 2 global position " << gPos2 <<
" new " << gPosn2);
182 if (gDir1.x() * gDirPos.x() + gDir1.y() * gDirPos.y() + gDir1.z() * gDirPos.z() < 0) {
183 gDirPos = -gPosn2 + gPosn1;
185 double dtheta =
theta - gDirPos.theta();
186 double dphi =
phi - gDirPos.phi();
187 ATH_MSG_DEBUG(
" theta " <<
theta <<
" gDirPos theta " << gDirPos.theta() <<
" dtheta " << dtheta <<
" phi " <<
phi
188 <<
" gDirPos phi " << gDirPos.phi() <<
" dphi " << dphi);
228 Amg::Vector3D lDiro12 = gToLocal1.linear() * (gToGlobal2.linear() * segLocDiro);
239 double b = lDir1.y() * lDir12.z() - lDir1.z() * lDir12.y();
240 double a = lDir1.y() * lDiro12.z() - lDir1.z() * lDiro12.y();
241 double dxn = lDir12.x();
242 double dyn = lDir12.y();
243 double dzn = lDir12.z();
244 if (std::abs(
a) > 1e-2) {
245 dxn = lDir12.x() - b * lDiro12.x() /
a;
246 dyn = lDir12.y() - b * lDiro12.y() /
a;
247 dzn = lDir12.z() - b * lDiro12.z() /
a;
249 double norm = std::hypot(dxn, dyn, dzn);
254 if (dxn * lDir1.x() + dyn * lDir1.y() + dzn * lDir1.z() < 0) norm = -norm;
270 double dyz = std::abs(segLocDir1.
angleYZ() - segLocDir2.
angleYZ());
271 return {segDir1Min, segDir2Min, dyz};
278 unsigned int nbins = 11;
280 double scanRange = 1.;
281 double scanStep = scanRange / (nbins - 1);
284 double dthetaMin = 1e9;
288 for (
unsigned int i = 0; i < nbins; ++i) {
289 double phi = phiStart + scanStep * i;
293 double dyz = std::abs(segLocDir12.
angleYZ() - segLocDir2.
angleYZ());
294 if (dyz < dthetaMin) {
296 segDir1Min = segDir1;
308 bool goodMatch =
true;
317 double posStep = tubeStep / (nbins - 1);
319 double resfirst{1e9}, reslast{1e9}, posfirst{1e9}, poslast{1e9};
322 for (
int j = 0; j < nbins; ++j) {
337 if (!intersect.valid || !segmentSurface.
globalToLocal(intersect.position, segDir1Min, lpos)) {
340 << segDir1Min.phi() <<
" theta "
341 << segDir1Min.theta());
351 if (j == nbins - 1) {
358 double distPosMin2{1e9}, distPosInTube2{1e9}, distPosMin{1e9}, distPosInTube{1e9}, resyMin{1e9};
360 double rangeCut = 1e5;
361 if (resfirst < rangeCut && reslast < rangeCut && posfirst < rangeCut && poslast < rangeCut) {
362 double resDif = reslast - resfirst;
363 double posDif = poslast - posfirst;
364 if (std::abs(resDif) < 1e-6) {
366 resDif = resDif < 0. ? -1e-6 : 1e-6;
368 if (std::abs(posDif) < 1e-6) {
370 posDif = posDif < 0. ? -1e-6 : 1e-6;
372 distPosMin = posfirst - resfirst / (resDif) * (posDif);
374 resyMin = resfirst + (resDif) * (distPosInTube - posfirst) / (posDif);
376 double locx = distPosInTube;
392 if (!intersect.valid) {
394 << segDir1Min.phi() <<
" theta "
395 << segDir1Min.theta());
399 distPosMin2 = locExSeg2.x();
421 double shortestTubeLen = 1e9;
434 if (tubelen < shortestTubeLen) {
435 shortestTubeLen = tubelen;
443 summary.detEl = detEl;
444 summary.hasMdt = hasMdt;
446 summary.globalToSeg = summary.segToGlobal.inverse();
447 summary.roPosInSegFrame = (summary.globalToSeg * roPos).
x();
448 double distTubeCenterFromRO = (summary.globalToSeg * tubeCenter).
x() - summary.roPosInSegFrame;
449 summary.hvPosInSegFrame = summary.roPosInSegFrame + 2 * distTubeCenterFromRO;
450 summary.shortestChannelLength = std::abs(2 * distTubeCenterFromRO);
460 <<
" Second segment " <<
m_printer->print(seg2));
474 if (
result.segmentResult1.goodMatch &&
result.segmentResult2.goodMatch) {
480 if (
result.phiResult.segmentDirection1.y() * difPos.y() < 0.) {
485 result.angularDifferencePhi = difPos.deltaPhi(
result.phiResult.segmentDirection1);
498 unsigned int nphiMeas = 0;
499 double averagePull = 0.;
512 if (!
id.is_valid() || !
m_idHelperSvc->measuresPhi(
id))
continue;
515 const Trk::Surface& measSurf = meas->associatedSurface();
518 std::unique_ptr<const Trk::TrackParameters> exPars {
527 ATH_MSG_WARNING(
" Failed to propagate parameter to segment surface" << std::endl
535 ATH_MSG_DEBUG(
" calculation of residual/pull failed !!!!! ");
540 if (resPull->pull().size() != 1) {
544 const double pull = resPull->pull().front();
549 if (nphiMeas != 0) averagePull /= nphiMeas;
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
double getActiveTubeLength(const int tubeLayer, const int tube) const
Amg::Vector3D ROPos(const int tubelayer, const int tube) const
virtual const Trk::Surface & surface() const override final
Return surface associated with this detector element.
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
virtual const MdtPrepData * prepRawData() const override final
Returns the PrepRawData used to create this corrected measurement.
virtual const MuonGM::MdtReadoutElement * detectorElement() const override
Returns the detector element corresponding to this PRD.
This is the common class for 3D segments used in the muon spectrometer.
const Amg::Vector3D & globalDirection() const
global direction
virtual const Amg::Vector3D & globalPosition() const override final
global position
virtual const Trk::PlaneSurface & associatedSurface() const override final
returns the surface for the local to global transformation
represents the three-dimensional global direction with respect to a planar surface frame.
double angleYZ() const
access method for angle of local YZ projection
bool contains(ParamDefs par) const
The simple check for the clients whether the parameter is contained.
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation.
virtual Intersection straightLineIntersection(const Amg::Vector3D &pos, const Amg::Vector3D &dir, bool forceDir, Trk::BoundaryCheck bchk) const override final
fast straight line intersection schema - standard: provides closest intersection and (signed) path le...
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
Identifier identify() const
return the identifier -extends MeasurementBase
@ Unbiased
RP with track state that has measurement not included.
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
Abstract Base Class for tracking surfaces.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
void setThetaPhi(Amg::Vector3D &v, double theta, double phi)
sets the theta and phi angle of a vector without changing the magnitude
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
Ensure that the ATLAS eigen extensions are properly loaded.
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane