15 #include "GeoModelKernel/GeoDefinitions.h"
16 #include "GeoModelKernel/GeoTube.h"
20 #include "GeoModelHelpers/throwExcept.h"
21 #include "GeoModelHelpers/TransformToStringConverter.h"
38 #define verbose_Bline false
55 constexpr
double linearDensity = 378.954;
71 std::vector<const Trk::Surface*> elementSurfaces;
75 if (
s) elementSurfaces.push_back(
s.get());
77 return elementSurfaces;
82 if (tubeLayer >
getNLayers() || tubeLayer < 1)
return false;
88 if (tubeLayer >
getNLayers() || tubeLayer < 1)
return false;
104 double nominalTubeLength = 0.;
109 if (istep < 0 || istep >=
m_nsteps) {
111 <<
" DEid = " <<
idHelperSvc()->toStringDetEl(
identify()) <<
" called with: tubeL, tube " << tubeLayer <<
" " <<
tube
118 double tlength = nominalTubeLength;
121 if (
manager()->MinimalGeoFlag() == 0) {
123 <<
" has cutouts, check for real tube length for tubeLayer, tube " << tubeLayer <<
" " <<
tube );
124 PVConstLink cv = getMaterialGeom();
125 int nGrandchildren = cv->getNChildVols();
126 if (nGrandchildren <= 0)
return tlength;
135 int packed_id =
tube + maxNTubesPerLayer * tubeLayer;
140 if (!
found &&
id == packed_id) {
147 ATH_MSG_DEBUG(
" MdtReadoutElement tube match found for BMG - input : tube(" <<
tube <<
"), layer("
148 << tubeLayer <<
") - output match : tube(" << ii % maxNTubesPerLayer <<
"), layer(" << ii / maxNTubesPerLayer
152 if (ii >= nGrandchildren) {
154 <<
" --- getTubeLength is looking for child with index ii=" << ii <<
" for tubeL and tube = " << tubeLayer <<
" "
161 <<
" --- getTubeLength is looking for child with index ii=" << ii <<
" for tubeL and tube = " << tubeLayer <<
" "
166 PVConstLink physChild = cv->getChildVol(ii);
167 const GeoShape* shape = physChild->getLogVol()->getShape();
168 if (shape ==
nullptr)
return tlength;
169 const GeoTube* theTube =
dynamic_cast<const GeoTube*
>(shape);
170 if (theTube !=
nullptr)
171 tlength = 2. * theTube->getZHalfLength();
174 <<
" out of (tubeLayer-1)*m_ntubesperlayer+tube with tl=" << tubeLayer <<
" tubes/lay=" <<
m_ntubesperlayer
177 if (std::abs(tlength - nominalTubeLength) > 0.1) {
179 <<
" is affected by a cutout: eff. length = " << tlength <<
" while nominal = " << nominalTubeLength
183 <<
" is NOT affected by the cutout: eff. length = " << tlength <<
" while nominal = " << nominalTubeLength);
196 double scalprod = c_ro.dot(x_ro);
228 int amdb_plus_minus1 = 1;
231 if (std::abs(
ms->xAmdbCRO()) > 10.) {
236 if (ROtubeFrame.z() < 0)
275 if (amdb_plus_minus1 == 0) {
276 ATH_MSG_WARNING(
"Unable to get the sign of RO side; signedRODistancefromTubeCenter returns 0" );
297 <<
"/" << tubeLayer <<
"/" <<
tube );
298 double xtube{0.}, ytube{0.}, ztube{0.};
310 PVConstLink cv = getMaterialGeom();
311 int nGrandchildren = cv->getNChildVols();
321 int packed_id =
tube + maxNTubesPerLayer * tubeLayer;
326 if (!
found &&
id == packed_id) {
334 ATH_MSG_DEBUG(
" MdtReadoutElement tube match found for BMG - input : tube(" <<
tube <<
"), layer("
335 << tubeLayer <<
") - output match : tube(" << ii % maxNTubesPerLayer <<
"), layer(" << ii / maxNTubesPerLayer
340 PVConstLink tv = cv->getChildVol(ii);
341 constexpr
double maxtol = 0.0000001;
343 if (std::abs(xtube - tubeTrans(0, 3)) > maxtol || std::abs(ztube - tubeTrans(2, 3)) > maxtol) {
344 THROW_EXCEPTION(__func__<<
"("<<tubeLayer<<
","<<
tube<<
")"<<
" - mismatch between local from tube-id/pitch/cutout position"<<
346 idHelperSvc()->toStringDetEl(
identify()) <<
"There are "<<nGrandchildren<<
" child volumes and "<<
350 if (tubeTrans(1, 3) > maxtol) {
353 <<
"/" << tubeLayer <<
"/" <<
tube);
356 THROW_EXCEPTION(__func__<<
"("<<tubeLayer<<
","<<
tube<<
")"<<
" - mismatch between local from tube-id/pitch/cutout position"<<
358 idHelperSvc()->toStringDetEl(
identify()) <<
"There are "<<nGrandchildren<<
" child volumes and "<<
412 if (istep < 0 || istep >=
m_nsteps) {
414 <<
" called with: tubeL, tube " << tubeLayer
422 double xtube{0.}, ztube{0.};
436 ATH_MSG_WARNING(__func__<<
"() :"<<__LINE__<<
" called with tubeLayer or tube out of range in chamber "
438 <<
" max " <<
m_ntubesperlayer <<
" will compute deformation for first tube in this chamber" );
446 ptr.
set(std::make_unique<Amg::Transform3D>(std::move(trans)));
464 if ( !
ms->hasBLines() && !
ms->hasMdtAsBuiltParams()) {
465 return Amg::Transform3D::Identity();
468 const Amg::Vector3D fixedPoint =
ms->getUpdatedBlineFixedPointInAmdbLRS();
472 if (itube >= ntot_tubes) {
473 ATH_MSG_WARNING(
"global index for tubeLayer/tube = " << tubeLayer <<
"/" <<
tube <<
" is " << itube
474 <<
" >=ntot_tubes =" << ntot_tubes <<
" RESETTING global index to 0" );
481 double height =
barrel() ?
ms->ZsizeMdtStation() :
ms->RsizeMdtStation();
482 double thickness =
barrel() ?
ms->RsizeMdtStation() :
ms->ZsizeMdtStation();
486 if (std::abs(height - heightML) > 10.) {
488 <<
"Different ML and MDTStation length in the precision coord.direction --- MultiLayerHeight, MDTstationHeigh "
489 << heightML <<
" " << height <<
" MultiLayerThickness, MDTstationThickness " << thicknessML <<
" " << thickness);
505 Amg::Vector3D pt_end1 = toAMDB * pt_center + halftubelen * Amg::Vector3D::UnitX();
506 Amg::Vector3D pt_end2 = toAMDB * pt_center - halftubelen * Amg::Vector3D::UnitX();
512 if (
ms->hasMdtAsBuiltParams()) {
517 if (
ms->hasBLines()) {
521 pt_end1_new =
posOnDefChamWire(pt_end1_new, width_narrow, width_wide, height, thickness, fixedPoint);
524 pt_end2_new =
posOnDefChamWire(pt_end2_new, width_narrow, width_wide, height, thickness, fixedPoint);
528 pt_end1 = fromAMDB * pt_end1;
529 pt_end2 = fromAMDB * pt_end2;
530 pt_end1_new = fromAMDB * pt_end1_new;
531 pt_end2_new = fromAMDB * pt_end2_new;
538 const Amg::Vector3D pt_center_new = 0.5 * (pt_end1_new + pt_end2_new);
543 const Amg::Vector3D rotation_vector = old_direction.cross(new_direction);
544 if (rotation_vector.mag() > 10. * std::numeric_limits<double>::epsilon()) {
545 const Amg::AngleAxis3D wire_rotation(std::asin(rotation_vector.mag()), rotation_vector.unit());
573 const double width_narrow,
574 const double width_wide,
576 const double thickness,
616 double s0 = locAMDBPos.x();
617 double z0 = locAMDBPos.y();
618 double t0 = locAMDBPos.z();
619 ATH_MSG_VERBOSE(
"** In "<<__func__<<
" - width_narrow, width_wide, length, thickness, " << width_narrow <<
" " << width_wide
620 <<
" " << height <<
" " << thickness <<
" " );
621 ATH_MSG_VERBOSE(
"** In "<<__func__<<
" - going to correct for B-line the position of Point at " << s0 <<
" " <<
z0 <<
" "
622 <<
t0 <<
" in the amdb-szt frame" );
625 if (std::abs(fixedPoint.x()) > 0.01) s0mdt = s0 - fixedPoint.x();
628 if (std::abs(fixedPoint.y()) > 0.01) z0mdt =
z0 - fixedPoint.y();
631 if (std::abs(fixedPoint.z()) > 0.01) t0mdt =
t0 - fixedPoint.z();
632 if (z0mdt < 0 || t0mdt < 0) {
633 ATH_MSG_WARNING(
""<<__func__<<
": correcting the local position of a point outside the mdt station (2 multilayers) volume -- RE "
635 <<
" fixedPoint " << fixedPoint );
637 ATH_MSG_VERBOSE(
"** In "<<__func__<<
" - correct for offset of B-line fixed point " << s0mdt <<
" " << z0mdt <<
" " << t0mdt);
639 double ds{0.},dz{0.},
dt{0.};
640 double width_actual = width_narrow + (width_wide - width_narrow) * (z0mdt / height);
641 double s_rel = s0mdt / (width_actual / 2.);
642 double z_rel = (z0mdt - height / 2.) / (height / 2.);
643 double t_rel = (t0mdt - thickness / 2.) / (thickness / 2.);
645 ATH_MSG_VERBOSE(
"** In "<<__func__<<
" - width_actual, s_rel, z_rel, t_rel " << width_actual <<
" " << s_rel <<
" "
646 << z_rel <<
" " << t_rel );
649 if ((sp != 0) || (sn != 0)) {
650 double ztmp = z_rel * z_rel - 1;
651 dt += 0.5 * (sp + sn) * ztmp + 0.5 * (sp - sn) * ztmp * s_rel;
656 dt -= tw * s_rel * z_rel;
657 dz += tw * s_rel * t_rel * thickness / height;
658 ATH_MSG_VERBOSE(
"** In "<<__func__<<
": tw=" << tw <<
" dt, dz " <<
dt <<
" " << dz );
663 double egppm =
eg / 1000.;
675 if ((ep != 0) || (
en != 0)) {
678 double phi = 0.5 * (ep +
en) * s_rel * s_rel + 0.5 * (ep -
en) * s_rel;
679 double localDt =
phi * (t0mdt - thickness / 2.);
680 double localDz =
phi * (z0mdt - height / 2.);
686 deformPos[0] = s0 +
ds;
687 deformPos[1] =
z0 + dz;
688 deformPos[2] =
t0 +
dt;
706 const int tubeLayer,
const int tube)
const {
714 <<
" tubeLayer=" << tubeLayer <<
" tube=" <<
tube);
716 constexpr
int nsid = 2;
719 std::array<MdtAsBuiltPar::tubeSide_t, nsid> tubeSide{tubeSide_t::POS, tubeSide_t::NEG};
720 std::array<Amg::Vector3D, nsid> wireEnd{locAMDBWireEndP, locAMDBWireEndN};
721 multilayer_t ml = (
getMultilayer() == 1) ? multilayer_t::ML1 : multilayer_t::ML2;
723 for (
int isid = 0; isid < nsid; ++isid) {
725 double xref{0.}, yref{0.}, zref{0.};
726 int ref_layer = (ml == multilayer_t::ML1) ?
m_nlayers : 1;
741 reference_point = toAMDB * reference_point;
747 int layer_delta = tubeLayer;
748 if (ml == multilayer_t::ML1) layer_delta =
m_nlayers + 1 - tubeLayer;
751 double zpitch =
params->zpitch(ml, tubeSide[isid]);
752 double ypitch =
params->ypitch(ml, tubeSide[isid]);
753 double stagg = (
double)
params->stagg(ml, tubeSide[isid]);
754 double alpha =
params->alpha(ml, tubeSide[isid]);
755 double y0 =
params->y0(ml, tubeSide[isid]);
756 double z0 =
params->z0(ml, tubeSide[isid]);
759 int do_stagg = (layer_delta - 1) % 2;
760 double offset_stagg = ((
double)do_stagg) * 0.5 * zpitch * stagg;
761 Amg::Vector3D end_plug(0., (
tube - 1.0) * zpitch + offset_stagg, (layer_delta - 1) * ypitch);
764 end_plug = amgTransf * end_plug;
773 Amg::Vector3D ret(reference_point.x() + xshift, reference_point.y() +
z0 + end_plug.y(),
774 reference_point.z() + y0 + end_plug.z());
784 if (tubeSide[isid] == tubeSide_t::POS)
785 locAMDBWireEndP =
ret;
787 locAMDBWireEndN =
ret;
792 return std::make_unique<GeoInfo>(std::move(
transform));
798 ATH_MSG_WARNING(__func__<<
"() :"<<__LINE__<<
" called with tubeLayer or tube out of range in chamber "
800 <<
" max " <<
m_ntubesperlayer <<
" will compute transform for first tube in this chamber" );
822 if (itube >= ntot_tubes) {
823 ATH_MSG_WARNING(
"surface called with tubeLayer or tube out of range in chamber "
825 <<
" max " <<
m_ntubesperlayer <<
" will compute surface for first tube in this chamber" );
832 double wireTension = 350;
835 ptr.
set(std::make_unique<Trk::SaggedLineSurface>(*
this,
id,
getWireLength(tubeLayer,
tube), wireTension, linearDensity));
850 if (istep < 0 || istep >= ntot_steps) {
852 <<
" DEid = " <<
idHelperSvc()->toStringDetEl(
identify()) <<
" called with: tubeL, tube " << tubeLayer <<
" " <<
tube
854 ATH_MSG_WARNING(
"Please run in DEBUG mode to get extra diagnostic; setting istep = 0" );
879 surfaceTRotation.col(0) = muonTRotation.col(1);
880 surfaceTRotation.col(1) = muonTRotation.col(2);
881 surfaceTRotation.col(2) = muonTRotation.col(0);
884 trans3D.pretranslate(
transform().translation());
960 ATH_MSG_VERBOSE(
"global Surface / Bounds pointers " << tmpSurface <<
" " << tmpBounds );
973 PVConstLink cv = getMaterialGeom();
977 int packed_id =
tube + maxNTubesPerLayer *
tl;
981 if (!
found &&
id == packed_id) {
1016 if (layer < 1 || layer >
getNLayers())
return false;