7#include <GeoModelHelpers/TransformToStringConverter.h>
10#include <GaudiKernel/SystemOfUnits.h>
17# include "Acts/Surfaces/TrapezoidBounds.hpp"
18# include "Acts/Surfaces/LineBounds.hpp"
19# include "Acts/Surfaces/Surface.hpp"
27 ostr <<
" // Chamber half- length (min/max): "<<pars.shortHalfX<<
"/"<<pars.longHalfX
28 <<
", half-width "<<pars.halfY<<
", height: "<<pars.halfHeight;
29 ostr <<
" // Number of tube layers " << pars.tubeLayers.size()<< std::endl;
30 ostr <<
" // Tube pitch: " << pars.tubePitch
31 <<
" wall thickness: " << pars.tubeWall
32 <<
" inner radius: " << pars.tubeInnerRad
33 <<
" endplug: "<<pars.endPlugLength
34 <<
" deadlength: "<<pars.deadLength<< std::endl;
36 ostr <<
" // **** "<<
Amg::toString(layer->tubeTransform(0).translation(), 2)<<std::endl;
56 return StatusCode::FAILURE;
60 return StatusCode::FAILURE;
71 std::optional<Amg::Vector3D> prevLayPos{std::nullopt};
73 for (
unsigned int lay =1 ; lay <=
numLayers() ; ++lay) {
77#ifdef SIMULATIONBASE_REMOVEPLANESURFACE
83 std::optional<Amg::Vector3D> prevTubePos{std::nullopt};
86 for (
unsigned int tube = 1; tube <=
numTubesInLay(); ++ tube) {
88 if (
m_pars.removedTubes.count(idHash)) {
89 prevTubePos = std::nullopt;
99 GeoTrf::Transform3D tubeFrame = layer.tubeTransform(
tubeNumber(idHash));
101 if (std::abs(tubeRot.determinant()- 1.) > std::numeric_limits<float>::epsilon()){
102 ATH_MSG_FATAL(__FILE__<<
":"<<__LINE__<<
" Transformation matrix is not a pure rotation for "<<
105 return StatusCode::FAILURE;
110 constexpr double pitchTolerance = 20. * Gaudi::Units::micrometer;
112 const double dR = std::abs((tubePos - (*prevTubePos)).
z());
113 if (std::abs(dR -
tubePitch()) > pitchTolerance) {
114 ATH_MSG_FATAL(__FILE__<<
":"<<__LINE__<<
" Detected irregular tube in "<<
116 <<
". Expected tube pitch: "<<
tubePitch()<<
" measured tube pitch: "
119 return StatusCode::FAILURE;
122 if (prevLayPos && tube == 1) {
123 const double dR = (tubePos - (*prevLayPos)).
mag();
124 if (std::abs(dR -
tubePitch()) > pitchTolerance) {
125 ATH_MSG_FATAL(__FILE__<<
":"<<__LINE__<<
" Detected irregular layer pitch in "<<
127 <<
". Expected tube pitch: "<<
tubePitch()<<
" measured tube pitch: "
133 prevLayPos = std::make_optional<Amg::Vector3D>(tubePos);
135 prevTubePos = std::make_optional<Amg::Vector3D>(tubePos);
138#ifndef SIMULATIONBASE
139 m_pars.boundFactory.reset();
141 return StatusCode::SUCCESS;
181 const unsigned int tube =
tubeNumber(tubeHash);
201 const unsigned int tube =
tubeNumber(measHash);
221 getMaterialGeom()->getParent()->getX() *
222 getMaterialGeom()->getX();
241#ifndef SIMULATIONBASE
261 const multilayer_t ml = (
multilayer() == 1) ? multilayer_t::ML1 : multilayer_t::ML2;
267 const double sideSign = 0.5*(1.- 2.*(side ==tubeSide_t::NEG));
279 const int layer_delta = ml == multilayer_t::ML1 ?
numLayers() - tubeLayer : tubeLayer +1;
283 const double zpitch = params.zpitch(ml, side);
284 const double ypitch = params.ypitch(ml, side);
285 const double stagg = params.stagg(ml, side);
286 const double alpha = params.alpha(ml, side);
287 const double y0 = params.y0(ml, side);
288 const double z0 = params.z0(ml, side);
295 const double offset_stagg = 0.5 * zpitch * stagg * ( (layer_delta-1) % 2);
297 tube* zpitch + offset_stagg,
298 (layer_delta-1) * ypitch};
302 ATH_MSG_VERBOSE(
"Off set staggering "<<offset_stagg<<
", layer_delta: "<<layer_delta<<
", zpitch: "<<zpitch<<
", ypitch: "<<ypitch
303 <<
", xshift: "<<xshift);
306 reference_point.y() + z0 + endPlug.y(),
307 reference_point.z() + y0 + endPlug.z());
310 if ((ret - wireEnd).
mag() > 3. * Gaudi::Units::mm) {
312 <<
", side "<< (side == tubeSide_t::POS ?
"positive" :
"negative")
315 ATH_MSG_VERBOSE((side == tubeSide_t::POS ?
"positive" :
"negative")<<
" wire end has moved from "
323 const double chamberThickness)
const {
350 <<
moduleWidthL() <<
", height: "<<chamberHeight<<
", thickness: " <<chamberThickness <<
"." );
353 double s0mdt = localTubeEndPoint.x();
354 if (std::abs(fixedPoint.x()) > 0.01) {
355 s0mdt = localTubeEndPoint.x() - fixedPoint.x();
357 double z0mdt = localTubeEndPoint.y();
361 if (std::abs(fixedPoint.y()) > 0.01) {
362 z0mdt = localTubeEndPoint.y() - fixedPoint.y();
364 double t0mdt = localTubeEndPoint.z();
365 if (std::abs(fixedPoint.z()) > 0.01) {
366 t0mdt = localTubeEndPoint.z() - fixedPoint.z();
368 if (z0mdt < 0 || t0mdt < 0) {
369 ATH_MSG_WARNING(
""<<__func__<<
": correcting the local position of a point outside the mdt station (2 multilayers) volume -- RE "
371 <<
" fixedPoint " <<
Amg::toString(fixedPoint)<<
", z0mdt: "<<z0mdt<<
", t0mdt"<<t0mdt);
373 ATH_MSG_VERBOSE(
"** In "<<__func__<<
" - correct for offset of B-line fixed point " << s0mdt <<
" " << z0mdt <<
" " << t0mdt);
375 constexpr double amdbMargin = 1.*Gaudi::Units::cm;
377 const double s_rel = s0mdt / (width_actual / 2.);
378 const double z_rel = (z0mdt - chamberHeight / 2.) / (chamberHeight / 2.);
379 const double t_rel = (t0mdt - chamberThickness / 2.) / (chamberThickness / 2.);
381 ATH_MSG_VERBOSE(
"** In "<<__func__<<
" - width_actual: "<<width_actual<<
", s_rel: "<<s_rel<<
", z_rel: "<<z_rel
382 <<
", t_rel:" << t_rel );
383 double ds{0.},dz{0.},dt{0.};
387 double ztmp = z_rel * z_rel - 1;
394 dt -= bline.
getParameter(Parameter::tw) * s_rel * z_rel;
395 dz += bline.
getParameter(Parameter::tw) * s_rel * t_rel * chamberThickness / chamberHeight;
402 double egppm = bline.
getParameter(Parameter::eg) * expansionScale;
415 const double ep = bline.
getParameter(Parameter::ep) * expansionScale;
416 const double en = bline.
getParameter(Parameter::en) * expansionScale;
417 const double phi = 0.5 * (ep + en) * s_rel * s_rel + 0.5 * (ep - en) * s_rel;
418 const double localDt =
phi * (t0mdt - chamberThickness / 2.);
419 const double localDz =
phi * (z0mdt - chamberHeight / 2.);
424 ATH_MSG_VERBOSE(
"posOnDefChamStraighWire: ds="<<ds<<
",z="<<dz<<
",t="<<dt);
425 deformedPos[0] = localTubeEndPoint[0] + ds;
426 deformedPos[1] = localTubeEndPoint[1] + dz;
427 deformedPos[2] = localTubeEndPoint[2] + dt;
444 <<
"store address to make the compiler happy: "<<store);
445 return Amg::Transform3D::Identity();
448 if (!store || !store->internalAlignment) {
450 return Amg::Transform3D::Identity();
455 const ChamberDistortions distortPars =
static_cast<const MdtAlignmentStore&
>(*store->internalAlignment).getDistortion(
identify());
458 return Amg::Transform3D::Identity();
470 const double relSign = (
multilayer() == 1 ? -1. : 1.);
473 modHalTHickO{-0.5*relSign*
m_reOtherMl->moduleThickness()};
475 const double thickness = relSign*( (toAMDB* (modHalfThick*Amg::Vector3D::UnitX())) -
476 (
m_reOtherMl->asBuiltRefFrame()*(modHalTHickO* Amg::Vector3D::UnitX()))).z();
486 if (distortPars.asBuilt) {
487 positiveEnd =
wireEndpointAsBuilt(*distortPars.asBuilt, tubeHash, positiveEnd, tubeSide_t::POS);
488 negativeEnd =
wireEndpointAsBuilt(*distortPars.asBuilt, tubeHash, negativeEnd, tubeSide_t::NEG);
492 if (distortPars.bLine) {
501 <<
", thickness: "<<
thickness<<
", height: "<<height);
505 positiveEnd = fromAMDB * positiveEnd;
506 negativeEnd = fromAMDB * negativeEnd;
507 positiveEndBline = fromAMDB * positiveEndBline;
508 negativeEndBline = fromAMDB * negativeEndBline;
518 const Amg::Vector3D new_direction = (positiveEndBline - negativeEndBline).
unit();
519 const Amg::Vector3D rotation_vector = old_direction.cross(new_direction);
522 if (rotation_vector.mag() > 10. * std::numeric_limits<double>::epsilon()) {
523 const Amg::AngleAxis3D wire_rotation(std::asin(rotation_vector.mag()), rotation_vector.unit());
524 deformedTransform = from_center * wire_rotation * to_center;
526 deformedTransform = from_center * to_center;
528 ATH_MSG_VERBOSE(
"To center "<<GeoTrf::toString(to_center)<<
" from: "<<GeoTrf::toString(from_center)<<
529 " -- direction: "<<GeoTrf::toString(old_direction)<<
" vs. "<<GeoTrf::toString(new_direction)
530 <<
" --> rot: "<<GeoTrf::toString(rotation_vector)<<
" ==> "<<GeoTrf::toString(deformedTransform,
true));
531 return deformedTransform;
Scalar phi() const
phi method
Scalar mag() const
mag method
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define AmgSymMatrix(dim)
float getParameter(const Parameter p) const
Returns a given parameter.
static constexpr double expansionScale
This is a "hash" representation of an Identifier.
Helper struct to cache simulatenously the As-built and the BLine corrections of the Mdts for fast acc...
Container classifier the MDT as-built parameters See parameter description in http://atlas-muon-align...
multilayer_t
MDT multi-layer index.
double thickness() const override final
Overload from the Acts::DetectorElement (2 * halfheight)
bool isBarrel() const
States whether the chamber is built into the barrel or not.
double moduleWidthL() const
Returns the length of the top edge of the chamber (top width)
static unsigned tubeNumber(const IdentifierHash &hash)
Transforms the measurement hash into a tube number ranging from [0; numTubeInLay() -1].
Amg::Vector3D highVoltPos(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the endpoint of the tube connected to the high voltage in the ATLAS coordinate frame.
Amg::Vector3D localTubePos(const IdentifierHash &hash) const
Returns the tube position in the chamber coordinate frame (Not applying the B-line corrections)
Amg::Transform3D toTubeFrame(const IdentifierHash &hash) const
Returns the transformation into the rest frame of the tube x-axis: Pointing towards the next layer y-...
double wireLength(const IdentifierHash &hash) const
double activeTubeLength(const IdentifierHash &hash) const
double tubeLength(const IdentifierHash &hash) const
virtual ~MdtReadoutElement()
Destructor.
Amg::Vector3D bLineReferencePoint() const
Returns the fixed point of the B-line & as-bult defromation model expressed in the as-built frame.
unsigned numLayers() const
Returns how many tube layers are inside the multi layer [1;4].
double tubeRadius() const
Adds the thickness of the tube wall onto the radius.
static unsigned layerNumber(const IdentifierHash &hash)
Transforms the measurement hash into a tube-layer number ranging from [0; numLayers() -1].
double distanceToReadout(const ActsTrk::GeometryContext &ctx, const Identifier &measId, const Amg::Vector3D &globPoint) const
Returns the distance to the readout card along the wire.
const MdtReadoutElement * m_reOtherMl
Complementary readout element.
StatusCode initElement() override final
Overload from MuonReadoutElement.
Amg::Vector3D readOutPos(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the endpoint of the tube where the readout card is mounted in the ATLAS coordinate frame.
const MdtIdHelper & m_idHelper
Detector identifier helper to quickly extract the ID fields.
const parameterBook & getParameters() const
Get a const reference to the parameter book.
double moduleHeight() const
Returns the height of the chamber (Distance bottom - topWidth)
Amg::Transform3D asBuiltRefFrame() const
Returns the transformation to go into the reference frame of the as-buit & b-line model starting from...
Amg::Vector3D globalTubePos(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the position of the tube mid point in the ATLAS coordinate frame.
MdtReadoutElement(defineArgs &&args)
Constructor with the define arguments.
void setComplementaryReadoutEle(const MdtReadoutElement *other)
Set the link to the second readout element inside the muon station.
double moduleThickness() const
Returns the thickness of the chamber.
double moduleWidthS() const
Returns the length of the bottom edge of the chamber (short width)
double uncutTubeLength(const IdentifierHash &tubeHash) const
Returns the uncut tube length.
unsigned numTubesInLay() const
Returns the number of tubes in a layer.
Amg::Transform3D fromIdealToDeformed(const IdentifierHash &tubeHash, const ActsTrk::DetectorAlignStore *store) const
Applies the B & as-built parameters.
Amg::Vector3D wireEndpointAsBuilt(const MdtAsBuiltPar &asBuilt, const IdentifierHash &tubeHash, const Amg::Vector3D &nominalEnd, const tubeSide_t side) const
Amg::Vector3D applyBlineCorrections(const BLinePar &bline, const Amg::Vector3D &localTubeEndPoint, const Amg::Vector3D &fixedPoint, const double thickness) const
Apply the B-line model correction to a tube endpoint.
Amg::Transform3D toChamberLayer(const IdentifierHash &hash) const
Returns the transformation into the rest frame of the tube x-axis: Pointing towards the next layer y-...
MdtAsBuiltPar::tubeSide_t tubeSide_t
Moves the wire endpoints according to the as-built model.
static IdentifierHash measurementHash(unsigned layerNumber, unsigned tubeNumber)
Constructs a Measurement hash from layer && tube number.
parameterBook m_pars
defining parameter set
Identifier measurementId(const IdentifierHash &measHash) const override final
Back conversion of the measurement hash towards a full identifier Tube & layer number are extracted f...
double tubePitch() const
Returns the pitch between 2 tubes in a layer.
unsigned multilayer() const
Returns the multi layer of the readout element [1;\2].
Helper struct to retrieve the tube lengths and the tube centers directly from the GeoModel tree.
const Amg::Transform3D & layerTransform() const
: Returns the transformation from the layer to the muon station
const Amg::Transform3D tubeTransform(const unsigned int tube) const
Returns the transformation of the tube to the muon station Index counting [0 - nTubes()-1].
double tubeHalfLength(const unsigned int tube) const
Returns the half-length of the given tube.
double uncutHalfLength(const unsigned int tube) const
Returns the uncut-half length of the given tube.
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the local coordinate system of the readout element into the global AT...
int stationEta() const
Returns the stationEta (positive A site, negative C site)
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the global ATLAS coordinate system into the local coordinate system o...
StatusCode strawSurfaceFactory(const IdentifierHash &hash, std::shared_ptr< const Acts::LineBounds > lBounds)
Invokes the factory to create straw surfaces && to associate them with the particular transform cache...
StatusCode planeSurfaceFactory(const IdentifierHash &hash, std::shared_ptr< const Acts::PlanarBounds > pBounds)
Invokes the factory to create plane surfaces && to associate them with the particular transform cache...
Identifier identify() const override final
Return the ATLAS identifier.
const Muon::IMuonIdHelperSvc * idHelperSvc() const
Returns the pointer to the muonIdHelperSvc.
StatusCode createGeoTransform()
Creates the TransformCacheDetEle corresponding the generic local -> global transformation of the read...
StatusCode insertTransform(const IdentifierHash &hash)
Constructs the TransformDetEleCache associated with the hash of the given Mdt tube or strip layer.
MuonReadoutElement(const defineArgs &args)
Constructor taking the basic define arguments.
static IdentifierHash geoTransformHash()
Returns the hash that is associated with the surface cache holding the transformation that is placing...
const GeoAlignableTransform * alignableTransform() const
Return the alignable transform node of the readout element.
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Amg::Transform3D getRotateX3D(double angle)
get a rotation transformation around X-axis
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
Eigen::AngleAxisd AngleAxis3D
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
std::ostream & operator<<(std::ostream &ostr, const Chamber::defineArgs &args)
GeoModel::TransientConstSharedPtr< MdtTubeLayer > MdtTubeLayerPtr
std::string toString(const MuonGMR4::MuonReadoutElement *re)
Helper struct to store the pointer to the Mdt distrotion parameters, namely the As-built and the BLin...
Declare the define args as concatination of the parameters to describe the chamber and the defineArgs...
Set of parameters to describe a MDT chamber.