ATLAS Offline Software
Loading...
Searching...
No Matches
ObjVisualizationHelpers.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
7
14
17
18#include "Acts/Surfaces/detail/PlanarHelper.hpp"
19#include "Acts/Visualization/GeometryView3D.hpp"
20#include "Acts/Surfaces/StrawSurface.hpp"
21#include "Acts/Surfaces/LineBounds.hpp"
22#include "Acts/Surfaces/RectangleBounds.hpp"
23#include "Acts/Surfaces/TrapezoidBounds.hpp"
24#include "Acts/Surfaces/PlaneSurface.hpp"
25#include "Acts/Definitions/Units.hpp"
26
27
28using namespace Acts::PlanarHelper;
29using namespace MuonR4;
30using namespace Acts::UnitLiterals;
31
32namespace{
33 using CovIdx = MuonR4::SpacePoint::CovIdx;
34}
35
36namespace MuonValR4 {
37 void drawPropagation(const std::vector<Acts::detail::Step>& steps,
38 Acts::ObjVisualization3D& visualHelper,
39 const Acts::ViewConfig& viewConfig){
40
41 if (steps.empty()) {
42 return;
43 }
44 Amg::Vector3D start = steps.front().position;
45 for (std::size_t s = 1; s < steps.size(); ++s) {
46 Amg::Vector3D end = steps[s].position;
47 if ( (end - start).mag() > Acts::s_epsilon){
48 Acts::GeometryView3D::drawSegment(visualHelper, start, end, viewConfig);
49 start = std::move(end);
50 }
51
52 }
53 }
55 const MuonR4::Segment& segment,
56 Acts::ObjVisualization3D& visualHelper,
57 const Acts::ViewConfig& viewConfig) {
59 const Amg::Transform3D& locToGlob = segment.msSector()->localToGlobalTransform(gctx);
60 const Amg::Vector3D firstSurfPos = locToGlob*segment.measurements().front()->localPosition();
61 const Amg::Vector3D lastSurfPos = locToGlob*segment.measurements().back()->localPosition();
62 const Amg::Vector3D planeNorm = locToGlob.linear().col(2);
64 const auto firstPlaneIsect = intersectPlane(segment.position(), segment.direction(),
65 planeNorm, firstSurfPos);
66 const auto lastPlaneIsect = intersectPlane(segment.position(), segment.direction(),
67 planeNorm, lastSurfPos);
68
69 Acts::GeometryView3D::drawSegment(visualHelper,
70 segment.position() + firstPlaneIsect.pathLength() * segment.direction(),
71 segment.position() + lastPlaneIsect.pathLength() * segment.direction(),
72 viewConfig);
73 }
75 const xAOD::MuonSegment& segment,
76 Acts::ObjVisualization3D& visualHelper,
77 const Acts::ViewConfig& viewConfig ,
78 const double standardLength){
79
80 std::vector<const xAOD::UncalibratedMeasurement*> assocMeas = collectMeasurements(segment, false);
81 if (assocMeas.empty()){
82 Acts::GeometryView3D::drawSegment(visualHelper,
83 segment.position() - 0.5 * standardLength * segment.direction(),
84 segment.position() + 0.5 * standardLength * segment.direction(),
85 viewConfig);
86 return;
87 }
88 const xAOD::UncalibratedMeasurement* firstMeas = assocMeas.front()->type() != xAOD::UncalibMeasType::Other ?
89 assocMeas.front() : assocMeas[1];
90 const xAOD::UncalibratedMeasurement* lastMeas = assocMeas.back();
91
92 const Amg::Vector3D firstSurfPos = xAOD::muonSurface(firstMeas).center(gctx.context());
93 const Amg::Vector3D lastSurfPos = xAOD::muonSurface(lastMeas).center(gctx.context());
94
95 const Segment* detSeg = detailedSegment(segment);
97 const Amg::Vector3D planeNorm = detSeg->msSector()->localToGlobalTransform(gctx).linear().col(2);
99 const auto firstPlaneIsect = intersectPlane(segment.position(), segment.direction(),
100 planeNorm, firstSurfPos);
101 const auto lastPlaneIsect = intersectPlane(segment.position(), segment.direction(),
102 planeNorm, lastSurfPos);
103
104 Acts::GeometryView3D::drawSegment(visualHelper,
105 segment.position() + firstPlaneIsect.pathLength() * segment.direction(),
106 segment.position() + lastPlaneIsect.pathLength() * segment.direction(),
107 viewConfig);
108 }
110 const xAOD::MuonSegment& segment,
111 Acts::ObjVisualization3D& visualHelper,
112 const Acts::ViewConfig& viewConfig) {
113 std::vector<const xAOD::UncalibratedMeasurement*> assocMeas = collectMeasurements(segment, false);
114 for (const xAOD::UncalibratedMeasurement* meas : assocMeas){
115 drawMeasurement(gctx, meas, visualHelper, viewConfig);
116 }
117 }
119 const MuonR4::Segment& segment,
120 Acts::ObjVisualization3D& visualHelper,
121 const Acts::ViewConfig& viewConfig) {
122 for (const auto& meas : segment.measurements()) {
123 drawSpacePoint(gctx, *meas, segment.msSector(), visualHelper, viewConfig);
124 }
125 }
128 Acts::ObjVisualization3D& visualHelper,
129 const Acts::ViewConfig& viewConfig) {
130
131 const Acts::Surface& surf = xAOD::muonSurface(meas);
132 const Acts::GeometryContext tgContext = gctx.context();
133 const auto& bounds = surf.bounds();
135 const auto& lBounds = static_cast<const Acts::LineBounds&>(bounds);
136 const auto* driftCirc = static_cast<const xAOD::MdtDriftCircle*>(meas);
137 const double dR = driftCirc->driftRadius();
138 const double hZ = driftCirc->numDimensions() == 1 ?
139 lBounds.get(Acts::LineBounds::eHalfLengthZ) :
140 std::sqrt(meas->localCovariance<2>()(1,1));
141 auto newBounds = std::make_unique<Acts::LineBounds>(dR, hZ);
142 auto dummySurface = Acts::Surface::makeShared<Acts::StrawSurface>(surf.localToGlobalTransform(tgContext)*
143 Amg::getTranslate3D(driftCirc->localMeasurementPos()),
144 std::move(newBounds));
145 Acts::GeometryView3D::drawSurface(visualHelper, *dummySurface, tgContext,
146 Amg::Transform3D::Identity(), viewConfig);
147 return;
148 }
149 double dX{0.}, dY{0.};
150 Amg::Vector3D locPos{Amg::Vector3D::Zero()};
151 switch (meas->numDimensions()) {
153 case 0:{
154 const auto* cmbMeas = static_cast<const xAOD::CombinedMuonStrip*>(meas);
155 if(cmbMeas->primaryStrip()->type() == xAOD::UncalibMeasType::sTgcStripType){
156 // combined stgc space points can be strip/wire, strip/pad or pad/wire combinations.
157 const auto* primMeas = static_cast<const xAOD::sTgcMeasurement*>(cmbMeas->primaryStrip());
158 const auto* secMeas = static_cast<const xAOD::sTgcMeasurement*>(cmbMeas->secondaryStrip());
159 if(primMeas->channelType() == sTgcIdHelper::sTgcChannelTypes::Strip){
160 locPos[Amg::x] = primMeas->localPosition<1>()[0];
161 dX = std::sqrt(primMeas->localCovariance<1>()(0,0));
162 } else if (primMeas->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad) {
163 locPos[Amg::x] = primMeas->localPosition<2>()[0];
164 dX = std::sqrt(primMeas->localCovariance<2>()(0,0));
165 }
166 if(secMeas->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire){
167 locPos[Amg::y] = secMeas->localPosition<1>()[0];
168 dY = std::sqrt(secMeas->localCovariance<1>()(0,0));
169 } else if (secMeas->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad) {
170 locPos[Amg::y] = secMeas->localPosition<2>()[1];
171 dY = std::sqrt(secMeas->localCovariance<2>()(1,1));
172 }
173 break;
174 }
175 locPos[Amg::x] = cmbMeas->primaryStrip()->localPosition<1>()[0];
176 locPos[Amg::y] = cmbMeas->secondaryStrip()->localPosition<1>()[0];
177 dX = std::sqrt(cmbMeas->primaryStrip()->localCovariance<1>()(0,0));
178 dY = std::sqrt(cmbMeas->secondaryStrip()->localCovariance<1>()(0,0));
179 break;
180 } case 1:{
183 const auto* rpcClus = static_cast<const xAOD::RpcMeasurement*>(meas);
184 locPos = rpcClus->localMeasurementPos();
185 dX = rpcClus->measuresPhi() ? 0.5* rpcClus->readoutElement()->stripPhiLength()
186 : std::sqrt(rpcClus->localCovariance<1>()(0,0));
187 dY = rpcClus->measuresPhi() ? std::sqrt(rpcClus->localCovariance<1>()(0,0))
188 : 0.5* rpcClus->readoutElement()->stripEtaLength();
189 } else if (meas->type() == xAOD::UncalibMeasType::TgcStripType) {
190 const auto* tgcClus = static_cast<const xAOD::TgcStrip*>(meas);
191 const MuonGMR4::TgcReadoutElement* re = tgcClus->readoutElement();
192 const auto& stripLay = re->sensorLayout(tgcClus->measurementHash());
193 locPos = tgcClus->localMeasurementPos();
194 dX = tgcClus->measuresPhi() ? 0.5* stripLay->design(true).stripLength(tgcClus->channelNumber())
195 : std::sqrt(tgcClus->localCovariance<1>()(0,0));
196 dY = tgcClus->measuresPhi() ? std::sqrt(tgcClus->localCovariance<1>()(0,0))
197 : 0.5* stripLay->design(false).stripLength(tgcClus->channelNumber());
198 } else if (meas->type() == xAOD::UncalibMeasType::MMClusterType) {
199 const auto* mmClust = static_cast<const xAOD::MMCluster*>(meas);
200 locPos = mmClust->localMeasurementPos();
201 dX = std::sqrt(mmClust->localCovariance<1>()(0,0));
202 dY = 0.5* mmClust->readoutElement()->stripLength(mmClust->measurementHash());
203 } else if(meas->type() == xAOD::UncalibMeasType::sTgcStripType) {
204 const auto* sTgcClus = static_cast<const xAOD::sTgcMeasurement*>(meas);
205 locPos = sTgcClus->localMeasurementPos();
206 if (sTgcClus->channelType() == sTgcIdHelper::sTgcChannelTypes::Strip){
207 dX = std::sqrt(sTgcClus->localCovariance<1>()(0,0));
208 dY = 0.5* sTgcClus->readoutElement()->stripDesign(sTgcClus->measurementHash()).stripLength(sTgcClus->channelNumber());
209 } else if (sTgcClus->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire) {
210 dY = std::sqrt(sTgcClus->localCovariance<1>()(0,0));
211 dX = 0.5*sTgcClus->readoutElement()->wireDesign(sTgcClus->measurementHash()).stripLength(sTgcClus->channelNumber());
212 }
213 }
214 break;
215 }
217 case 2:{
218 locPos.block<2,1>(0, 0) = xAOD::toEigen(meas->localPosition<2>());
219 dX = std::sqrt(meas->localCovariance<2>()(0,0));
220 dY = std::sqrt(meas->localCovariance<2>()(1,1));
221 break;
222 }
223 }
224 auto newBounds = std::make_unique<Acts::RectangleBounds>(dX, dY);
225 auto dummySurf = Acts::Surface::makeShared<Acts::PlaneSurface>(surf.localToGlobalTransform(tgContext)*
226 Amg::getTranslate3D(locPos),
227 std::move(newBounds));
228 Acts::GeometryView3D::drawSurface(visualHelper, *dummySurf, tgContext,
229 Amg::Transform3D::Identity(), viewConfig);
230 }
232 const Acts::BoundTrackParameters& pars,
233 Acts::ObjVisualization3D& visualHelper,
234 const Acts::ViewConfig& viewConfig,
235 const double standardLength){
236 const Amg::Vector3D globPos = pars.position(gctx.context());
237 const Amg::Vector3D start = globPos - 0.5 * standardLength * pars.direction();
238 const Amg::Vector3D end = globPos + 0.5 * standardLength * pars.direction();
239 Acts::GeometryView3D::drawSegment(visualHelper, start, end, viewConfig);
240 }
242 const MuonR4::SpacePoint& spacePoint,
243 Acts::ObjVisualization3D& visualHelper,
244 const Acts::ViewConfig& viewConfig) {
245 if (spacePoint.dimension() == 2 &&
246 spacePoint.primaryMeasurement() != spacePoint.secondaryMeasurement()) {
247 const Amg::Transform3D& locToGlob = spacePoint.msSector()->localToGlobalTransform(gctx);
248 const double dX = std::sqrt(spacePoint.covariance()[Acts::toUnderlying(CovIdx::phiCov)]);
249 const double dY = std::sqrt(spacePoint.covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
250 auto bounds = std::make_unique<Acts::RectangleBounds>(dX, dY);
251 const Acts::Transform3 trf = locToGlob * Amg::getTranslate3D(spacePoint.localPosition());
252 auto surf = Acts::Surface::makeShared<Acts::PlaneSurface>(trf, std::move(bounds));
253 Acts::GeometryView3D::drawSurface(visualHelper, *surf, gctx.context());
254 } else {
255 drawMeasurement(gctx, spacePoint.primaryMeasurement(),
256 visualHelper, viewConfig);
257 }
258 }
260 const MuonR4::CalibratedSpacePoint& spacePoint,
261 const MuonGMR4::SpectrometerSector* msSector,
262 Acts::ObjVisualization3D& visualHelper,
263 const Acts::ViewConfig& viewConfig) {
264 if (spacePoint.type() != xAOD::UncalibMeasType::Other) {
265 drawSpacePoint(gctx, *spacePoint.spacePoint(), visualHelper, viewConfig);
266 return;
267 }
268 const Amg::Transform3D& locToGlob = msSector->localToGlobalTransform(gctx);
269 if (spacePoint.isStraw()) {
270 const double dR = std::sqrt(spacePoint.covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
271 const double hZ = std::sqrt(spacePoint.covariance()[Acts::toUnderlying(CovIdx::phiCov)]);
272 auto bounds = std::make_unique<Acts::LineBounds>(dR, hZ);
273 const Amg::Transform3D trf = locToGlob * Amg::getTranslate3D(spacePoint.localPosition());
274 auto surface = Acts::Surface::makeShared<Acts::StrawSurface>(trf, std::move(bounds));
275 Acts::GeometryView3D::drawSurface(visualHelper, *surface, gctx.context());
276 } else {
277 const double dX = std::sqrt(spacePoint.covariance()[Acts::toUnderlying(CovIdx::phiCov)]);
278 const double dY = std::sqrt(spacePoint.covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
279 auto bounds = std::make_unique<Acts::RectangleBounds>(dX, dY);
280 const Acts::Transform3 trf = locToGlob * Amg::getTranslate3D(spacePoint.localPosition());
281 auto surf = Acts::Surface::makeShared<Acts::PlaneSurface>(trf, std::move(bounds));
282 Acts::GeometryView3D::drawSurface(visualHelper, *surf, gctx.context());
283 }
284 }
285
286
287} // namespace MuonValR4
const boost::regex re(r_e)
Scalar mag() const
mag method
Acts::GeometryContext context() const
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
The calibrated Space point is created during the calibration process.
const Amg::Vector3D & localPosition() const
bool isStraw() const
Returns whether the measurement is a Mdt.
const SpacePoint * spacePoint() const
The pointer to the space point out of which this space point has been built.
xAOD::UncalibMeasType type() const
Returns the space point type.
const Cov_t & covariance() const
Returns the covariance array.
Placeholder for what will later be the muon segment EDM representation.
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated MS sector.
const MeasVec & measurements() const
Returns the associated measurements.
const Amg::Vector3D & position() const
Returns the global segment position.
const Amg::Vector3D & direction() const
Returns the global segment direction.
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
unsigned dimension() const
Is the space point a 1D or combined 2D measurement.
const xAOD::UncalibratedMeasurement * secondaryMeasurement() const
const Cov_t & covariance() const
Returns the covariance array.
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
Amg::Vector3D position() const
Returns the position as Amg::Vector.
ConstMatrixMap< N > localCovariance() const
Returns the local covariance of the measurement.
ConstVectorMap< N > localPosition() const
Returns the local position of the measurement.
virtual unsigned int numDimensions() const =0
Returns the number of dimensions of the measurement.
virtual xAOD::UncalibMeasType type() const =0
Returns the type of the measurement type as a simple enumeration.
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
This header ties the generic definitions in this package.
std::vector< const xAOD::UncalibratedMeasurement * > collectMeasurements(const xAOD::MuonSegment &segment, bool skipOutlier=true)
Helper function to extract the measurements from the segment.
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
void drawBoundParameters(const ActsTrk::GeometryContext &gctx, const Acts::BoundTrackParameters &pars, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine, const double standardLength=3.*Gaudi::Units::cm)
Draw a line representing the bound track parameters.
void drawPropagation(const std::vector< Acts::detail::Step > &steps, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine)
Draws the recorded propagation steps as a polygon line.
void drawMeasurement(const ActsTrk::GeometryContext &gctx, const xAOD::UncalibratedMeasurement *meas, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw an uncalibrated measurement inside the obj file.
void drawSpacePoint(const ActsTrk::GeometryContext &gctx, const MuonR4::SpacePoint &spacePoint, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw an uncalibrated space point inside the obj file.
void drawSegmentMeasurements(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw all uncalibrated measurements associated to the segment.
void drawSegmentLine(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine, const double standardLength=1.*Gaudi::Units::m)
Draw a segment line inside the obj file.
MdtDriftCircle_v1 MdtDriftCircle
TgcStrip_v1 TgcStrip
Definition TgcStripFwd.h:9
const Acts::Surface & muonSurface(const UncalibratedMeasurement *meas)
Returns the associated Acts surface to the measurement.
RpcMeasurement_v1 RpcMeasurement
MMCluster_v1 MMCluster
sTgcMeasurement_v1 sTgcMeasurement
MuonSegment_v1 MuonSegment
Reference the current persistent version:
CombinedMuonStrip_v1 CombinedMuonStrip
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.