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;
83 ATH_MSG_DEBUG(
"The current readout geometry is still valid.");
84 return StatusCode::SUCCESS;
93 ATH_MSG_FATAL(
"Failed to retrieve alignment store "<<key.fullKey());
94 return StatusCode::FAILURE;
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));
107 std::vector<ActsTrk::DetectorType> presentTechs =
m_detMgr->getDetectorTypes();
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));
139 const std::vector<const MuonGMR4::MuonReadoutElement*> refEles{
m_detMgr->getAllReadoutElements()};
150 return StatusCode::SUCCESS;
155 const std::string stName{
m_idHelperSvc->stationNameString(stationId)};
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);
200 minX = std::min(minX, edge.x());
201 maxX = std::max(maxX, edge.x());
202 minZ = std::min(minZ, edge.z());
203 maxZ = std::max(maxZ, edge.z());
205 minY1 = std::min(minY1, edge.y());
206 maxY1 = std::max(maxY1, edge.y());
208 minY2 = std::min(minY2, edge.y());
209 maxY2 = std::max(maxY2, edge.y());
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());
251 ATH_MSG_VERBOSE(
"stName: "<<stName<<
", stEta: "<<stEta<<
", stPhi: "<<stPhi
252 <<
" -- shortS: "<<shortS<<
", longS: "<<longS
253 <<
", lengthR: "<<lengthR<<
", lengthZ: "<<lengthZ
254 <<std::endl<<
"AlignableNode: "<<GeoTrf::toString(alignedTransform,
true)
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));
260 cacheObj.
world->add(copyAlignNode);
261 cacheObj.
world->add(copiedStationVol);
262 return StatusCode::SUCCESS;
269 GeoIntrusivePtr<GeoVFullPhysVol>& physVol,
273 const std::string stName{
m_idHelperSvc->stationNameString(reId)};
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 newElement->setDoubletPhi(copyMe->doubletPhi());
321 newElement->setDoubletR(copyMe->doubletR());
322 newElement->setDoubletZ(copyMe->doubletZ());
323 newElement->setIdentifier(reId);
324 newElement->setParentMuonStation(station);
328 newElement->setLongZsize(2.*pars.halfLength);
329 newElement->setLongSsize(2.*pars.halfWidth);
330 newElement->setLongRsize(2.*pars.halfThickness);
331 newElement->setZsize(2.*pars.halfLength);
332 newElement->setSsize(2.*pars.halfWidth);
333 newElement->setRsize(2.*pars.halfThickness);
335 newElement->m_nlayers = copyMe->nGasGaps();
336 newElement->m_phistripwidth = copyMe->stripPhiWidth();
337 newElement->m_etastripwidth = copyMe->stripEtaWidth();
338 newElement->m_phistrippitch = copyMe->stripPhiPitch();
339 newElement->m_etastrippitch = Acts::copySign(1., copyMe->stationEta() -
340 (copyMe->stationEta()==0))*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{};
351 for (
unsigned int gasGap = 1; gasGap <= copyMe->nGasGaps(); ++gasGap) {
352 for (
int doubPhi = copyMe->doubletPhiMax(); doubPhi >= copyMe->doubletPhi(); --doubPhi) {
353 for (
bool measPhi : {
false,
true}) {
354 if (measPhi && copyMe->nPhiStrips()==0)
continue;
355 const int channel = 1;
358 doubPhi, gasGap, measPhi,
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();
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')];
425 using WiregangArray = TgcReadoutParams::WiregangArray;
426 using StripArray = TgcReadoutParams::StripArray;
427 using GasGapIntArray = TgcReadoutParams::GasGapIntArray;
429 std::array<WiregangArray, 3> wires{};
430 GasGapIntArray nWireGangs{}, nStrips{};
431 std::vector<StripArray> botMountings(copyMe->nGasGaps()),
432 topMountings(copyMe->nGasGaps());
434 double wirePitch{0.};
435 for (
unsigned int gasGap =1; gasGap <= copyMe->nGasGaps(); ++gasGap) {
436 const IdentifierHash gangHash = copyMe->constructHash(0, gasGap,
false);
437 const IdentifierHash stripHash = copyMe->constructHash(0, gasGap,
true);
438 nWireGangs[gasGap -1] = copyMe->numWireGangs(gangHash);
439 nStrips[gasGap -1] = copyMe->numStrips(stripHash);
440 ATH_MSG_VERBOSE(
"Assigned wire gangs: "<<nWireGangs[gasGap-1]<<
", strips: "<<nStrips[gasGap -1]
441 <<
" for gas gap "<<gasGap);
443 if (nWireGangs[gasGap -1]) {
446 WiregangArray& fillMe{wires[gasGap-1]};
447 for (
int gang = 1; gang <= design.
numStrips(); ++gang) {
452 if (nStrips[gasGap -1]) {
454 const int nCh = nStrips[gasGap -1];
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(),
467 std::move(nWireGangs),
472 std::move(botMountings),
473 std::move(topMountings),
478 for (
unsigned int gasGap = 1; gasGap <= copyMe->nGasGaps(); ++gasGap) {
479 const IdentifierHash layHash{copyMe->constructHash(0, gasGap,
false)};
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);
498 return StatusCode::SUCCESS;
501GeoIntrusivePtr<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;
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());
536 for (
unsigned int gasGap = 0; gasGap < copyMe->nGasGaps(); ++gasGap) {
540 newRE->m_Xlg[gasGap] = stripLayer.
toOrigin() *
543 ATH_MSG_VERBOSE(
"Layer transform "<<gasGap<<
" "<<GeoTrf::toString(newRE->m_Xlg[gasGap],
true));
562 if (alignStore && alignStore->getBLine(reId)) {
563 newRE->setBLinePar(*alignStore->getBLine(reId));
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));
593 for (
unsigned int layer = 1; layer <= copyMe->numLayers(); ++layer) {
604 ChannelDesign& etaDesign{newRE->m_etaDesign[layer-1]};
605 etaDesign.type = ChannelDesign::ChannelType::etaStrip;
606 etaDesign.detType = ChannelDesign::DetType::STGC;
619 etaDesign.inputPitch = copyEtaDesign.
stripPitch();
620 etaDesign.inputWidth = copyEtaDesign.
stripWidth();
621 etaDesign.nch = copyEtaDesign.
numStrips();
628 ChannelDesign& phiDesign{newRE->m_phiDesign[layer-1]};
629 phiDesign.type = ChannelDesign::ChannelType::phiStrip;
630 phiDesign.detType = ChannelDesign::DetType::STGC;
631 if (copyPhiDesign.
yCutout() == 0.) {
641 phiDesign.inputPitch = copyPhiDesign.
stripPitch();
642 phiDesign.inputWidth = copyPhiDesign.
stripWidth();
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();
658 padDesign.
ysFrame = copyMe->sFrameWidth();
659 padDesign.
ylFrame = copyMe->lFrameWidth();
660 padDesign.
thickness = copyMe->thickness();
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) {
703 const double height = std::max(copyMe->moduleHeight(), otherRE->
moduleHeight()) -
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()) {
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);
730 newElement->setLongSsize(2*pars.longHalfX - 1.*Gaudi::Units::cm);
731 newElement->setSsize(2*pars.shortHalfX - 1.*Gaudi::Units::cm);
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};
751 for (
unsigned tube = 0; tube < copyMe->numTubesInLay(); ++tube) {
754 if (std::abs(lastLength - currLength) > std::numeric_limits<float>::epsilon() ||
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;
785 const Amg::Vector3D refPoint = copyMe->bLineReferencePoint();
788 newElement->geoInitDone();
789 newElement->setBLinePar(distort.
bLine);
790 newElement->fillCache();
795 return StatusCode::SUCCESS;
805 return StatusCode::FAILURE;
810 return StatusCode::FAILURE;
812 return StatusCode::SUCCESS;
820 return StatusCode::SUCCESS;
825 <<GeoTrf::toString(testEle.
absTransform(),
true)<<std::endl
828 for (
unsigned int gasGap = 1; gasGap <= refEle.
nGasGaps(); ++ gasGap) {
835 <<GeoTrf::toString(refTrf,
true) <<
" vs. "<<GeoTrf::toString(testTrf,
true));
836 return StatusCode::FAILURE;
848 return StatusCode::FAILURE;
850 const double dist = refStripDir.dot(refStripPos - testStripPos);
851 if (std::abs(dist) > 10. * Gaudi::Units::micrometer) {
854 <<
" distance: "<<dist<<
" "<<(dist / testEle.
m_etaDesign[gasGap -1].inputWidth));
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){
879 for (
unsigned int tube = 1; tube <= refEle.
numTubesInLay(); ++tube) {
881 if (!refEle.
isValid(tubeHash)) {
891 if ( (refPos - tubePos).
mag() > Gaudi::Units::micrometer &&
892 (globToLocal*refPos - globToLocal * tubePos).
perp() > Gaudi::Units::micrometer) {
894 <<
" reference: "<<GeoTrf::toString(globToLocal*refPos)<<
" vs. test: "
895 <<GeoTrf::toString(globToLocal*tubePos) <<
" delta: "<<(refPos - tubePos).mag()
896 <<
" Transforms "<<std::endl
897 <<
" **** "<< GeoTrf::toString(globToLocal.inverse())<<std::endl
898 <<
" **** "<< GeoTrf::toString(testEle.
transform(lay, tube)));
899 return StatusCode::FAILURE;
902 <<std::endl<<
"reference: "<<GeoTrf::toString(refPos)
903 <<std::endl<<
"test: "<<GeoTrf::toString(tubePos)
909 std::numeric_limits<float>::epsilon() ) {
913 return StatusCode::FAILURE;
918 return StatusCode::SUCCESS;
925 return StatusCode::SUCCESS;
931 <<
" test: "<<GeoTrf::toString(testEle.
absTransform(),
true)<<std::endl
934 for (
unsigned int gasGap = 1; gasGap <= refEle.
nGasGaps(); ++gasGap) {
936 for (
bool measPhi : {
false,
true}) {
937 if (measPhi && !refEle.
nPhiStrips())
continue;
941 doubPhi, gasGap, measPhi,
strip);
945 Amg::Transform3D::Identity())};
949 <<
" *** ref: "<<GeoTrf::toString(refTrans)<<std::endl
950 <<
" *** test: "<<GeoTrf::toString(testTrans)<<std::endl
951 <<
" -> delta: "<<GeoTrf::toString(refTrans.inverse()*testTrans));
952 return StatusCode::FAILURE;
965 if ((refStripPos - testStripPos).
mag() > 2e-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)
999 for (
unsigned int gasGap = 1; gasGap <= refEle.
nGasGaps(); ++gasGap) {
1000 for (
bool isStrip : {
false,
true}) {
1007 (!isStrip ? Amg::Transform3D::Identity()
1012 <<std::endl<<
"ref : "<<GeoTrf::toString(refLayerTrf,
true)
1013 <<std::endl<<
"test: "<<GeoTrf::toString(testLayerTrf,
true)
1014 <<
" are not identical. ");
1015 return StatusCode::FAILURE;
1018 <<std::endl<<
"ref : "<<GeoTrf::toString(refLayerTrf,
true)
1019 <<std::endl<<
"test: "<<GeoTrf::toString(testLayerTrf,
true));
1021 for (
unsigned int ch = 1; ch <= refEle.
numChannels(layHash); ++ch) {
1026 if ((refChannel - testChannel).
mag() < std::numeric_limits<float>::epsilon()){
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()
1036 <<
", tot wires "<<testEle.
nWires(gasGap)
1038 <<
", wires in gang "<<testEle.
nWires(gasGap, ch);
1040 msg<<std::endl<<
"*** Ref *** - wirePitch: "<<design.
stripPitch()
1041 <<
", tot wires "<<testEle.
nWires(gasGap)
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;
1067 <<GeoTrf::toString(testEle.
absTransform(),
true)<<std::endl
1070 for (
unsigned int gasGap = 1; gasGap <= refEle.
numLayers(); ++gasGap) {
1075 const unsigned int numChannel = refEle.
numChannels(layID);
1076 constexpr unsigned firstCh = 1;
1077 for (
unsigned int channel = firstCh; channel < numChannel ; ++channel) {
1099 || (testTrans.inverse()*refTrans).translation().perp() > std::numeric_limits<float>::epsilon() ) ) {
1101 <<
" *** ref: "<<GeoTrf::toString(refTrans,
true)<<std::endl
1102 <<
" *** test: "<<GeoTrf::toString(testTrans,
true));
1103 return StatusCode::FAILURE;
1111 const std::array<Amg::Vector3D,4> refPadCorners = refEle.
globalPadCorners(gctx, chID);
1114 for (
unsigned int cornerIdx = 0; cornerIdx < refPadCorners.size(); ++cornerIdx) {
1115 const double padCornerDiff = (refPadCorners[cornerIdx] - testPadCorners[cornerIdx]).
mag();
1116 if (padCornerDiff - 25. > 1. * Gaudi::Units::micrometer){
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();
1126 if (padChannelDiff - 25. > 1. * Gaudi::Units::micrometer){
1129 <<
" difference: " << padChannelDiff
1130 <<
" local coordinates -- ref: "<<
Amg::toString(refTrans.inverse()*refChannelPos)
1131 <<
" test: "<<
Amg::toString(testPadTrans.inverse()*testChannelPos));
1132 return StatusCode::FAILURE;
1141 if ((refChannelPos - testChannelPos).
mag() > 1. * Gaudi::Units::micrometer){
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};
1157 if((std::abs(localRefPos.x() -localTestPos.x()) > 1.* Gaudi::Units::micrometer)
1158 || (std::abs(refChannelPos.z() -testChannelPos.z()) > 15.* Gaudi::Units::micrometer)){
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;
Scalar perp() const
perp method - perpendicular length
Scalar mag() const
mag method
constexpr std::array< T, N > make_array(const T &def_val)
Helper function to initialize in-place arrays with non-zero values.
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
sTgcIdHelper::sTgcChannelTypes chType
Store holding the transfomations used by the Acts algorithms.
GeoModel::TransientConstSharedPtr< AlignmentStore > AlignmentStorePtr
AlignmentStorePtr & getStore(const DetectorType type)
Returns the mutable alignable store for the ATLAS detector type (Pixel, Mdt, etc.)
void setStore(AlignmentStorePtr store)
Adds the store to the Geometry context.
const ServiceHandle< StoreGateSvc > & detStore() const
static EventIDRange infiniteRunLB()
Produces an EventIDRange that is infinite in RunLumi and invalid in Time.
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...
chamberDistortions getDistortion(const Identifier &detElId) const
Returns a chamber distortion that's cached for the corresponding Mdt chamber element.
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channel) const
double wireLength(const IdentifierHash &hash) const
static IdentifierHash measurementHash(unsigned int layerNumber, unsigned int tubeNumber)
Transform the layer and tube number to the measurementHash.
double activeTubeLength(const IdentifierHash &hash) const
double tubeLength(const IdentifierHash &hash) const
bool isValid(const IdentifierHash &measHash) const
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 global position of the tube center.
unsigned int numTubesInLay() const
Returns the number of tubes per layer.
double moduleThickness() const
Returns the thickness of the chamber.
double uncutTubeLength(const IdentifierHash &tubeHash) const
Returns the uncut tube length.
const MdtReadoutElement * complementaryRE() const
Returns the pointer to the other readout element inside the muon station.
Identifier measurementId(const IdentifierHash &measHash) const override final
Converts the measurement hash back to the full Identifier.
unsigned int numLayers() const
Returns the number of tube layer.
Helper struct to retrieve the tube lengths and the tube centers directly from the GeoModel tree.
double uncutHalfLength(const unsigned int tube) const
Returns the uncut-half length of the given tube.
const StripLayer & stripLayer(const Identifier &measId) const
unsigned int nGasGaps() const
Returns the number of gas gaps.
int multilayer() const
Returns the multi layer of the element [1-2].
IdentifierHash layerHash(const Identifier &measId) const override final
Amg::Vector3D stripPosition(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the position of the strip center.
static IdentifierHash createHash(const int gasGap, const int strip)
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
IdentifierHash identHash() const
Returns the Identifier has of the Element that is Identical to the detElHash from the id_helper class...
Identifier identify() const override final
Return the athena identifier.
const GeoAlignableTransform * alignableTransform() const
Returnsthe alignable transform of the readout element.
Amg::Transform3D globalToLocalTrans(const ActsTrk::GeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
double beamlineRadius() const
Returns the distance between the gasGap center and the beamline.
int numPadPhi() const
Returns the number of pads in the Phi direction in the given gasGap layer.
std::pair< int, int > padNumber(const int SeqChannel) const
Returns the pad (eta,phi) for a given pad number in sequence (1,2,3,...18,19,20......
int numPadEta() const
Returns the number of pads in the eta direction in the given layer.
double sectorAngle() const
Function gives the angular width of the sector.
double padPhiShift() const
Returns the staggering shift of inner pad edges in the phi direction.
int maxPadEta() const
Returns the maximum number of pads that can be contained in a column of a pad. Used to match the pad ...
double firstPadHeight() const
Returns the height of the pads that are adjacent to the bottom edge of the trapezoid active area.
double anglePadPhi() const
Returns the angular pitch of the pads in the phi direction.
double padHeight() const
Returns the height of all the pads that are not adjacent to the bottom edge of the trapezoid active a...
double firstPadPhiDiv() const
Returns the angle of the first pad outer edge w.r.t. the gasGap center from the beamline.
Amg::Vector2D stripLeftTop(int stripNumber) const
: Returns the intersection of the left strip edge at the top panel's edge
Amg::Vector2D stripRightTop(int stripNumber) const
: Returns the intersecetion fo the right strip edge at the top panel's edge
Amg::Vector2D stripRightBottom(int stripNumber) const
: Returns the intersecton of the strip right edge at the bottom panel's edge
Amg::Vector2D stripLeftBottom(int stripNumber) const
: Returns the intersection of the left strip edge at the bottom panel's edge
StatusCode buildStation(const ActsTrk::GeometryContext &gctx, const Identifier &stationId, ConstructionCache &cacheObj) const
builds a station object from readout element.
Gaudi::Property< std::string > m_geoDumpName
StatusCode buildMdt(const ActsTrk::GeometryContext &gctx, ConstructionCache &cacheObj) const
StatusCode initialize() override
StatusCode cloneReadoutVolume(const ActsTrk::GeometryContext &gctx, const Identifier &stationId, ConstructionCache &cacheObj, GeoIntrusivePtr< GeoVFullPhysVol > &clonedPhysVol, MuonGM::MuonStation *&station) const
Clones the fullPhysical volume of the readoutElement and embeds it into the associated station.
StatusCode execute(const EventContext &ctx) const override
SG::WriteCondHandleKey< MuonGM::MuonDetectorManager > m_writeKey
StatusCode buildRpc(const ActsTrk::GeometryContext &gctx, ConstructionCache &cacheObj) const
GeoIntrusivePtr< GeoVFullPhysVol > cloneNswWedge(const ActsTrk::GeometryContext &gctx, const MuonGMR4::MuonReadoutElement *nswRE, ConstructionCache &cacheObj) const
Clones the fullPhysicalVolume of the.
StatusCode buildTgc(const ActsTrk::GeometryContext &gctx, ConstructionCache &cacheObj) const
Gaudi::Property< bool > m_dumpGeo
StatusCode buildSTGC(const ActsTrk::GeometryContext &gctx, ConstructionCache &cacheObj) const
StatusCode dumpAndCompare(const ActsTrk::GeometryContext &gctx, const MuonGMR4::RpcReadoutElement &refEle, const MuonGM::RpcReadoutElement &testEle) const
StatusCode checkIdCompability(const MuonGMR4::MuonReadoutElement &refEle, const MuonGM::MuonReadoutElement &testEle) const
StatusCode buildMM(const ActsTrk::GeometryContext &gctx, ConstructionCache &cacheObj) const
SG::ReadCondHandleKeyArray< ActsTrk::DetectorAlignStore > m_alignStoreKeys
const MuonGMR4::MuonDetectorManager * m_detMgr
Gaudi::Property< bool > m_checkGeo
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
unsigned nPhiStrips() const
Number of strips measuring the phi coordinate.
int doubletZ() const
Returns the doublet Z field of the MuonReadoutElement identifier.
int doubletPhi() const
Returns the doublet Phi field of the MuonReadoutElement identifier.
int doubletPhiMax() const
Returns the maximum phi panel.
Amg::Vector3D stripPosition(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the position of the strip center.
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3)
double halfWidth() const
Returns the half height of the strip panel.
double stereoAngle() const
Returns the value of the stereo angle.
int firstStripNumber() const
Returns the number of the first strip.
const Amg::Vector2D & firstStripPos() const
Vector indicating the first strip position.
double yCutout() const
Returns the cutout of the diamond.
double stripPitch() const
Distance between two adjacent strips.
double stripWidth() const
Width of a strip.
double shortHalfHeight() const
Returns the shorter half height of the panel.
double longHalfHeight() const
Returns the longer half height of the panel.
virtual int numStrips() const
Number of strips on the panel.
The StripLayer interfaces the 2D description of the strip plane layout with the 3D description of the...
const StripDesign & design(bool phiView=false) const
Returns the underlying strip design.
const Amg::Transform3D & toOrigin() const
Returns the transformation to go from the strip layer center to the origin of the Strip chamber.
Amg::Vector3D channelPosition(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the center of the measurement channel eta measurement: wire gang center phi measurement: stri...
Identifier measurementId(const IdentifierHash &measHash) const override final
Converts the measurement hash back to the full Identifier.
static IdentifierHash constructHash(unsigned measCh, unsigned gasGap, const bool isStrip)
Constructs the Hash out of the Identifier fields (channel, gasGap, isStrip)
const WireGroupDesign & wireGangLayout(const IdentifierHash &layHash) const
Returns access to the wire group design of the given gasGap [1-3] If the gap does not have a wires an...
unsigned numChannels(const IdentifierHash &measHash) const
Returns the number of readout channels.
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3)
unsigned int numWiresInGroup(unsigned int groupNum) const
Returns the number of wires in a given group.
unsigned int numPitchesToGroup(unsigned int groupNum) const
Returns the number of wire pitches to reach the given group.
double wireCutout() const
Extract the wireCutout for a wireGroup layer.
unsigned int nAllWires() const
Returns the number of all wires.
Amg::Vector3D globalChannelPosition(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the global pad/strip/wireGroup position.
static IdentifierHash createHash(const unsigned int gasGap, const unsigned int channelType, const unsigned int channel, const unsigned int wireInGrp=0)
Create a measurement hash from the Identifier fields.
const PadDesign & padDesign(const Identifier &measId) const
Retrieves the readoutElement Layer given the Identifier/Hash.
globalCornerArray globalPadCorners(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
int multilayer() const
Returns the multilayer of the sTgcReadoutElement.
unsigned int numLayers() const
Returns the number of gas gap layers.
ReadoutChannelType
ReadoutChannelType to distinguish the available readout channels Pad - pad readout channel Strip - et...
unsigned int numChannels(const Identifier &measId) const
Returns the number of strips / wires / pads in a given gasGap.
An MMReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station con...
bool stripGlobalPosition(const Identifier &id, Amg::Vector3D &gpos) const
std::array< MuonChannelDesign, 4 > m_etaDesign
double getTubeLengthForCaching(const int tubeLayer, const int tube) const
double getActiveTubeLength(const int tubeLayer, const int tube) const
Amg::Vector3D tubePos(const Identifier &id) const
Returns the global position of the given tube.
virtual const Amg::Transform3D & transform(const Identifier &id) const override final
Return local to global transform associated with this identifier.
double tubeLength(const int tubeLayer, const int tube) const
double getWireLength(const int tubeLayer, const int tube) const
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
const MuonReadoutElement * getReadoutElement(const Identifier &id) const
Get any read out element.
void addsTgcReadoutElement(std::unique_ptr< sTgcReadoutElement > &&reEle)
store the sTGCReadoutElement using as "key" the identifier
void addRpcReadoutElement(std::unique_ptr< RpcReadoutElement > &&reEle)
store the RpcReadoutElement using as "key" the identifier
void setMMPassivation(const NswPassivationDbData *passiv)
const MuonStation * getMuonStation(const std::string &stName, int eta, int phi) const
void addMdtReadoutElement(std::unique_ptr< MdtReadoutElement > &&reEle)
store the MdtReadoutElement using as "key" the identifier
void addMuonStation(std::unique_ptr< MuonStation > &&mst)
void addTgcReadoutElement(std::unique_ptr< TgcReadoutElement > &&reEle)
store the TgcReadoutElement using as "key" the identifier
void addMMReadoutElement(std::unique_ptr< MMReadoutElement > &&reEle)
store the MMReadoutElement using as "key" the identifier
Base class for the XxxReadoutElement, with Xxx = Mdt, Rpc, Tgc, Csc.
IdentifierHash detectorElementHash() const
Returns the IdentifierHash of the detector element.
double getLongZsize() const
double getLongRsize() const
const Amg::Transform3D & absTransform() const
double getLongSsize() const
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
void setBlineFixedPointInAmdbLRS(double s0, double z0, double t0)
PVConstLink getPhysVol() const
void setMdtAsBuiltParams(const MdtAsBuiltPar *xtomo)
void setMdtRsize(const double rSize)
int nMuonReadoutElements() const
void addMuonReadoutElementWithAlTransf(MuonReadoutElement *a, GeoAlignableTransform *ptrsf, int jobIndex)
void setMdtZsize(const double zSize)
void setBline(const BLinePar *bline)
bool hasMdtAsBuiltParams() const
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
Amg::Vector3D stripPos(const Identifier &id) const
int Nstrips(bool measphi) const
returns the number of strips for the phi or eta plane
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Amg::Vector3D channelPos(const Identifier &id) const
Returns the position of the active channel (wireGang or strip)
double nPitchesToGang(int gasGap, int gang) const
Returns the number of wire pitches that have to be travelled to reach gang i.
int nWires(int gasGap) const
Returns the total number of wires in a given gas gap.
double wirePitch() const
Returns the pitch of the wires.
An sTgcReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station c...
bool stripGlobalPosition(const Identifier &id, Amg::Vector3D &gpos) const
bool padGlobalCorners(const Identifier &id, std::array< Amg::Vector3D, 4 > &gcorners) const
pad global corners
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
void addDependency(const EventIDRange &range)
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
static int stationPhiMax(bool endcap)
Identifier channelID(int stationName, int stationEta, int stationPhi, int gasGap, int isStrip, int channel) const
Identifier padID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int padEta, int padPhi) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int channel) const
std::string to_string(const DetectorType &type)
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
@ Mm
Maybe not needed in the migration.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
bool isIdentity(const Amg::Transform3D &trans)
Checks whether the transformation is the Identity transformation.
bool doesNotDeform(const Amg::Transform3D &trans)
Checks whether the linear part of the transformation rotates or stetches any of the basis vectors.
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Eigen::Affine3d Transform3D
Amg::Transform3D getTranslateX3D(const double X)
: Returns a shift transformation along the x-axis
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
Helper struct to store the pointer to the Mdt distrotion parameters, namely the As-built and the BLin...
const MdtAsBuiltPar * asBuilt
Set of parameters to describe a MDT chamber.
PVLink world
Pointer to the world.
std::unique_ptr< MuonGM::MuonDetectorManager > detMgr
Pointer to the legacy MuonDetectorManager.
GeoIntrusivePtr< GeoIdentifierTag > newIdTag()
Returns an identifier tag.
std::set< PVConstLink > translatedStations
Set of all translated Physical volumes.
Set of parameters to describe a RPC chamber.
double stereoAngle() const
returns the stereo angle
void defineTrapezoid(double HalfShortY, double HalfLongY, double HalfHeight)
set the trapezoid dimensions
void setFirstPos(const double pos)
Set the position of the first strip along the x-axis.
Parameters defining the design of the readout sTGC pads.
double sectorOpeningAngle
bool isConvertedFromPhaseII
void setR(double R)
access to cache