7 #include <GeoModelKernel/GeoVPhysVol.h>
11 #include <GeoModelKernel/GeoFullPhysVol.h>
12 #include <GeoModelKernel/GeoShapeShift.h>
13 #include <GeoModelHelpers/printVolume.h>
39 #include <GaudiKernel/SystemOfUnits.h>
41 #include <GeoModelHelpers/defineWorld.h>
42 #include <GeoModelHelpers/cloneVolume.h>
43 #include <GeoModelHelpers/getChildNodesWithTrf.h>
44 #include <GeoModelHelpers/TransformToStringConverter.h>
45 #include <GeoModelHelpers/GeoShapeUtils.h>
46 #include <GeoModelIOHelpers/GMIO.h>
50 #include <GaudiKernel/SystemOfUnits.h>
55 bool hasStationVolume(
const PVConstLink treeTop,
56 const std::set<PVConstLink>& translated) {
57 const unsigned int nCh = treeTop->getNChildVols();
58 for (
unsigned int ch = 0 ;
ch < nCh; ++
ch) {
59 PVConstLink child = treeTop->getChildVol(
ch);
60 if (translated.count(child) ||
61 hasStationVolume(child, translated)){
76 return StatusCode::SUCCESS;
82 if (writeHandle.isValid()) {
83 ATH_MSG_DEBUG(
"The current readout geometry is still valid.");
84 return StatusCode::SUCCESS;
92 if (!readHandle.isValid()) {
94 return StatusCode::FAILURE;
96 writeHandle.addDependency(readHandle);
97 auto alignStore = std::make_unique<ActsTrk::DetectorAlignStore>(**readHandle);
99 if (alignStore->geoModelAlignment) {
100 alignStore->geoModelAlignment->clearPosCache();
102 alignStore->trackingAlignment = std::make_unique<TrackingAlignment>(alignStore->detType);
103 geoContext.setStore(std::move(alignStore));
109 if (geoContext.getStore(detType)) {
113 geoContext.setStore(std::make_unique<ActsTrk::DetectorAlignStore>(detType));
117 cacheObj.
detMgr = std::make_unique<MuonGM::MuonDetectorManager>();
118 cacheObj.
world = createGeoWorld();
127 std::vector<GeoChildNodeWithTrf> treeTops = getChildrenWithRef(
m_detMgr->
getTreeTop(0),
false);
130 for (
const GeoChildNodeWithTrf& treeTop : treeTops) {
134 cacheObj.
world->add(const_pointer_cast(treeTop.volume));
150 return StatusCode::SUCCESS;
160 ATH_MSG_DEBUG(
"Station "<<
stName<<
", stEta: "<<stEta<<
", stPhi: "<<stPhi<<
" already exists.");
161 return StatusCode::SUCCESS;
167 const GeoVFullPhysVol* readOutVol = copyMe->getMaterialGeom();
169 PVConstLink parentVolume = readOutVol->getParent();
174 GeoIntrusivePtr<const GeoGraphNode> alignNode{*(parentVolume->getParent()->findChildNode(alignTrf) + 1)};
176 GeoIntrusivePtr<const GeoTransform> stationShiftNode{alignNode != parentVolume ?
177 dynamic_pointer_cast<const GeoTransform>(alignNode) :
nullptr};
181 PVLink copiedStationVol{};
182 if (!stationShiftNode) {
183 copiedStationVol = make_intrusive<GeoFullPhysVol>(parentVolume->getLogVol());
185 auto volToCopy = parentVolume->getLogVol();
186 auto newShape = cacheObj.cacheShape(make_intrusive<GeoShapeShift>(volToCopy->getShape(),
187 stationShiftNode->getDefTransform()));
188 auto newLogVol = make_intrusive<GeoLogVol>(volToCopy->getName(), newShape, volToCopy->getMaterial());
189 copiedStationVol = make_intrusive<GeoFullPhysVol>(cacheObj.cacheVolume(newLogVol));
194 const std::vector<GeoChildNodeWithTrf>
children = getChildrenWithRef(parentVolume,
false);
195 double minX{1.e9}, maxX{-1.e9}, minY1{1.e9}, maxY1{-1.e9}, minY2{1.e9}, maxY2{-1.e9}, minZ{1.e9}, maxZ{-1.e9};
196 for (
const GeoChildNodeWithTrf& child :
children) {
197 std::vector<Amg::Vector3D> edges = getPolyShapeEdges(child.volume->getLogVol()->getShape(),
198 readOutVol->getX().inverse() * child.transform);
213 const GeoVPhysVol &childVolRef = *child.volume;
214 if (
typeid(childVolRef) ==
typeid(GeoFullPhysVol)) {
218 PVLink childVol = const_pointer_cast<GeoVPhysVol>(child.volume);
219 copiedStationVol->add(cacheObj.
newIdTag());
220 if (stationShiftNode) {
221 copiedStationVol->add(const_pointer_cast(stationShiftNode));
223 copiedStationVol->add(cacheObj.makeTransform(child.transform));
224 copiedStationVol->add(cloneVolume(childVol));
229 const double shortS = (maxY1 - minY1);
230 const double longS = (maxY2 - minY2);
231 const double lengthR = (maxX - minX);
232 const double lengthZ = (maxZ - minZ);
236 ( ( stationShiftNode ? stationShiftNode->getDefTransform() : Amg::Transform3D::Identity())
237 * readOutVol->getDefX()).inverse();
240 auto newStation = std::make_unique<MuonGM::MuonStation>(
stName,
241 shortS, lengthR, lengthZ,
242 longS, lengthR, lengthZ,
243 stEta, stPhi,
false);
244 newStation->setPhysVol(copiedStationVol);
247 auto copyAlignNode = make_intrusive<GeoAlignableTransform>(alignedTransform);
248 newStation->setTransform(copyAlignNode);
249 newStation->setNominalAmdbLRSToGlobal(copyAlignNode->getTransform());
252 <<
" -- shortS: "<<shortS<<
", longS: "<<longS
253 <<
", lengthR: "<<lengthR<<
", lengthZ: "<<lengthZ
255 <<std::endl<<
"Station shift: "<<
GeoTrf::toString(stationShiftNode ? stationShiftNode->getDefTransform()
256 : Amg::Transform3D::Identity(),
true)
257 <<std::endl<<
"AmdLRSToGlobal: "<<
GeoTrf::toString(newStation->getNominalAmdbLRSToGlobal(),
true)
258 <<std::endl<<
"Readout transform: "<<
GeoTrf::toString(readOutVol->getX(),
true));
259 cacheObj.
detMgr->addMuonStation(std::move(newStation));
260 cacheObj.
world->add(copyAlignNode);
261 cacheObj.
world->add(copiedStationVol);
262 return StatusCode::SUCCESS;
269 GeoIntrusivePtr<GeoVFullPhysVol>& physVol,
278 PVLink copiedStationVol{station->
getPhysVol()};
280 GeoIntrusivePtr<const GeoVFullPhysVol> readOutVol{copyMe->getMaterialGeom()};
281 copiedStationVol->add(cacheObj.
newIdTag());
293 readOutVol->getParent()->getX() * readOutVol->getX()};
296 const Amg::Transform3D stationTrf{copiedStationVol->getX().inverse() * alignedNode};
298 copiedStationVol->add(cacheObj.makeTransform(stationTrf*alignNodeToRE));
300 PVLink clonedVol{cloneVolume(const_pointer_cast<GeoVFullPhysVol>(readOutVol))};
301 physVol = dynamic_pointer_cast<GeoVFullPhysVol>(clonedVol);
302 copiedStationVol->add(physVol);
303 return StatusCode::SUCCESS;
308 const std::vector<const MuonGMR4::RpcReadoutElement*> readoutEles =
m_detMgr->getAllRpcReadoutElements();
309 ATH_MSG_INFO(
"Copy "<<readoutEles.size()<<
" Rpc readout elements to the legacy system");
314 GeoIntrusivePtr<GeoVFullPhysVol> physVol{};
317 auto newElement = std::make_unique<MuonGM::RpcReadoutElement>(physVol,
319 1, 1,
false, cacheObj.
detMgr.get());
320 const bool aSide{copyMe->stationEta() > 0};
321 newElement->setDoubletPhi(copyMe->doubletPhi());
322 newElement->setDoubletR(copyMe->doubletR());
323 newElement->setDoubletZ(copyMe->doubletZ());
324 newElement->setIdentifier(reId);
325 newElement->setParentMuonStation(station);
326 station->addMuonReadoutElementWithAlTransf(newElement.get(),
nullptr, station->nMuonReadoutElements());
329 newElement->setLongZsize(2.*
pars.halfLength);
330 newElement->setLongSsize(2.*
pars.halfWidth);
331 newElement->setLongRsize(2.*
pars.halfThickness);
332 newElement->setZsize(2.*
pars.halfLength);
333 newElement->setSsize(2.*
pars.halfWidth);
334 newElement->setRsize(2.*
pars.halfThickness);
336 newElement->m_nlayers = copyMe->nGasGaps();
337 newElement->m_phistripwidth = copyMe->stripPhiWidth();
338 newElement->m_etastripwidth = copyMe->stripEtaWidth();
339 newElement->m_phistrippitch = copyMe->stripPhiPitch();
340 newElement->m_etastrippitch = (aSide > 0 ? 1. : -1.) *copyMe->stripEtaPitch();
341 newElement->m_phistriplength = copyMe->stripPhiLength();
342 newElement->m_etastriplength = copyMe->stripEtaLength();
344 newElement->m_nphistripsperpanel = copyMe->nPhiStrips();
345 newElement->m_netastripsperpanel = copyMe->nEtaStrips();
346 newElement->m_nphistrippanels = copyMe->nPhiPanels();
347 newElement->m_hasDEDontop =
true;
348 newElement->m_descratzneg =
false;
350 std::vector<Identifier> gapIds{};
352 for (
int doubPhi = copyMe->doubletPhiMax(); doubPhi >= copyMe->doubletPhi(); --doubPhi) {
353 for (
bool measPhi : {
false,
true}) {
354 if (measPhi && copyMe->nPhiStrips()==0)
continue;
356 const Identifier gapId = idHelper.channelID(copyMe->identify(),
361 gapIds.push_back(gapId);
362 const Amg::Vector3D locStripPos = copyMe->globalToLocalTrans(gctx) * copyMe->stripPosition(gctx, gapId);
364 newElement->m_gasGap_xPos[
gasGap -1] = locStripPos.x();
367 const int dbPIdx = copyMe->doubletPhi() == 2 ? 1 : doubPhi;
369 newElement->m_first_phistrip_s[dbPIdx -1] = locStripPos.y();
370 newElement->m_phistrip_z = locStripPos.z();
372 newElement->m_first_etastrip_z = locStripPos.z();
373 newElement->m_etastrip_s[dbPIdx-1] = locStripPos.y();
378 newElement->fillCache();
381 const int surfaceHash = newElement->surfaceHash(gapId);
382 const int layerHash = newElement->layerHash(gapId);
386 Amg::Transform3D::Identity())};
388 newElement->m_surfaceData->m_layerTransforms[surfaceHash] = refTrf;
389 newElement->m_surfaceData->m_layerCenters[
layerHash] = refTrf.translation();
390 newElement->m_surfaceData->m_layerNormals[
layerHash] = refTrf.linear() * Amg::Vector3D::UnitZ();
393 cacheObj.
detMgr->addRpcReadoutElement(std::move(newElement));
395 return StatusCode::SUCCESS;
401 std::vector<const MuonGMR4::TgcReadoutElement*> tgcReadouts{
m_detMgr->getAllTgcReadoutElements()};
403 return a->stationEta() >
b->stationEta();
405 ATH_MSG_INFO(
"Copy "<<tgcReadouts.size()<<
" Tgc readout elements to the legacy system");
409 std::map<std::string, std::shared_ptr<TgcReadoutParams>> readoutParMap{};
413 GeoIntrusivePtr<GeoVFullPhysVol> physVol{};
417 auto newRE = std::make_unique<MuonGM::TgcReadoutElement>(physVol,
m_idHelperSvc->stationNameString(reId),
419 newRE->setIdentifier(reId);
420 newRE->setParentMuonStation(station);
422 std::shared_ptr<TgcReadoutParams>& readOutPars = readoutParMap[
std::format(
"{:}_{:}", copyMe->chamberDesign(),
423 copyMe->stationEta()> 0?
'A' :
'C')];
429 std::array<WiregangArray, 3> wires{};
431 std::vector<StripArray> botMountings(copyMe->nGasGaps()),
432 topMountings(copyMe->nGasGaps());
434 double wirePitch{0.};
438 nWireGangs[
gasGap -1] = copyMe->numWireGangs(gangHash);
441 <<
" for gas gap "<<
gasGap);
443 if (nWireGangs[
gasGap -1]) {
447 for (
int gang = 1; gang <= design.numStrips(); ++gang) {
448 fillMe[gang -1] = design.numWiresInGroup(gang);
455 for (
int strip = 1; strip <= nCh; ++strip) {
456 botMountings[
gasGap-1][strip-1] = - design.stripLeftBottom(strip).x();
457 topMountings[
gasGap-1][strip-1] = - design.stripLeftTop(strip).x();
459 botMountings[
gasGap-1][nCh] = - design.stripRightBottom(nCh).x();
460 topMountings[
gasGap-1][nCh] = - design.stripRightTop(nCh).x();
461 ATH_MSG_VERBOSE(
"Strip layout\n bottom: "<<botMountings<<
"\n top: "<<topMountings);
464 readOutPars = std::make_unique<TgcReadoutParams>(copyMe->chamberDesign(),
466 idHelper.stationPhiMax(reId),
467 std::move(nWireGangs),
472 std::move(botMountings),
473 std::move(topMountings),
481 const Amg::Vector3D translation{copyMe->globalToLocalTrans(gctx) * copyMe->center(gctx, layHash)};
482 newRE->setPlaneZ(translation.x(),
gasGap);
484 newRE->setRsize(copyMe->moduleHeight());
485 newRE->setSsize(copyMe->moduleWidthS());
486 newRE->setZsize(copyMe->moduleThickness());
488 newRE->setLongRsize(copyMe->moduleHeight());
489 newRE->setLongSsize(copyMe->moduleWidthL());
490 newRE->setLongZsize(copyMe->moduleThickness());
492 newRE->setReadOutParams(readOutPars);
495 cacheObj.
detMgr->addTgcReadoutElement(std::move(newRE));
498 return StatusCode::SUCCESS;
501 GeoIntrusivePtr<GeoVFullPhysVol>
505 GeoIntrusivePtr<const GeoVFullPhysVol> readOutVol{copyMe->getMaterialGeom()};
508 PVLink clonedVol{cloneVolume(const_pointer_cast<GeoVFullPhysVol>(readOutVol))};
509 GeoIntrusivePtr<GeoFullPhysVol> physVol{dynamic_pointer_cast<GeoFullPhysVol>(clonedVol)};
512 cacheObj.
world->add(physVol);
518 const auto alignStore = alignItr ?
519 static_cast<const MmAlignmentStore*
>(alignItr->internalAlignment.get()) :
nullptr;
522 cacheObj.
detMgr->setMMPassivation(alignStore->passivation);
524 const std::vector<const MuonGMR4::MmReadoutElement*> mmReadouts{
m_detMgr->getAllMmReadoutElements()};
525 ATH_MSG_INFO(
"Copy "<<mmReadouts.size()<<
" Mm readout elements to the legacy system");
529 GeoIntrusivePtr<GeoVFullPhysVol> physVol{
cloneNswWedge(gctx, copyMe, cacheObj)};
530 auto newRE = std::make_unique<MuonGM::MMReadoutElement>(physVol,
532 copyMe->stationEta(),
533 copyMe->stationPhi(),
534 copyMe->multilayer(), cacheObj.
detMgr.get());
540 newRE->m_Xlg[
gasGap] = stripLayer.toOrigin() *
547 designFrom.longHalfHeight(),
548 designFrom.halfWidth(),
549 designFrom.stereoAngle());
552 designTo.inputPitch = designFrom.stripPitch();
553 designTo.inputWidth = designTo.inputPitch *
std::cos(designTo.stereoAngle());
554 designTo.nMissedBottomEta = designTo.nMissedBottomStereo = designFrom.firstStripNumber() - 1;
555 designTo.totalStrips = designFrom.numStrips();
556 designTo.nch = designFrom.numStrips();
558 designTo.setFirstPos(designFrom.firstStripPos().x() + 0.5*designTo.inputPitch);
562 if (alignStore && alignStore->getBLine(reId)) {
563 newRE->setBLinePar(*alignStore->getBLine(reId));
566 cacheObj.
detMgr->addMMReadoutElement(std::move(newRE));
568 return StatusCode::SUCCESS;
573 auto alignStore = alignItr ?
static_cast<const sTgcAlignmentStore*
>(alignItr->internalAlignment.get()) :
nullptr;
575 const std::vector<const MuonGMR4::sTgcReadoutElement*> sTgcReadOuts{
m_detMgr->getAllsTgcReadoutElements()};
576 ATH_MSG_INFO(
"Copy "<<sTgcReadOuts.size()<<
" sTgc readout elements to the legacy system");
581 GeoIntrusivePtr<GeoVFullPhysVol> physVol{
cloneNswWedge(gctx, copyMe, cacheObj)};
583 auto newRE = std::make_unique<MuonGM::sTgcReadoutElement>(physVol,
585 copyMe->stationEta(),
586 copyMe->stationPhi(),
587 copyMe->multilayer(),
590 if (alignStore && alignStore->getBLine(reId)) {
591 newRE->setBLinePar(*alignStore->getBLine(reId));
604 ChannelDesign& etaDesign{newRE->m_etaDesign[
layer-1]};
605 etaDesign.type = ChannelDesign::ChannelType::etaStrip;
607 if (copyEtaDesign.yCutout()) {
608 etaDesign.defineDiamond(copyEtaDesign.shortHalfHeight(),
609 copyEtaDesign.longHalfHeight(),
610 copyEtaDesign.halfWidth(),
611 copyEtaDesign.yCutout());
613 etaDesign.defineTrapezoid(copyEtaDesign.shortHalfHeight(),
614 copyEtaDesign.longHalfHeight(),
615 copyEtaDesign.halfWidth());
618 etaDesign.firstPitch = copyEtaDesign.firstStripPos().x() + 0.5*copyEtaDesign.stripPitch() + copyEtaDesign.halfWidth();
619 etaDesign.inputPitch = copyEtaDesign.stripPitch();
620 etaDesign.inputWidth = copyEtaDesign.stripWidth();
621 etaDesign.nch = copyEtaDesign.numStrips();
623 etaDesign.setFirstPos(copyEtaDesign.firstStripPos().x() + 0.5*copyEtaDesign.stripPitch());
628 ChannelDesign& phiDesign{newRE->m_phiDesign[
layer-1]};
629 phiDesign.type = ChannelDesign::ChannelType::phiStrip;
631 if (copyPhiDesign.yCutout() == 0.) {
632 phiDesign.defineTrapezoid(copyPhiDesign.shortHalfHeight(),
633 copyPhiDesign.longHalfHeight(),
634 copyPhiDesign.halfWidth());
636 phiDesign.defineDiamond(copyPhiDesign.shortHalfHeight(),
637 copyPhiDesign.longHalfHeight(),
638 copyPhiDesign.halfWidth(),
639 copyPhiDesign.yCutout());
641 phiDesign.inputPitch = copyPhiDesign.stripPitch();
642 phiDesign.inputWidth = copyPhiDesign.stripWidth();
644 phiDesign.setFirstPos(copyPhiDesign.firstStripPos().x());
645 phiDesign.firstPitch = copyPhiDesign.numWiresInGroup(1);
646 phiDesign.groupWidth = copyPhiDesign.numWiresInGroup(2);
647 phiDesign.nGroups = copyPhiDesign.numStrips();
648 phiDesign.wireCutout = copyPhiDesign.wireCutout();
649 phiDesign.nch = copyPhiDesign.nAllWires();
650 phiDesign.isConvertedFromPhaseII =
true;
654 padDesign.
Length = copyMe->chamberHeight();
655 padDesign.sWidth = copyMe->sChamberLength();
656 padDesign.lWidth = copyMe->lChamberLength();
657 padDesign.Size = 2.*copyPadDesign.halfWidth();
658 padDesign.ysFrame = copyMe->sFrameWidth();
659 padDesign.ylFrame = copyMe->lFrameWidth();
660 padDesign.thickness = copyMe->thickness();
662 if (copyPadDesign.yCutout()) {
663 padDesign.yCutout = copyPadDesign.halfWidth();
665 padDesign.setR(copyPadDesign.beamlineRadius());
666 padDesign.sPadWidth = 2.*copyPadDesign.shortHalfHeight();
667 padDesign.lPadWidth = 2.*copyPadDesign.longHalfHeight();
668 padDesign.nPadColumns = copyPadDesign.numPadPhi();
669 padDesign.firstPhiPos = copyPadDesign.firstPadPhiDiv();
670 padDesign.inputPhiPitch = copyPadDesign.anglePadPhi();
671 padDesign.PadPhiShift = copyPadDesign.padPhiShift();
672 padDesign.nPadH = copyPadDesign.numPadEta();
673 padDesign.padEtaMax = copyPadDesign.maxPadEta();
674 padDesign.firstRowPos = copyPadDesign.firstPadHeight();
675 padDesign.inputRowPitch = copyPadDesign.padHeight();
676 padDesign.sectorOpeningAngle = copyPadDesign.sectorAngle();
677 padDesign.isConvertedFromPhaseII =
true;
681 cacheObj.
detMgr->addsTgcReadoutElement(std::move(newRE));
684 return StatusCode::SUCCESS;
690 static_cast<const MdtAlignmentStore*
>(alignItr->internalAlignment.get()) :
nullptr;
692 const std::vector<const MuonGMR4::MdtReadoutElement*> mdtReadOuts{
m_detMgr->getAllMdtReadoutElements()};
693 ATH_MSG_INFO(
"Copy "<<mdtReadOuts.size()<<
" Mdt readout elements to the legacy system");
698 GeoIntrusivePtr<GeoVFullPhysVol> physVol{};
701 if (copyMe->multilayer() == 1) {
704 (copyMe->tubePitch() - 2. * copyMe->tubeRadius());
707 modHalfThick{-0.5*copyMe->moduleThickness()};
709 const double thickness = ( (otherRE->
asBuiltRefFrame()*(modHalTHickO* Amg::Vector3D::UnitX())) -
710 (copyMe->asBuiltRefFrame()*(modHalfThick* Amg::Vector3D::UnitX()))).
z();
711 if (copyMe->isBarrel()) {
712 station->setMdtZsize(height);
713 station->setMdtRsize(thickness);
715 station->setMdtRsize(height);
716 station->setMdtZsize(thickness);
720 auto newElement = std::make_unique<MuonGM::MdtReadoutElement>(physVol,
723 newElement->setIdentifier(reId);
724 newElement->setMultilayer(copyMe->multilayer());
725 newElement->setNMdtInStation(
m_idHelperSvc->mdtIdHelper().multilayerMax(reId));
727 newElement->setParentMuonStation(station);
732 newElement->setLongRsize(2*
pars.halfY);
733 newElement->setRsize(2*
pars.halfY);
734 newElement->setZsize(2*
pars.halfHeight);
735 newElement->setLongZsize(2*
pars.halfHeight);
737 newElement->m_nlayers = copyMe->numLayers();
738 newElement->m_ntubesperlayer = copyMe->numTubesInLay();
739 newElement->m_deadlength =
pars.deadLength;
740 newElement->m_endpluglength =
pars.endPlugLength;
741 newElement->m_innerRadius =
pars.tubeInnerRad;
742 newElement->m_tubeWallThickness =
pars.tubeWall;
743 newElement->m_tubepitch =
pars.tubePitch;
749 unsigned int step{1};
750 double lastLength{2.*tubeLay.uncutHalfLength(1)};
751 for (
unsigned tube = 0;
tube < copyMe->numTubesInLay(); ++
tube) {
752 const double currLength = 2.*tubeLay.uncutHalfLength(
tube);
755 tube == copyMe->numTubesInLay() -1) {
756 newElement->m_tubelength[
step-1] = lastLength;
757 newElement->m_tubelength[
step] = currLength;
759 newElement->m_ntubesinastep =
tube;
761 lastLength = currLength;
765 newElement->m_nsteps =
step;
768 double xOffSet{
pars.halfY}, yOffSet{
pars.halfHeight};
769 if (newElement->barrel())
std::swap(xOffSet, yOffSet);
770 for (
unsigned lay = 1; lay <= copyMe->numLayers(); ++lay) {
772 const Amg::Vector3D locTube = copyMe->localTubePos(tubeHash);
773 newElement->m_firstwire_x[lay-1] = locTube.z() + xOffSet;
774 newElement->m_firstwire_y[lay-1] = locTube.x() + yOffSet;
779 if (!station->hasMdtAsBuiltParams()){
780 station->setMdtAsBuiltParams(distort.
asBuilt);
782 if (!station->hasBLines()){
783 station->setBline(distort.
bLine);
785 const Amg::Vector3D refPoint = copyMe->bLineReferencePoint();
786 station->setBlineFixedPointInAmdbLRS(refPoint.x(), refPoint.y(), refPoint.z());
788 newElement->geoInitDone();
789 newElement->setBLinePar(distort.
bLine);
790 newElement->fillCache();
793 cacheObj.
detMgr->addMdtReadoutElement(std::move(newElement));
795 return StatusCode::SUCCESS;
805 return StatusCode::FAILURE;
810 return StatusCode::FAILURE;
812 return StatusCode::SUCCESS;
820 return StatusCode::SUCCESS;
836 return StatusCode::FAILURE;
840 for (
int strip = stripDesign.firstStripNumber(); strip <= stripDesign.numStrips(); ++strip) {
848 return StatusCode::FAILURE;
850 const double dist = refStripDir.dot(refStripPos - testStripPos);
855 return StatusCode::FAILURE;
860 return StatusCode::SUCCESS;
868 return StatusCode::SUCCESS;
874 <<std::endl<<
GeoTrf::toString(testEle.getMaterialGeom()->getAbsoluteTransform())
878 for (
unsigned int lay = 1; lay <= refEle.
numLayers(); ++lay){
881 if (!refEle.
isValid(tubeHash)) {
895 <<
GeoTrf::toString(globToLocal*tubePos) <<
" delta: "<<(refPos - tubePos).mag()
896 <<
" Transforms "<<std::endl
899 return StatusCode::FAILURE;
913 return StatusCode::FAILURE;
918 return StatusCode::SUCCESS;
925 return StatusCode::SUCCESS;
936 for (
bool measPhi : {
false,
true}) {
937 if (measPhi && !refEle.
nPhiStrips())
continue;
938 for (
int strip = 1; strip <= testEle.
Nstrips(measPhi); ++strip) {
941 doubPhi,
gasGap, measPhi, strip);
945 Amg::Transform3D::Identity())};
952 return StatusCode::FAILURE;
965 if ((refStripPos - testStripPos).
mag() > 2
e-4){
968 <<
" local coordinates -- ref: "<<
Amg::toString(refTrans.inverse()*refStripPos)
969 <<
" test: "<<
Amg::toString(refTrans.inverse()*testStripPos));
970 return StatusCode::FAILURE;
974 <<
", local: "<<
Amg::toString(refTrans.inverse()*refStripPos));
979 return StatusCode::SUCCESS;
986 return StatusCode::SUCCESS;
994 <<std::endl<<
GeoTrf::toString(testEle.getMaterialGeom()->getAbsoluteTransform(),
true)
1000 for (
bool isStrip : {
false,
true}) {
1007 (!
isStrip ? Amg::Transform3D::Identity()
1014 <<
" are not identical. ");
1015 return StatusCode::FAILURE;
1029 std::stringstream
msg{};
1031 <<
" is not at the same position "<<
Amg::toString(refChannel)
1033 <<(refChannel - testChannel).
mag();
1035 msg<<std::endl<<
"*** Test *** - wirePitch: "<<testEle.
wirePitch()
1040 msg<<std::endl<<
"*** Ref *** - wirePitch: "<<design.stripPitch()
1042 <<
", wires to reach "<<design.numPitchesToGroup(
ch)
1043 <<
", wires in gang "<<design.numWiresInGroup(
ch);
1045 const Amg::Vector3D locRefPos{refLayerTrf.inverse() * refChannel};
1046 const Amg::Vector3D locTestPos{refLayerTrf.inverse()* testChannel};
1051 return StatusCode::FAILURE;
1056 return StatusCode::SUCCESS;
1062 return StatusCode::SUCCESS;
1071 for (
int chType : {sTgcIdHelper::sTgcChannelTypes::Pad , sTgcIdHelper::sTgcChannelTypes::Strip, sTgcIdHelper::sTgcChannelTypes::Wire}) {
1075 const unsigned int numChannel = refEle.
numChannels(layID);
1076 constexpr
unsigned firstCh = 1;
1080 if(
chType == sTgcIdHelper::sTgcChannelTypes::Pad) {
1083 chID = idHelper.padID(refEle.
identify(),
1087 chID = idHelper.channelID(refEle.
identify(),
1103 return StatusCode::FAILURE;
1105 if (
chType == sTgcIdHelper::sTgcChannelTypes::Pad) {
1111 const std::array<Amg::Vector3D,4> refPadCorners = refEle.
globalPadCorners(gctx, chID);
1112 std::array<Amg::Vector3D,4> testPadCorners{make_array<Amg::Vector3D, 4>(
Amg::Vector3D::Zero())};
1114 for (
unsigned int cornerIdx = 0; cornerIdx < refPadCorners.size(); ++cornerIdx) {
1115 const double padCornerDiff = (refPadCorners[cornerIdx] - testPadCorners[cornerIdx]).
mag();
1119 <<
" difference: " << padCornerDiff
1120 <<
" local coordinates -- ref: "<<
Amg::toString(refTrans.inverse()*refPadCorners[cornerIdx])
1121 <<
" test: "<<
Amg::toString(testPadTrans.inverse()*testPadCorners[cornerIdx]));
1122 return StatusCode::FAILURE;
1125 const double padChannelDiff = (refChannelPos - testChannelPos).
mag();
1129 <<
" difference: " << padChannelDiff
1130 <<
" local coordinates -- ref: "<<
Amg::toString(refTrans.inverse()*refChannelPos)
1131 <<
" test: "<<
Amg::toString(testPadTrans.inverse()*testChannelPos));
1132 return StatusCode::FAILURE;
1137 else if (
chType == sTgcIdHelper::sTgcChannelTypes::Strip){
1144 <<
" local coordinates -- ref: "<<
Amg::toString(testTrans.inverse()*refChannelPos)
1145 <<
" test: "<<
Amg::toString(testTrans.inverse()*testChannelPos));
1146 return StatusCode::FAILURE;
1154 Amg::Vector3D localRefPos {testTrans.inverse()*refChannelPos};
1155 Amg::Vector3D localTestPos{testTrans.inverse()*testChannelPos};
1161 <<
" local coordinates -- ref: "<<
Amg::toString(testTrans.inverse()*refChannelPos)
1162 <<
" test: "<<
Amg::toString(testTrans.inverse()*testChannelPos)
1163 <<
"delta X: "<<std::abs(localRefPos.x() -localTestPos.x())
1164 <<
", delta Z: "<<std::abs(localRefPos.z() -localTestPos.z()));
1165 return StatusCode::FAILURE;
1171 return StatusCode::SUCCESS;